示例#1
0
    def test_reuse_quit(self):
        # if the user replies with QUIT, then we should always return QUIT
        # for future errors
        self.run_choice_dialog.return_value = dialogs.BUTTON_QUIT
        dialog = mock.Mock(title='test 1', description='test 2')
        # handle a backend error
        self.run_backend_dialog(dialog)
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        self.assertEquals(dialog.run_callback.call_args[0][0],
                          dialogs.BUTTON_QUIT)
        # for future errors, we should assume the user still wants to quit

        # try a bunch of frontend errors
        retry_callback = mock.Mock()
        self.run_dialog('test 1', 'test 2', retry_callback)
        self.run_dialog('test 1', 'test 2', retry_callback)
        self.run_dialog('test 1', 'test 2', retry_callback)
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        self.assertEquals(retry_callback.call_count, 0)
        # try a bunch of backend errors
        self.run_backend_dialog(dialog)
        self.run_backend_dialog(dialog)
        self.run_backend_dialog(dialog)
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        self.assertEquals(dialog.run_callback.call_args_list,
                          [((dialogs.BUTTON_QUIT, ), {}),
                           ((dialogs.BUTTON_QUIT, ), {}),
                           ((dialogs.BUTTON_QUIT, ), {}),
                           ((dialogs.BUTTON_QUIT, ), {})])
示例#2
0
 def test_on_item_changes(self):
     # Test that calling on_item_changes on the ItemListPool calls it on
     # all lists inside that pool.
     self.item_list.on_item_changes = mock.Mock()
     self.item_list2.on_item_changes = mock.Mock()
     fake_message = mock.Mock()
     app.item_tracker_updater.on_item_changes(fake_message)
     self.item_list.on_item_changes.assert_called_once_with(fake_message)
     self.item_list2.on_item_changes.assert_called_once_with(fake_message)
示例#3
0
 def setUp(self):
     ExtensionTestBase.setUp(self)
     # Make a Mock object to use as a hook function.  Nest inside another
     # Mock object to test hook parser better
     global hook_holder
     hook_holder = mock.Mock()
     hook_holder.hook_func = mock.Mock()
     self.mock_hook = hook_holder.hook_func
     # make our extension
     self.create_extension()
示例#4
0
 def test_quit(self):
     # Check that we call Frontend.quit()
     self.run_choice_dialog.return_value = dialogs.BUTTON_QUIT
     dialog = mock.Mock(title='test 1', description='test 2')
     self.run_backend_dialog(dialog)
     self.assertEquals(self.frontend.quit.call_count, 1)
     # another error shouldn't result in 2 quit calls
     self.run_choice_dialog.return_value = dialogs.BUTTON_QUIT
     dialog = mock.Mock(title='test 1', description='test 2')
     self.run_backend_dialog(dialog)
     self.assertEquals(self.frontend.quit.call_count, 1)
示例#5
0
 def setUp(self):
     MiroTestCase.setUp(self)
     self.mock_item_list_pool = self.patch_for_test(
         'miro.app.item_list_pool')
     self.items = [
         mock.Mock(id=0, title='one', is_playable=True),
         mock.Mock(id=1, title='two', is_playable=True),
         mock.Mock(id=2, title='three', is_playable=False),
         mock.Mock(id=3, title='four', is_playable=True),
     ]
     self.item_list = MockItemList(self.items)
示例#6
0
 def make_tracker(self):
     query = itemtrack.ItemTrackerQuery()
     query.add_condition('feed_id', '=', self.feed.id)
     query.set_order_by(['release_date'])
     item_tracker = itemtrack.ItemTracker(self.idle_scheduler, query,
                                          item.ItemSource())
     self.list_changed_callback = mock.Mock()
     self.items_changed_callback = mock.Mock()
     item_tracker.connect('list-changed', self.list_changed_callback)
     item_tracker.connect('items-changed', self.items_changed_callback)
     return item_tracker
示例#7
0
 def setUp(self):
     MiroTestCase.setUp(self)
     self.init_data_package()
     self.feed = models.Feed(u'http://example.com/feed.rss')
     self.items = [
         testobjects.make_item(self.feed, u'item-%s' % i)
         for i in xrange(10)
     ]
     app.db.finish_transaction()
     self.item_list = itemlist.ItemList('feed', self.feed.id)
     self.items_changed_handler = mock.Mock()
     self.list_changed_handler = mock.Mock()
     self.item_list.connect("items-changed", self.items_changed_handler)
     self.item_list.connect("list-changed", self.list_changed_handler)
