Exemplo n.º 1
0
 def test_dictionaries_option(self):
     section = config.SYSTEM_CONFIG_SECTION % config.DEFAULT_SYSTEM_NAME
     option = config.SYSTEM_DICTIONARIES_OPTION
     legacy_section = config.LEGACY_DICTIONARY_CONFIG_SECTION
     legacy_option = config.LEGACY_DICTIONARY_FILE_OPTION
     c = config.Config()
     config_dir = os.path.normcase(os.path.realpath(config.CONFIG_DIR))
     # Check the default value.
     self.assertEqual(c.get_dictionaries(),
                      [DictionaryConfig(path)
                       for path in system.DEFAULT_DICTIONARIES])
     # Load from a file encoded the ancient way...
     filename = normalize_path('/some_file')
     f = make_config('[%s]\n%s: %s' % (legacy_section, legacy_option, filename))
     c.load(f)
     # ..and make sure the right value is set.
     self.assertEqual(c.get_dictionaries(), [DictionaryConfig(filename)])
     # Load from a file encoded the old way...
     filenames = [os.path.join(ABS_PATH, f) for f in ('b', 'a', 'd', 'c')]
     dictionaries = [DictionaryConfig(path) for path in filenames]
     value = '\n'.join('%s%d: %s' % (legacy_option, d, v)
                           for d, v in enumerate(reversed(filenames), start=1))
     f = make_config('[%s]\n%s' % (legacy_section, value))
     c.load(f)
     # ...and make sure the right value is set.
     self.assertEqual(c.get_dictionaries(), dictionaries)
     # Check the config is saved back converted to the new way.
     f = make_config()
     c.save(f)
     new_config_contents = '[%s]\n%s = %s\n\n' % (
         section, option, json.dumps([
             {'path': path, 'enabled': True}
             for path in filenames
         ], sort_keys=True))
     self.assertEqual(f.getvalue().decode('utf-8'), new_config_contents)
     # Load from a file encoded the new way...
     f = make_config(new_config_contents)
     c.load(f)
     # ...and make sure the right value is set.
     self.assertEqual(c.get_dictionaries(), dictionaries)
     # Set a value...
     dictionaries.reverse()
     filenames.reverse()
     c.set_dictionaries(dictionaries)
     f = make_config()
     # ...save it...
     c.save(f)
     # ...and make sure it's right.
     new_config_contents = '[%s]\n%s = %s\n\n' % (
         section, option, json.dumps([
             {'path': path, 'enabled': True}
             for path in filenames
         ], sort_keys=True))
     self.assertEqual(f.getvalue().decode('utf-8'), new_config_contents)
     # The new way must take precedence over the old way.
     legacy_value = '\n'.join('%s%d = %s' % (legacy_option, d, v)
                           for d, v in enumerate(['/foo', '/bar'], start=1))
     f = make_config(new_config_contents + '\n[%s]\n%s\n' % ( legacy_section, legacy_value))
     c.load(f)
     self.assertEqual(c.get_dictionaries(), dictionaries)
Exemplo n.º 2
0
 def test_config_dict(self):
     short_path = os.path.normpath('~/foo/bar')
     full_path = os.path.expanduser(os.path.normpath('~/foo/bar'))
     # Path should be expanded.
     self.assertEqual(DictionaryConfig(short_path).path, full_path)
     self.assertEqual(DictionaryConfig(full_path).path, full_path)
     # Short path is available through `short_path`.
     self.assertEqual(DictionaryConfig(full_path).short_path, short_path)
     self.assertEqual(DictionaryConfig(short_path).short_path, short_path)
     # Enabled default to True.
     self.assertEqual(DictionaryConfig('foo').enabled, True)
     self.assertEqual(DictionaryConfig('foo', False).enabled, False)
     # When converting to a dict (for dumping to JSON),
     # a dictionary with the shortened path is used.
     self.assertEqual(
         DictionaryConfig(full_path).to_dict(), {
             'path': short_path,
             'enabled': True
         })
     self.assertEqual(
         DictionaryConfig(short_path, False).to_dict(), {
             'path': short_path,
             'enabled': False
         })
     # Test from_dict creation helper.
     self.assertEqual(
         config.DictionaryConfig.from_dict({'path': short_path}),
         DictionaryConfig(short_path))
     self.assertEqual(
         config.DictionaryConfig.from_dict({
             'path': full_path,
             'enabled': False
         }), DictionaryConfig(short_path, False))
