141 lines
5.5 KiB
Python
141 lines
5.5 KiB
Python
|
|
|
||
|
|
import os
|
||
|
|
import shutil
|
||
|
|
import tempfile
|
||
|
|
import unittest
|
||
|
|
|
||
|
|
import mock
|
||
|
|
from mock import MagicMock, sentinel
|
||
|
|
|
||
|
|
import AnkiServer
|
||
|
|
from AnkiServer.collection import CollectionWrapper, CollectionManager
|
||
|
|
|
||
|
|
class CollectionWrapperTest(unittest.TestCase):
|
||
|
|
def setUp(self):
|
||
|
|
self.temp_dir = tempfile.mkdtemp()
|
||
|
|
self.collection_path = os.path.join(self.temp_dir, 'collection.anki2');
|
||
|
|
|
||
|
|
def tearDown(self):
|
||
|
|
shutil.rmtree(self.temp_dir)
|
||
|
|
|
||
|
|
def test_lifecycle_real(self):
|
||
|
|
"""Testing common life-cycle with existing and non-existant collections. This
|
||
|
|
test uses the real Anki objects and actually creates a new collection on disk."""
|
||
|
|
|
||
|
|
wrapper = CollectionWrapper(self.collection_path)
|
||
|
|
self.assertFalse(os.path.exists(self.collection_path))
|
||
|
|
self.assertFalse(wrapper.opened())
|
||
|
|
|
||
|
|
wrapper.open()
|
||
|
|
self.assertTrue(os.path.exists(self.collection_path))
|
||
|
|
self.assertTrue(wrapper.opened())
|
||
|
|
|
||
|
|
# calling open twice shouldn't break anything
|
||
|
|
wrapper.open()
|
||
|
|
|
||
|
|
wrapper.close()
|
||
|
|
self.assertTrue(os.path.exists(self.collection_path))
|
||
|
|
self.assertFalse(wrapper.opened())
|
||
|
|
|
||
|
|
# open the same collection again (not a creation)
|
||
|
|
wrapper = CollectionWrapper(self.collection_path)
|
||
|
|
self.assertFalse(wrapper.opened())
|
||
|
|
wrapper.open()
|
||
|
|
self.assertTrue(wrapper.opened())
|
||
|
|
wrapper.close()
|
||
|
|
self.assertFalse(wrapper.opened())
|
||
|
|
self.assertTrue(os.path.exists(self.collection_path))
|
||
|
|
|
||
|
|
def test_del(self):
|
||
|
|
with mock.patch('anki.storage.Collection') as anki_storage_Collection:
|
||
|
|
col = anki_storage_Collection.return_value
|
||
|
|
wrapper = CollectionWrapper(self.collection_path)
|
||
|
|
wrapper.open()
|
||
|
|
wrapper = None
|
||
|
|
col.close.assert_called_with()
|
||
|
|
|
||
|
|
def test_setup_func(self):
|
||
|
|
# Run it when the collection doesn't exist
|
||
|
|
with mock.patch('anki.storage.Collection') as anki_storage_Collection:
|
||
|
|
col = anki_storage_Collection.return_value
|
||
|
|
setup_new_collection = MagicMock()
|
||
|
|
self.assertFalse(os.path.exists(self.collection_path))
|
||
|
|
wrapper = CollectionWrapper(self.collection_path, setup_new_collection)
|
||
|
|
wrapper.open()
|
||
|
|
anki_storage_Collection.assert_called_with(self.collection_path)
|
||
|
|
setup_new_collection.assert_called_with(col)
|
||
|
|
wrapper = None
|
||
|
|
|
||
|
|
# Make sure that no collection was actually created
|
||
|
|
self.assertFalse(os.path.exists(self.collection_path))
|
||
|
|
|
||
|
|
# Create a faux collection file
|
||
|
|
with file(self.collection_path, 'wt') as fd:
|
||
|
|
fd.write('Collection!')
|
||
|
|
|
||
|
|
# Run it when the collection does exist
|
||
|
|
with mock.patch('anki.storage.Collection'):
|
||
|
|
setup_new_collection = lambda col: self.fail("Setup function called when collection already exists!")
|
||
|
|
self.assertTrue(os.path.exists(self.collection_path))
|
||
|
|
wrapper = CollectionWrapper(self.collection_path, setup_new_collection)
|
||
|
|
wrapper.open()
|
||
|
|
anki_storage_Collection.assert_called_with(self.collection_path)
|
||
|
|
wrapper = None
|
||
|
|
|
||
|
|
def test_execute(self):
|
||
|
|
with mock.patch('anki.storage.Collection') as anki_storage_Collection:
|
||
|
|
col = anki_storage_Collection.return_value
|
||
|
|
func = MagicMock()
|
||
|
|
func.return_value = sentinel.some_object
|
||
|
|
|
||
|
|
# check that execute works and auto-creates the collection
|
||
|
|
wrapper = CollectionWrapper(self.collection_path)
|
||
|
|
ret = wrapper.execute(func, [1, 2, 3], {'key': 'aoeu'})
|
||
|
|
self.assertEqual(ret, sentinel.some_object)
|
||
|
|
anki_storage_Collection.assert_called_with(self.collection_path)
|
||
|
|
func.assert_called_with(col, 1, 2, 3, key='aoeu')
|
||
|
|
|
||
|
|
# check that execute always returns False if waitForReturn=False
|
||
|
|
func.reset_mock()
|
||
|
|
ret = wrapper.execute(func, [1, 2, 3], {'key': 'aoeu'}, waitForReturn=False)
|
||
|
|
self.assertEqual(ret, None)
|
||
|
|
func.assert_called_with(col, 1, 2, 3, key='aoeu')
|
||
|
|
|
||
|
|
class CollectionManagerTest(unittest.TestCase):
|
||
|
|
def test_lifecycle(self):
|
||
|
|
with mock.patch('AnkiServer.collection.CollectionManager.collection_wrapper') as CollectionWrapper:
|
||
|
|
wrapper = MagicMock()
|
||
|
|
CollectionWrapper.return_value = wrapper
|
||
|
|
|
||
|
|
manager = CollectionManager()
|
||
|
|
|
||
|
|
# check getting a new collection
|
||
|
|
ret = manager.get_collection('path1')
|
||
|
|
CollectionWrapper.assert_called_with(os.path.realpath('path1'), None)
|
||
|
|
self.assertEqual(ret, wrapper)
|
||
|
|
|
||
|
|
# change the return value, so that it would return a new object
|
||
|
|
new_wrapper = MagicMock()
|
||
|
|
CollectionWrapper.return_value = new_wrapper
|
||
|
|
CollectionWrapper.reset_mock()
|
||
|
|
|
||
|
|
# get the new wrapper
|
||
|
|
ret = manager.get_collection('path2')
|
||
|
|
CollectionWrapper.assert_called_with(os.path.realpath('path2'), None)
|
||
|
|
self.assertEqual(ret, new_wrapper)
|
||
|
|
|
||
|
|
# make sure the wrapper and new_wrapper are different
|
||
|
|
self.assertNotEqual(wrapper, new_wrapper)
|
||
|
|
|
||
|
|
# assert that calling with the first path again, returns the first wrapper
|
||
|
|
ret = manager.get_collection('path1')
|
||
|
|
self.assertEqual(ret, wrapper)
|
||
|
|
|
||
|
|
manager.shutdown()
|
||
|
|
wrapper.close.assert_called_with()
|
||
|
|
new_wrapper.close.assert_called_with()
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
unittest.main()
|
||
|
|
|