示例#8
0
    def test_path_sql_arguments(self):
        # Check that DeviceItem converts paths to unicode when sending values
        # to sqlite and does case-insensitive comparisons
        path = PlatformFilenameType('Foo.mp3')
        mock_make_view = self.patch_for_test(
            'miro.item.DeviceItem.make_view', autospec=False)

        # test get_by_path
        item.DeviceItem.get_by_path(path, self.device.db_info)
        self.assertEquals(mock_make_view.call_count, 1)
        sql, params = mock_make_view.call_args[0]
        self.assertEquals(type(params[0]), unicode)
        if 'LOWER' not in sql:
            raise AssertionError("this doesn't look like lower case "
                                 "comparison: %s " % sql)
        self.assertEquals(params[0], 'Foo.mp3')
        self.assertEquals(type(mock_make_view.call_args[0][1][0]), unicode)
        mock_make_view.reset_mock() 

        # test_items_for_paths
        mock_make_view.return_value = [mock.Mock(filename='foo.mp3')]
        item.DeviceItem.items_for_paths([path], self.device.db_info)
        sql, params = mock_make_view.call_args[0]
        self.assertEquals(type(params[0]), unicode)
        if 'LOWER' not in sql:
            raise AssertionError("this doesn't look like lower case "
                                 "comparison: %s " % sql)
        self.assertEquals(params[0], 'Foo.mp3')
示例#9
0
 def test_add_image(self):
     layout = cellpack.Layout()
     image = mock.Mock()
     image.get_size.return_value = (20, 50)
     layout.add_image(image, 100, 100)
     layout.draw(self.context)
     image.draw.assert_called_with(self.context, 100, 100, 20, 50)
示例#10
0
    def force_db_error(self):
        def execute_that_fails(*args, **kwargs):
            raise sqlite3.DatabaseError("Test Error")

        mock_execute = mock.Mock(side_effect=execute_that_fails)
        return mock.patch('miro.data.connectionpool.Connection.execute',
                          mock_execute)
示例#11
0
 def test_add_text_line(self):
     layout = cellpack.Layout()
     textbox = mock.Mock()
     textbox.font.line_height.return_value = 30
     layout.add_text_line(textbox, 100, 100, 50)
     layout.draw(self.context)
     textbox.draw.assert_called_with(self.context, 100, 100, 50, 30)
示例#12
0
    def test_error_in_retry_callback(self):
        self.run_choice_dialog.return_value = dialogs.BUTTON_RETRY
        # the frontend calls run_dialog() when it sees an error
        mock_retry_callback = mock.Mock()

        def retry_callback():
            # the first time this one is called, we similate another error
            # happening
            if mock_retry_callback.call_count == 1:
                self.db_error_handler.run_dialog('test 1', 'test 2',
                                                 mock_retry_callback)

        mock_retry_callback.side_effect = retry_callback
        self.run_dialog('test 1', 'test 2', mock_retry_callback)
        # the first run through retry_callback resulted in an error.  We
        # should have a new dialog scheduled to pop up.  We shouldn't call
        # retry_callback() again yet, nor have actually popped up the dialog.
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        args = self.check_run_dialog_scheduled('test 1', 'test 2', 'ui thread')
        self.assertEquals(mock_retry_callback.call_count, 1)
        # Run the dialog again.  The second time through our retry callback
        # won't have an error
        self.db_error_handler._run_dialog(*args)
        self.assertEquals(self.run_choice_dialog.call_count, 2)
        self.assertEquals(mock_retry_callback.call_count, 2)
        self.check_run_dialog_not_scheduled()
示例#13
0
    def setUp(self):
        MiroTestCase.setUp(self)
        self.save_path = os.path.join(self.tempdir, 'test-db')
        # set up an error handler that tells LiveStorage to use temporary
        # storage if it fails to open a new database
        use_temp = storedatabase.LiveStorageErrorHandler.ACTION_USE_TEMPORARY
        self.error_handler = mock.Mock()
        self.error_handler.handle_open_error.return_value = use_temp

        self.row_data = []

        self.mock_add_timeout = mock.Mock()
        self.patch_function('miro.eventloop.add_timeout',
                            self.mock_add_timeout)

        self.real_sqlite3_connect = sqlite3.connect
        self.patch_function('sqlite3.connect', self.mock_sqlite3_connect)