Exemplo n.º 3
0
 def test_as_dict_update(self):
     opt_list = '''
         auto_start
         classic_dictionaries_display_order
         dictionaries
         enable_stroke_logging
         enable_translation_logging
         enabled_extensions
         log_file_name
         machine_specific_options
         machine_type
         show_stroke_display
         show_suggestions_display
         space_placement
         start_attached
         start_capitalized
         start_minimized
         system_keymap
         system_name
         translation_frame_opacity
         undo_levels
     '''.split()
     cfg = config.Config()
     excepted_dict = {opt: getattr(cfg, 'get_' + opt)() for opt in opt_list}
     self.assertEqual(cfg.as_dict(), excepted_dict)
     update = {
         'auto_start': False,
         'dictionaries': [DictionaryConfig('user.json', False)],
         'enable_stroke_logging': False,
         'space_placement': 'After Output',
         'start_minimized': False,
     }
     cfg.update(**update)
     excepted_dict.update(update)
     self.assertEqual(cfg.as_dict(), excepted_dict)
Exemplo n.º 4
0
 def _create_new_dictionary(self):
     new_filename = QFileDialog.getSaveFileName(
         self,
         _('New dictionary'),
         None,
         _dictionary_filters(include_readonly=False),
     )[0]
     if not new_filename:
         return
     new_filename = normalize_path(new_filename)
     try:
         d = create_dictionary(new_filename, threaded_save=False)
         d.save()
     except:
         log.error('creating dictionary %s failed',
                   new_filename,
                   exc_info=True)
         return
     dictionaries = self._config_dictionaries[:]
     for d in dictionaries:
         if d.path == new_filename:
             break
     else:
         dictionaries.insert(0, DictionaryConfig(new_filename))
     # Note: pass in `loaded_dictionaries` to force update (use case:
     # the user decided to overwrite an already loaded dictionary).
     self._update_dictionaries(
         dictionaries,
         keep_selection=False,
         loaded_dictionaries=self._loaded_dictionaries)
Exemplo n.º 5
0
 def test_dictionary_config(self):
     short_path = os.path.normcase(os.path.normpath('~/foo/bar'))
     full_path = os.path.normcase(os.path.expanduser(os.path.normpath('~/foo/bar')))
     dc = DictionaryConfig(short_path)
     # Path should be expanded.
     self.assertEqual(dc.path, full_path)
     # Shortened path is available through short_path.
     self.assertEqual(dc.short_path, short_path)
     # Enabled default to True.
     self.assertEqual(dc.enabled, True)
     # Check conversion to dict: short path should be used.
     self.assertEqual(dc.to_dict(), {'path': short_path, 'enabled': True})
     # Test replace method.
     dc = dc.replace(enabled=False)
     self.assertEqual(dc.path, full_path)
     self.assertEqual(dc.enabled, False)
     # Test creation from dict.
     self.assertEqual(DictionaryConfig.from_dict({'path': short_path, 'enabled': False}), dc)
Exemplo n.º 6
0
def backup_dictionary_stack(dictionaries, path):
    if dictionaries:
        with open(path, 'w') as f:
            json.dump([DictionaryConfig.to_dict(d) for d in dictionaries], f)
    else:
        try:
            os.remove(path)
        except OSError:
            pass  #Good, we didn't want it anyway!
Exemplo n.º 7
0
 def setUp(self):
     self.spanish = DictionaryConfig('spanish/main.json')
     self.english = DictionaryConfig('main.json')
     self.commands = DictionaryConfig('commands.json')
     self.user = DictionaryConfig('user.json')
     self.extra = DictionaryConfig('extra.json')
     self.engine = FakeEngine([
         self.user,
         self.commands,
         self.english,
         self.spanish,
     ])
     solo_state[SOLO_ENABLED] = False
     solo_state[SOLO_DICT_HAS_RUN] = False
     self.tf = tempfile.NamedTemporaryFile(delete=False)
     pdc.BACKUP_DICTIONARY_PATH = self.tf.name
