def test_loading(self): class MockLoader(object): def __init__(self, files): self.files = files self.load_counts = defaultdict(int) def __call__(self, filename): self.load_counts[filename] += 1 return self.files[filename] files = {c: c * 5 for c in [chr(ord('a') + i) for i in range(10)]} loader = MockLoader(files) with patch('plover.dictionary.loading_manager.load_dictionary', loader): manager = loading_manager.DictionaryLoadingManager() manager.start_loading('a') manager.start_loading('b') results = manager.load(['c', 'b']) # Returns the right values in the right order. self.assertEqual(results, ['ccccc', 'bbbbb']) # Only loaded the files once. self.assertTrue(all(x == 1 for x in loader.load_counts.values())) # Dropped superfluous files. self.assertEqual(['b', 'c'], sorted(manager.dictionaries.keys()))
def test_loading(self): class FakeDictionaryContents(object): def __init__(self, contents, timestamp): self.contents = contents self.timestamp = timestamp def __eq__(self, other): if isinstance(other, FakeDictionaryContents): return self.contents == other.contents return self.contents == other class FakeDictionaryInfo(object): def __init__(self, name, contents): self.name = name self.contents = contents self.tf = tempfile.NamedTemporaryFile() def __repr__(self): return 'FakeDictionaryInfo(%r, %r)' % (self.name, self.contents) class MockLoader(object): def __init__(self, files): self.files = files self.load_counts = defaultdict(int) def __call__(self, filename): self.load_counts[filename] += 1 d = self.files[filename] if isinstance(d.contents, Exception): raise d.contents timestamp = os.path.getmtime(filename) return FakeDictionaryContents(d.contents, timestamp) dictionaries = {} for i in range(8): c = chr(ord('a') + i) contents = c * 5 if i >= 4: contents = Exception(contents) d = FakeDictionaryInfo(c, contents) assert d.tf.name not in dictionaries dictionaries[d.tf.name] = d assert c not in dictionaries dictionaries[c] = d def df(name): return dictionaries[name].tf.name loader = MockLoader(dictionaries) with patch('plover.dictionary.loading_manager.load_dictionary', loader): manager = loading_manager.DictionaryLoadingManager() manager.start_loading(df('a')).get() manager.start_loading(df('b')).get() results = manager.load([df('c'), df('b')]) # Returns the right values in the right order. self.assertEqual(results, ['ccccc', 'bbbbb']) # Dropped superfluous files. self.assertCountEqual([df('b'), df('c')], manager.dictionaries.keys()) # Check dict like interface. self.assertEqual(len(manager), 2) self.assertFalse(df('a') in manager) with self.assertRaises(KeyError): manager[df('a')] self.assertTrue(df('b') in manager) self.assertTrue(df('c') in manager) self.assertEqual(results, [manager[df('c')], manager[df('b')]]) # Return a DictionaryLoaderException for load errors. results = manager.load([df('c'), df('e'), df('b'), df('f')]) self.assertEqual(len(results), 4) self.assertEqual(results[0], 'ccccc') self.assertEqual(results[2], 'bbbbb') self.assertIsInstance(results[1], DictionaryLoaderException) self.assertEqual(results[1].path, df('e')) self.assertIsInstance(results[1].exception, Exception) self.assertIsInstance(results[3], DictionaryLoaderException) self.assertEqual(results[3].path, df('f')) self.assertIsInstance(results[3].exception, Exception) # Only loaded the files once. self.assertTrue(all(x == 1 for x in loader.load_counts.values())) # No reload if file timestamp is unchanged, or the dictionary # timestamp is more recent. (use case: dictionary edited with # Plover and saved back) file_timestamp = results[0].timestamp results[0].timestamp = file_timestamp + 1 dictionaries['c'].contents = 'CCCCC' results = manager.load([df('c')]) self.assertEqual(results, ['ccccc']) self.assertEqual(loader.load_counts[df('c')], 1) # Check outdated dictionaries are reloaded. results[0].timestamp = file_timestamp - 1 results = manager.load([df('c')]) self.assertEqual(results, ['CCCCC']) self.assertEqual(loader.load_counts[df('c')], 2) # Check trimming of outdated dictionaries. results[0].timestamp = file_timestamp - 1 manager.unload_outdated() self.assertEqual(len(manager), 0) self.assertFalse(df('c') in manager)
def test_loading(monkeypatch): dictionaries = {} for i in range(8): c = chr(ord('a') + i) contents = c * 5 if i >= 4: contents = Exception(contents) d = FakeDictionaryInfo(c, contents) assert d.tf.name not in dictionaries dictionaries[d.tf.name] = d assert c not in dictionaries dictionaries[c] = d def df(name): return dictionaries[name].tf.name loader = MockLoader(dictionaries) monkeypatch.setattr('plover.dictionary.loading_manager.load_dictionary', loader) manager = loading_manager.DictionaryLoadingManager() manager.start_loading(df('a')).get() manager.start_loading(df('b')).get() results = manager.load([df('c'), df('b')]) # Returns the right values in the right order. assert results == ['ccccc', 'bbbbb'] # Dropped superfluous files. assert sorted([df('b'), df('c')]) == sorted(manager.dictionaries.keys()) # Check dict like interface. assert len(manager) == 2 assert df('a') not in manager with pytest.raises(KeyError): manager[df('a')] assert df('b') in manager assert df('c') in manager assert results == [manager[df('c')], manager[df('b')]] # Return a DictionaryLoaderException for load errors. results = manager.load([df('c'), df('e'), df('b'), df('f')]) assert len(results) == 4 assert results[0] == 'ccccc' assert results[2] == 'bbbbb' assert isinstance(results[1], DictionaryLoaderException) assert results[1].path == df('e') assert isinstance(results[1].exception, Exception) assert isinstance(results[3], DictionaryLoaderException) assert results[3].path == df('f') assert isinstance(results[3].exception, Exception) # Only loaded the files once. assert all(x == 1 for x in loader.load_counts.values()) # No reload if file timestamp is unchanged, or the dictionary # timestamp is more recent. (use case: dictionary edited with # Plover and saved back) file_timestamp = results[0].timestamp results[0].timestamp = file_timestamp + 1 dictionaries['c'].contents = 'CCCCC' results = manager.load([df('c')]) assert results == ['ccccc'] assert loader.load_counts[df('c')] == 1 # Check outdated dictionaries are reloaded. results[0].timestamp = file_timestamp - 1 results = manager.load([df('c')]) assert results == ['CCCCC'] assert loader.load_counts[df('c')] == 2 # Check trimming of outdated dictionaries. results[0].timestamp = file_timestamp - 1 manager.unload_outdated() assert len(manager) == 0 assert df('c') not in manager
def test_loading(self): class FakeDictionaryContents(object): def __init__(self, contents, timestamp): self.contents = contents self.timestamp = timestamp def __eq__(self, other): if isinstance(other, FakeDictionaryContents): return self.contents == other.contents return self.contents == other class FakeDictionaryInfo(object): def __init__(self, name, contents): self.name = name self.contents = contents self.tf = tempfile.NamedTemporaryFile() self.timestamp = os.path.getmtime(self.tf.name) def __repr__(self): return 'FakeDictionaryInfo(%r, %r)' % (self.name, self.contents) class MockLoader(object): def __init__(self, files): self.files = files self.load_counts = defaultdict(int) def __call__(self, filename): self.load_counts[filename] += 1 d = self.files[filename] if isinstance(d.contents, Exception): raise d.contents return FakeDictionaryContents(d.contents, d.timestamp) dictionaries = {} for i in range(8): c = chr(ord('a') + i) contents = c * 5 if i >= 4: contents = Exception(contents) d = FakeDictionaryInfo(c, contents) assert d.tf.name not in dictionaries dictionaries[d.tf.name] = d assert c not in dictionaries dictionaries[c] = d def df(name): return dictionaries[name].tf.name loader = MockLoader(dictionaries) with patch('plover.dictionary.loading_manager.load_dictionary', loader): manager = loading_manager.DictionaryLoadingManager() manager.start_loading(df('a')) manager.start_loading(df('b')) results = manager.load([df('c'), df('b')]) # Returns the right values in the right order. self.assertEqual(results, ['ccccc', 'bbbbb']) # Dropped superfluous files. assertCountEqual(self, [df('b'), df('c')], manager.dictionaries.keys()) # Return a DictionaryLoaderException for load errors. results = manager.load([df('c'), df('e'), df('b'), df('f')]) self.assertEqual(len(results), 4) self.assertEqual(results[0], 'ccccc') self.assertEqual(results[2], 'bbbbb') self.assertIsInstance(results[1], DictionaryLoaderException) self.assertEqual(results[1].path, df('e')) self.assertIsInstance(results[1].exception, Exception) self.assertIsInstance(results[3], DictionaryLoaderException) self.assertEqual(results[3].path, df('f')) self.assertIsInstance(results[3].exception, Exception) # Only loaded the files once. self.assertTrue(all(x == 1 for x in loader.load_counts.values())) # No reload if timestamp is unchanged, or more recent. # (use case: dictionary edited with Plover and saved back) dictionaries['c'].contents = 'CCCCC' dictionaries['c'].timestamp += 1 results = manager.load([df('c')]) self.assertEqual(results, ['ccccc']) self.assertEqual(loader.load_counts[df('c')], 1) # Check files are reloaded when modified. # Note: do not try to "touch" the file using os.utime # as it's not reliable without sleeping to account # for operating system resolution. mtime = os.path.getmtime(df('c')) def getmtime(path): assert path == df('c') return mtime + 1 with patch('os.path.getmtime', getmtime): results = manager.load([df('c')]) self.assertEqual(results, ['CCCCC']) self.assertEqual(loader.load_counts[df('c')], 2)