示例#14
0
 def setUp(self):
     ItemTrackTestCase.setUp(self)
     # setup mock objects to track when the items-changed and list-changed
     # signals get emitted
     self.signal_handlers = {}
     for signal in ("items-changed", "list-changed"):
         self.signal_handlers[signal] = mock.Mock()
         self.tracker.connect(signal, self.signal_handlers[signal])
示例#15
0
    def test_backend_then_frontend_errors(self):
        retry_callback = mock.Mock()

        def run_choice_dialog(title, description, buttons):
            # while inside the choice dialog for the backend, we trigger
            # another error from the frontend.
            self.run_dialog('test 1', 'test 2', retry_callback)
            return dialogs.BUTTON_RETRY

        self.run_choice_dialog.side_effect = run_choice_dialog
        dialog = mock.Mock(title='test 1', description='test 2')
        self.run_backend_dialog(dialog)
        # even though we saw 2 errors, only 1 dialog should be shown
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        # since RETRY was chosen for the dialog, both backend and frontend
        # should see that
        self.assertEquals(dialog.run_callback.call_args[0][0],
                          dialogs.BUTTON_RETRY)
        self.assertEquals(retry_callback.call_count, 1)
示例#16
0
    def setup_mock_message_handler(self):
        """Install a mock object to handle frontend messages.

        We use this to intercept the ItemChanges message
        """
        self.mock_message_handler = mock.Mock()
        messages.FrontendMessage.install_handler(self.mock_message_handler)
        # move past the the SharingItemChanges method for our initial items.
        eventloop._eventloop.emit('event-finished', True)
        self.mock_message_handler.reset_mock()
示例#17
0
    def test_client_disconnects_in_get_revision(self):
        # get_revision() blocks waiting for chainges, but it should return if
        # the client disconnects.  Test that this happens
        self.setup_sharing_manager_backend()
        mock_socket = mock.Mock()
        # We use a threading.Condition object to wait for changes.
        self.wait_count = 0

        def mock_wait(timeout=None):
            # we must use a timeout since we want to poll the socket
            self.assertNotEquals(timeout, None)
            if self.wait_count > 2:
                raise AssertionError("wait called too many times")
            self.wait_count += 1

        self.backend.data_set.condition.wait = mock_wait

        # We use select() to check if the socket is closed.
        self.select_count = 0

        def mock_select(rlist, wlist, xlist, timeout=None):
            self.assertEquals(timeout, 0)
            self.assertEquals(rlist, [mock_socket])
            if self.select_count == 0:
                # first time around, return nothing
                rv = [], [], []
            elif self.select_count == 1:
                # second time around, return the socket as available for
                # reading.  This happens when the socket gets closed
                rv = [mock_socket], [], []
            else:
                raise AssertionError("select called too much")
            self.select_count += 1
            return rv

        self.patch_function('select.select', mock_select)
        # calling get_revision() should set all the wheels in motion
        initial_revision = self.backend.data_set.revision
        new_revision = self.backend.get_revision(mock.Mock(), initial_revision,
                                                 mock_socket)
        # get_revision() should have returned before any changes happened.
        self.assertEquals(initial_revision, new_revision)
示例#18
0
 def test_reuse_retry(self):
     # if we get an error on one thread and the user response with RETRY,
     # then we should reuse that response if another thread sees an error.
     self.run_choice_dialog.return_value = dialogs.BUTTON_RETRY
     dialog = mock.Mock(title='test 1', description='test 2')
     # handle a backend error
     self.run_backend_dialog(dialog)
     self.assertEquals(self.run_choice_dialog.call_count, 1)
     self.assertEquals(dialog.run_callback.call_args[0][0],
                       dialogs.BUTTON_RETRY)
     # handle a frontend error, we should reuse the RETRY response
     retry_callback = mock.Mock()
     self.run_dialog('test 1', 'test 2', retry_callback)
     self.assertEquals(self.run_choice_dialog.call_count, 1)
     self.assertEquals(retry_callback.call_count, 1)
     # handle another frontend error this time we shouldn't reuse the RETRY
     # response
     self.run_dialog('test 1', 'test 2', retry_callback)
     self.assertEquals(self.run_choice_dialog.call_count, 2)
     self.assertEquals(retry_callback.call_count, 2)