Exemplo n.º 8
0
 def handle(self, words=[]):
     path = normalize_path(" ".join(words))
     if not isfile(path):
         self.output(f"{path} is not a file")
         return True
     with self.engine:
         self.output(f"Adding {path} as a dictionary")
         dicts = self.engine.config["dictionaries"].copy()
         dicts.insert(0, DictionaryConfig(path))
         self.engine.config = {"dictionaries": dicts}
         return True
Exemplo n.º 9
0
def test_config_dict():
    short_path = os.path.normcase(os.path.normpath('~/foo/bar'))
    full_path = os.path.normcase(os.path.expanduser(os.path.normpath('~/foo/bar')))
    # Path should be expanded.
    assert DictionaryConfig(short_path).path == full_path
    assert DictionaryConfig(full_path).path == full_path
    # Short path is available through `short_path`.
    assert DictionaryConfig(full_path).short_path == short_path
    assert DictionaryConfig(short_path).short_path == short_path
    # Enabled default to True.
    assert DictionaryConfig('foo').enabled
    assert not DictionaryConfig('foo', False).enabled
    # When converting to a dict (for dumping to JSON),
    # a dictionary with the shortened path is used.
    assert DictionaryConfig(full_path).to_dict() == \
            {'path': short_path, 'enabled': True}
    assert DictionaryConfig(short_path, False).to_dict() == \
            {'path': short_path, 'enabled': False}
    # Test from_dict creation helper.
    assert DictionaryConfig.from_dict({'path': short_path}) == \
            DictionaryConfig(short_path)
    assert DictionaryConfig.from_dict({'path': full_path, 'enabled': False}) == \
            DictionaryConfig(short_path, False)
Exemplo n.º 10
0
 def on_add_dictionaries(self):
     filters = ['*.' + ext for ext in sorted(_dictionary_formats())]
     new_filenames = QFileDialog.getOpenFileNames(
         self,
         _('Add dictionaries'),
         None,
         _('Dictionary Files') + ' (%s)' % ' '.join(filters),
     )[0]
     dictionaries = self._config_dictionaries[:]
     for filename in new_filenames:
         for d in dictionaries:
             if d.path == filename:
                 break
         else:
             dictionaries.insert(0, DictionaryConfig(filename))
     self._update_dictionaries(dictionaries, keep_selection=False)
Exemplo n.º 11
0
 def _add_existing_dictionaries(self):
     new_filenames = QFileDialog.getOpenFileNames(
         self,
         _('Add dictionaries'),
         None,
         _dictionary_filters(),
     )[0]
     dictionaries = self._config_dictionaries[:]
     for filename in new_filenames:
         filename = normalize_path(filename)
         for d in dictionaries:
             if d.path == filename:
                 break
         else:
             dictionaries.insert(0, DictionaryConfig(filename))
     self._update_dictionaries(dictionaries, keep_selection=False)
Exemplo n.º 12
0
 def _insert(self, dest_row, path_list):
     old_path_list = [item.path for item in self._from_row]
     new_path_list = (
         [p for p in old_path_list[:dest_row] if p not in path_list] +
         path_list +
         [p for p in old_path_list[dest_row:] if p not in path_list])
     if new_path_list == old_path_list:
         return
     if self._reverse_order:
         new_path_list = reversed(new_path_list)
     config = [
         self._from_path[path].config
         if path in self._from_path else DictionaryConfig(path)
         for path in new_path_list
     ]
     self._reset_items(config)
Exemplo n.º 13
0
 def _add_existing_dictionaries(self):
     new_filenames = QFileDialog.getOpenFileNames(
         # i18n: Widget: “DictionariesWidget”, “add” file picker.
         parent=self,
         caption=_('Add dictionaries'),
         directory=self._file_dialogs_directory,
         filter=_dictionary_filters(),
     )[0]
     dictionaries = self._config_dictionaries[:]
     for filename in new_filenames:
         filename = normalize_path(filename)
         self._file_dialogs_directory = os.path.dirname(filename)
         for d in dictionaries:
             if d.path == filename:
                 break
         else:
             dictionaries.insert(0, DictionaryConfig(filename))
     self._update_dictionaries(dictionaries, keep_selection=False)