示例#19
0
 def test_remove_from_list(self):
     playlist = playback.PlaybackPlaylist(self.item_list, 0, False, False)
     mock_handler = mock.Mock()
     playlist.connect("playing-info-changed", mock_handler)
     self.check_currently_playing(playlist, 0)
     # simulate an item getting removed from the list, we should still keep
     # playing the item
     removed = self.item_list.items.pop(0)
     self.item_list.emit('list-changed')
     self.assertEquals(mock_handler.call_count, 0)
     self.assertEquals(playlist.currently_playing, removed)
示例#20
0
 def setUp(self):
     MiroTestCase.setUp(self)
     self.renderer = itemrenderer.ItemRenderer()
     self.feed = models.Feed(u'http://example.com/feed.rss')
     self.item = testobjects.make_item(self.feed, u'item')
     self.manual_feed = models.Feed(u'dtv:manualFeed',
                                    initiallyAutoDownloadable=False)
     self.file_item = models.FileItem(self.make_temp_path(),
                                      self.manual_feed.id)
     app.saved_items = set()
     app.playback_manager = mock.Mock()
     app.playback_manager.item_resume_policy.return_value = False
示例#21
0
    def check_render(self, item):
        """Check that ItemRenderer can sucessfully render a row.

        NOTE: we don't actually check the correctness of the render, just that
        it doesn't crash.
        """
        self.renderer.attrs = {}
        self.renderer.info = self._get_item(item.id)
        context = mock.Mock()
        layout_manager = mock.Mock()
        hotspot = hover = None
        context.width = self.renderer.MIN_WIDTH
        context.height = self.renderer.HEIGHT
        mock_textbox = layout_manager.textbox.return_value
        mock_textbox.font.line_height.return_value = 16
        mock_textbox.get_size.return_value = (100, 16)
        layout_manager.current_font.line_height.return_value = 16
        layout_manager.current_font.ascent.return_value = 12
        for selected in (False, True):
            self.renderer.render(context, layout_manager, selected, hotspot,
                                 hover)
示例#22
0
 def test_backend_error_handling(self):
     # when the backend sees an error, it should send the
     # DatabaseErrorDialog to the frontend and the frontend should call
     # DBErrorHandler.run_backend_dialog().  This test is testing what
     # happens when run_backend_dialog() is called.
     self.run_choice_dialog.return_value = dialogs.BUTTON_RETRY
     dialog = mock.Mock(title='test 1', description='test 2')
     self.run_backend_dialog(dialog)
     self.assertEquals(self.run_choice_dialog.call_count, 1)
     self.assertEquals(dialog.run_callback.call_count, 1)
     self.assertEquals(dialog.run_callback.call_args,
                       ((dialogs.BUTTON_RETRY, ), {}))
示例#23
0
    def patch_function(self, function_name, new_function):
        """Use Mock to replace an existing function for a single test.

        function_name should be in the form "full.module.name.object".  For
        example "miro.startup.startup"

        This can also be used on a class object in order to return a different
        object, if we only use class objects as factory functions.

        :param function_name: name of the function to patch
        :param new_function: function object to replace it with
        """
        self.patch_for_test(function_name, mock.Mock(side_effect=new_function))
示例#24
0
文件: messagetest.py 项目: kmshi/miro
 def setUp(self):
     EventLoopTest.setUp(self)
     self.updater = metadataprogress.MetadataProgressUpdater()
     # make messages send immediately to speed up test execution
     self.updater.message_interval = 0.0
     # setup a fake device to use
     self.device = mock.Mock()
     self.device.id = 123
     # make our handler
     self.test_handler = TestFrontendMessageHandler()
     messages.FrontendMessage.install_handler(self.test_handler)
     # the warnings from MetadataProgressUpdater should be errors in the
     # test case
     self.log_filter.set_exception_level(logging.WARNING)
示例#25
0
 def test_item_change(self):
     playlist = playback.PlaybackPlaylist(self.item_list, 0, False, False)
     mock_handler = mock.Mock()
     playlist.connect("playing-info-changed", mock_handler)
     self.check_currently_playing(playlist, 0)
     # simulate an item changing titles
     new_item = mock.Mock(id=0, title='New item one', is_playable=True)
     self.item_list.items[0] = new_item
     self.item_list.emit('items-changed', set([new_item.id]))
     self.assertEquals(mock_handler.call_count, 1)
     self.assertEquals(playlist.currently_playing, new_item)
     # simulate an item that's not playing changing
     mock_handler.reset_mock()
     new_item2 = mock.Mock(id=2, title='New item three', is_playable=True)
     self.item_list.items[2] = new_item2
     self.item_list.emit('items-changed', set([new_item2.id]))
     self.assertEquals(mock_handler.call_count, 0)
     # simulate an item changing to not playable
     new_item3 = mock.Mock(id=0, title='New item one', is_playable=False)
     self.item_list.items[0] = new_item3
     self.item_list.emit('items-changed', set([new_item3.id]))
     self.assertEquals(mock_handler.call_count, 1)
     self.assertEquals(playlist.currently_playing, None)
示例#26
0
 def setUp(self):
     MiroTestCase.setUp(self)
     self.idle_scheduler = mock.Mock()
     self.init_data_package()
     self.setup_items()
     self.setup_connection_pool()
     self.force_wal_mode()
     self.setup_mock_message_handler()
     self.setup_tracker()
     # make the change tracker start fresh for the unittests.  Since we
     # don't know which change tracker our item type will use, we go for
     # the sledge hammer approach here and reset them all.
     models.Item.change_tracker.reset()
     models.DeviceItem.change_tracker.reset()
     models.SharingItem.change_tracker.reset()
示例#27
0
    def init_data_package(self):
        """Initialize the data package

        The data package is used by the frontend to get data.

        Note: Since data uses a different connection than the backend system
        (storedatabase and friends), we need to create an on-disk database.
        """
        self.db_path = self.make_temp_path(".sqlite")
        if os.path.exists(self.db_path):
            os.unlink(self.db_path)
        self.reload_database(FilenameType(self.db_path))
        data.init(self.db_path)
        # use a mock objects for the database error handler
        app.db_error_handler = mock.Mock()
示例#28
0
    def patch_for_test(self, object_name, mock_object=None):
        """Use Mock to replace a function/class/object with a mock object.

        We will unpatch the object during teardown

        :param object_name: name of the object to patch
        :param mock_object: object to patch with, if None we will create a new
        Mock
        :returns: object used to patch
        """
        if mock_object is None:
            mock_object = mock.Mock()
        patcher = mock.patch(object_name, mock_object)
        patcher.start()
        self.mock_patchers.append(patcher)
        return mock_object
示例#29
0
    def test_nested_frontend_errors(self):
        retry_callback = mock.Mock()

        def run_choice_dialog(title, description, buttons):
            # simulate several other errors while running the dialog
            self.run_dialog('test 1', 'test 2', retry_callback)
            self.run_dialog('test 1', 'test 2', retry_callback)
            self.run_dialog('test 1', 'test 2', retry_callback)
            return dialogs.BUTTON_RETRY

        self.run_choice_dialog.side_effect = run_choice_dialog
        self.run_dialog('test 1', 'test 2', retry_callback)
        # even though we saw 4 errors, only 1 dialog should be shown
        self.assertEquals(self.run_choice_dialog.call_count, 1)
        # the retry_callback should be called for each run_dialog() call.
        self.assertEquals(retry_callback.call_count, 4)
示例#30
0
 def test_frontend_error_handling(self):
     self.run_choice_dialog.return_value = dialogs.BUTTON_RETRY
     # the frontend calls run_dialog() when it sees an error
     retry_callback = mock.Mock()
     self.run_dialog('test 1', 'test 2', retry_callback)
     # run_dialog() should pop up a choice dialog
     self.assertEquals(self.run_choice_dialog.call_count, 1)
     self.assertEquals(
         self.run_choice_dialog.call_args[0],
         ('test 1', 'test 2', [dialogs.BUTTON_RETRY, dialogs.BUTTON_QUIT]))
     self.assertEquals(self.run_choice_dialog.call_args[1], {})
     # since RETRY was chosen, the retry callback should be called
     self.assertEquals(retry_callback.call_count, 1)
     # try again with QUIT chosen.  In that case, the retry callback
     # shouldn't be called
     retry_callback.reset_mock()
     self.run_choice_dialog.return_value = dialogs.BUTTON_QUIT
     self.run_dialog('test 1', 'test 2', retry_callback)
     self.assertEquals(retry_callback.call_count, 0)