Exemplo n.º 14
0
def load_dictionary_stack_from_backup(path):
    try:
        with open(path, 'r') as f:
            try:
                dictionaries = json.load(f)
            except json.JSONDecodeError:
                dictionaries = None
        if dictionaries:
            old_dictionaries = [
                DictionaryConfig.from_dict(x) for x in dictionaries
            ]
            os.remove(path)  #backup recovered, delete file
            return old_dictionaries
        else:
            return None
    except IOError:
        # No backup file, no problem
        return None
Exemplo n.º 15
0
 def _create_new_dictionary(self):
     # i18n: Widget: “DictionariesWidget”, “new” file picker.
     new_filename = self._get_dictionary_save_name(_('New dictionary'))
     if new_filename is None:
         return
     with _new_dictionary(new_filename) as d:
         pass
     dictionaries = self._config_dictionaries[:]
     for d in dictionaries:
         if d.path == new_filename:
             break
     else:
         dictionaries.insert(0, DictionaryConfig(new_filename))
     # Note: pass in `loaded_dictionaries` to force update (use case:
     # the user decided to overwrite an already loaded dictionary).
     self._update_dictionaries(
         dictionaries,
         keep_selection=False,
         loaded_dictionaries=self._loaded_dictionaries)
Exemplo n.º 16
0
 def _drop_event(self, event):
     if not self.is_accepted_drag_event(event):
         return
     dictionaries = self._config_dictionaries[:]
     dest_item = self.table.itemAt(event.pos())
     if dest_item is None:
         if self._reverse_order:
             dest_index = 0
         else:
             dest_index = len(self._config_dictionaries)
     else:
         dest_index = dest_item.row()
         if self._reverse_order:
             dest_index = len(self._config_dictionaries) - dest_index - 1
     if event.source() == self.table:
         sources = [dictionaries[row] for row in self._get_selection()]
     else:
         sources = [
             DictionaryConfig(url.toLocalFile())
             for url in event.mimeData().urls()
         ]
     for dictionary in sources:
         try:
             source_index = [d.path
                             for d in dictionaries].index(dictionary.path)
         except ValueError:
             pass
         else:
             if source_index == dest_index:
                 dest_index += 1
                 continue
             del dictionaries[source_index]
             if source_index < dest_index:
                 dest_index -= 1
         dictionaries.insert(dest_index, dictionary)
         dest_index += 1
     self._update_dictionaries(dictionaries, keep_selection=False)
Exemplo n.º 17
0
def test_loading_dictionaries(engine):
    def check_loaded_events(actual_events, expected_events):
        assert len(actual_events) == len(expected_events)
        for n, event in enumerate(actual_events):
            event_type, event_args, event_kwargs = event
            msg = 'event %u: %r' % (n, event)
            assert event_type == 'dictionaries_loaded', msg
            assert event_kwargs == {}, msg
            assert len(event_args) == 1, msg
            assert isinstance(event_args[0], StenoDictionaryCollection), msg
            assert [(d.path, d.enabled, isinstance(d, ErroredDictionary))
                    for d in event_args[0].dicts] == expected_events[n], msg
    with \
            make_dict(b'{}', 'json', 'valid1') as valid_dict_1, \
            make_dict(b'{}', 'json', 'valid2') as valid_dict_2, \
            make_dict(b'', 'json', 'invalid1') as invalid_dict_1, \
            make_dict(b'', 'json', 'invalid2') as invalid_dict_2:
        engine.start()
        for new_dictionaries, *expected_events in (
                # Load one valid dictionary.
            [
                [
                    # path, enabled
                    (valid_dict_1, True),
                ],
                [
                    # path, enabled, errored
                    (valid_dict_1, True, False),
                ]
            ],
                # Load another invalid dictionary.
            [[
                (valid_dict_1, True),
                (invalid_dict_1, True),
            ], [
                (valid_dict_1, True, False),
                (invalid_dict_1, True, True),
            ]],
                # Disable first dictionary.
            [[
                (valid_dict_1, False),
                (invalid_dict_1, True),
            ], [
                (valid_dict_1, False, False),
                (invalid_dict_1, True, True),
            ]],
                # Replace invalid dictonary with another invalid one.
            [[
                (valid_dict_1, False),
                (invalid_dict_2, True),
            ], [
                (valid_dict_1, False, False),
            ], [
                (valid_dict_1, False, False),
                (invalid_dict_2, True, True),
            ]]):
            engine.events.clear()
            config_update = {
                'dictionaries':
                [DictionaryConfig(*d) for d in new_dictionaries]
            }
            engine.config = dict(config_update)
            assert engine.events[0] == ('config_changed', (config_update, ),
                                        {})
            check_loaded_events(engine.events[1:], expected_events)
        # Simulate an outdated dictionary.
        engine.events.clear()
        engine.dictionaries[valid_dict_1].timestamp -= 1
        engine.config = {}
        check_loaded_events(engine.events, [[
            (invalid_dict_2, True, True),
        ], [
            (valid_dict_1, False, False),
            (invalid_dict_2, True, True),
        ]])
Exemplo n.º 18
0
def config_dictionaries_from_state(state_str):
    return [
        DictionaryConfig(path, enabled)
        for enabled, icon, path in parse_state(state_str)
    ]
Exemplo n.º 19
0
 def test_loading_dictionaries(self):
     def check_loaded_events(actual_events, expected_events):
         self.assertEqual(len(actual_events),
                          len(expected_events),
                          msg='events: %r' % self.events)
         for n, event in enumerate(actual_events):
             event_type, event_args, event_kwargs = event
             msg = 'event %u: %r' % (n, event)
             self.assertEqual(event_type, 'dictionaries_loaded', msg=msg)
             self.assertEqual(event_kwargs, {}, msg=msg)
             self.assertEqual(len(event_args), 1, msg=msg)
             self.assertIsInstance(event_args[0],
                                   StenoDictionaryCollection,
                                   msg=msg)
             self.assertEqual(
                 [(d.path, d.enabled, isinstance(d, ErroredDictionary))
                  for d in event_args[0].dicts],
                 expected_events[n],
                 msg=msg)
     with \
             make_dict(b'{}', 'json', 'valid1') as valid_dict_1, \
             make_dict(b'{}', 'json', 'valid2') as valid_dict_2, \
             make_dict(b'', 'json', 'invalid1') as invalid_dict_1, \
             make_dict(b'', 'json', 'invalid2') as invalid_dict_2, \
             self._setup():
         self.engine.start()
         for test in (
                 # Load one valid dictionary.
             [
                 [
                     # path, enabled
                     (valid_dict_1, True),
                 ],
                 [
                     # path, enabled, errored
                     (valid_dict_1, True, False),
                 ]
             ],
                 # Load another invalid dictionary.
             [[
                 (valid_dict_1, True),
                 (invalid_dict_1, True),
             ], [
                 (valid_dict_1, True, False),
                 (invalid_dict_1, True, True),
             ]],
                 # Disable first dictionary.
             [[
                 (valid_dict_1, False),
                 (invalid_dict_1, True),
             ],
              [
                  (valid_dict_1, False, False),
                  (invalid_dict_1, True, True),
              ]],
                 # Replace invalid dictonary with another invalid one.
             [[
                 (valid_dict_1, False),
                 (invalid_dict_2, True),
             ], [
                 (valid_dict_1, False, False),
             ],
              [
                  (valid_dict_1, False, False),
                  (invalid_dict_2, True, True),
              ]]):
             config_dictionaries = [
                 DictionaryConfig(path, enabled)
                 for path, enabled in test[0]
             ]
             self.events = []
             config_update = {
                 'dictionaries': list(config_dictionaries),
             }
             self.engine.config = dict(config_update)
             self.assertEqual(self.events[0],
                              ('config_changed', (config_update, ), {}))
             check_loaded_events(self.events[1:], test[1:])
         # Simulate an outdated dictionary.
         self.events = []
         self.engine.dictionaries[valid_dict_1].timestamp -= 1
         self.engine.config = {}
         check_loaded_events(self.events, [[
             (invalid_dict_2, True, True),
         ], [
             (valid_dict_1, False, False),
             (invalid_dict_2, True, True),
         ]])
Exemplo n.º 20
0
def test_config_dict():
    short_path = os.path.normcase(os.path.normpath('~/foo/bar'))
    full_path = os.path.normcase(
        os.path.expanduser(os.path.normpath('~/foo/bar')))
    # Path should be expanded.
    assert DictionaryConfig(short_path).path == full_path
    assert DictionaryConfig(full_path).path == full_path
    # Short path is available through `short_path`.
    assert DictionaryConfig(full_path).short_path == short_path
    assert DictionaryConfig(short_path).short_path == short_path
    # Enabled default to True.
    assert DictionaryConfig('foo').enabled
    assert not DictionaryConfig('foo', False).enabled
    # When converting to a dict (for dumping to JSON),
    # a dictionary with the shortened path is used.
    assert DictionaryConfig(full_path).to_dict() == \
            {'path': short_path, 'enabled': True}
    assert DictionaryConfig(short_path, False).to_dict() == \
            {'path': short_path, 'enabled': False}
    # Test from_dict creation helper.
    assert DictionaryConfig.from_dict({'path': short_path}) == \
            DictionaryConfig(short_path)
    assert DictionaryConfig.from_dict({'path': full_path, 'enabled': False}) == \
            DictionaryConfig(short_path, False)
Exemplo n.º 21
0
    False,
    'enabled_extensions':
    set(),
    'auto_start':
    False,
    'machine_type':
    'Keyboard',
    'machine_specific_options': {
        'arpeggiate': False
    },
    'system_name':
    config.DEFAULT_SYSTEM_NAME,
    'system_keymap':
    DEFAULT_KEYMAP,
    'dictionaries':
    [DictionaryConfig(p) for p in english_stenotype.DEFAULT_DICTIONARIES]
}

CONFIG_TESTS = (
    (
        'defaults',
        '''
     ''',
        DEFAULTS,
        {},
        {},
        '''
     ''',
    ),
    (
        'simple_options',
Exemplo n.º 22
0
 def config(self):
     return DictionaryConfig(self.path, self.enabled)
Exemplo n.º 23
0
class DictCommandsTest(unittest.TestCase):
    def setUp(self):
        self.spanish = DictionaryConfig('spanish/main.json')
        self.english = DictionaryConfig('main.json')
        self.commands = DictionaryConfig('commands.json')
        self.user = DictionaryConfig('user.json')
        self.extra = DictionaryConfig('extra.json')
        self.engine = FakeEngine([
            self.user,
            self.commands,
            self.english,
            self.spanish,
        ])
        solo_state[SOLO_ENABLED] = False
        solo_state[SOLO_DICT_HAS_RUN] = False
        self.tf = tempfile.NamedTemporaryFile(delete=False)
        pdc.BACKUP_DICTIONARY_PATH = self.tf.name

    def tearDown(self):
        try:
            os.unlink(self.tf.name)
        except OSError:
            # This file gets deleted by the module being tested right now,
            # leave this here in case that changes to delete temp file
            # if necessary.
            pass

    def test_priority_dict_shortest_path_is_default(self):
        priority_dict(self.engine, 'main.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.english,
            self.user,
            self.commands,
            self.spanish,
        ])
        priority_dict(self.engine, 'spanish/main.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.spanish,
            self.english,
            self.user,
            self.commands,
        ])

    def test_priority_dict_multiple(self):
        priority_dict(self.engine,
                      'user.json, spanish/main.json, commands.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user,
            self.spanish,
            self.commands,
            self.english,
        ])

    def test_priority_dict_invalid(self):
        with self.assertRaises(ValueError):
            priority_dict(self.engine, 'foobar.json')

    def test_toggle_dict_shortest_path_is_default(self):
        toggle_dict(self.engine, '+main.json, -spanish/main.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user,
            self.commands,
            self.english.replace(enabled=True),
            self.spanish.replace(enabled=False),
        ])

    def test_toggle_dict_multiple(self):
        toggle_dict(self.engine,
                    '+spanish/main.json, !commands.json, -user.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user.replace(enabled=False),
            self.commands.replace(enabled=False),
            self.english,
            self.spanish,
        ])

    def test_toggle_dict_invalid_toggle(self):
        with self.assertRaises(ValueError):
            toggle_dict(self.engine, '=user.json')

    def test_toggle_dict_invalid_dictionary(self):
        with self.assertRaises(ValueError):
            toggle_dict(self.engine, '+foobar.json')

    def test_solo_dict(self):
        solo_dict(self.engine, '+spanish/main.json')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user.replace(enabled=False),
            self.commands.replace(enabled=False),
            self.english.replace(enabled=False),
            self.spanish,
        ])

    def test_end_solo_dict_doesnt_delete_new_dictionaries(self):
        solo_dict(self.engine, '+spanish/main.json')
        # ...then load a new dictionary while in the temporary mode
        dictionaries = self.engine.config['dictionaries']
        dictionaries.append(self.extra)
        self.engine.config = {'dictionaries': dictionaries}
        end_solo_dict(self.engine, '')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user,
            self.commands,
            self.english,
            self.spanish,
            self.extra,
        ])
        pass

    def test_backup_dictionaries_to_json_and_reload(self):
        original_dictionaries = self.engine.config['dictionaries']
        #import pdb; pdb.set_trace()
        backup_dictionary_stack(original_dictionaries,
                                pdc.BACKUP_DICTIONARY_PATH)
        toggle_dict(self.engine, '-main.json')
        self.assertEqual(
            self.engine.config['dictionaries'],
            [
                self.user,
                self.commands,
                self.english.replace(enabled=False),  # turned off
                self.spanish,
            ])
        restored_dictionaries = load_dictionary_stack_from_backup(
            pdc.BACKUP_DICTIONARY_PATH)
        self.engine.config = {'dictionaries': restored_dictionaries}
        self.assertEqual(
            self.engine.config['dictionaries'],
            [
                self.user,
                self.commands,
                self.english,  # turned back on again after restore
                self.spanish,
            ])
        backup_dictionary_stack([], pdc.BACKUP_DICTIONARY_PATH)
        #clear the file for the next test

    def test_backed_up_dictionaries_restored_after_solo_if_backup_exists(self):
        toggle_dict(self.engine, '-main.json')  #turned off before backup...
        original_dictionaries = self.engine.config['dictionaries']
        backup_dictionary_stack(original_dictionaries,
                                pdc.BACKUP_DICTIONARY_PATH)
        toggle_dict(self.engine, '+main.json')  #but normal before solo_dict

        #Now that there's a backup file, do the first solo_dict since we've run...
        solo_dict(self.engine, '+spanish/main.json')
        end_solo_dict(self.engine, '')

        self.assertEqual(
            self.engine.config['dictionaries'],
            [
                self.user,
                self.commands,
                self.english.replace(
                    enabled=False),  # turned back off again after restore
                self.spanish,
            ])

    def test_end_solo_dict_restores_previous_state(self):
        toggle_dict(self.engine, '-main.json')
        solo_dict(self.engine, '+spanish/main.json')
        end_solo_dict(self.engine, '')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user,
            self.commands,
            self.english.replace(enabled=False),
            self.spanish,
        ])

    def test_end_solo_dict_without_first_doing_solo_1(self):
        backup_dictionary_stack([
            self.spanish.replace(enabled=False),
            self.user.replace(enabled=False),
        ], pdc.BACKUP_DICTIONARY_PATH)
        end_solo_dict(self.engine, '')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user.replace(enabled=False),
            self.commands,
            self.english,
            self.spanish.replace(enabled=False),
        ])

    def test_end_solo_dict_without_first_doing_solo_2(self):
        backup_dictionary_stack([
            self.extra,
            self.english.replace(enabled=False),
        ], pdc.BACKUP_DICTIONARY_PATH)
        end_solo_dict(self.engine, '')
        self.assertEqual(self.engine.config['dictionaries'], [
            self.user,
            self.commands,
            self.english.replace(enabled=False),
            self.spanish,
        ])