123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- import unittest
- from unittest.mock import patch
-
- from EditorialModel.model import Model
- from EditorialModel.classes import EmClass
- from EditorialModel.types import EmType
- from EditorialModel.fields import EmField
- from EditorialModel.components import EmComponent
- from Lodel.utils.mlstring import MlString
-
-
- from EditorialModel.backend.json_backend import EmBackendJson
- from EditorialModel.backend.dummy_backend import EmBackendDummy
- from EditorialModel.migrationhandler.dummy import DummyMigrationHandler
-
-
- class TestModel(unittest.TestCase):
-
- def setUp(self):
- self.ed_mod = Model(EmBackendJson('EditorialModel/test/me.json'))
-
- def test_init(self):
- """ Instanciation test """
- model = Model(EmBackendJson('EditorialModel/test/me.json'))
- self.assertTrue(isinstance(model, Model))
-
- model = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DummyMigrationHandler())
- self.assertTrue(isinstance(model, Model))
-
- def test_bad_init(self):
- """ Test initialisation with bad arguments """
- for bad in [None, int, EmBackendDummy, DummyMigrationHandler, 'foobar']:
- with self.assertRaises(TypeError, msg="Tried to instanciate a Model with a bad backend"):
- Model(bad)
- for bad in [int, EmBackendDummy, DummyMigrationHandler, 'foobar']:
- with self.assertRaises(TypeError, msg="Tried to instanciate a Model with a migration_handler"):
- Model(EmBackendDummy(), bad)
-
- def test_components(self):
- """ Test components fetching """
- uid_l = list()
- for comp_class in [EmClass, EmType, EmField]:
- comp_l = self.ed_mod.components(comp_class)
- #Testing types of returned components
- for component in comp_l:
- self.assertTrue(isinstance(component, comp_class), "Model.components method doesn't return EmComponent of the right type. Asked for {} but got {}".format(type(comp_class), type(component)))
- uid_l.append(component.uid)
-
- #Testing that we have fetched all the components
- for uid in self.ed_mod._components['uids']:
- self.assertIn(uid, uid_l, "Component with uid %d was not fetched" % uid)
-
- #Testing components method without parameters
- uid_l = [comp.uid for comp in self.ed_mod.components()]
-
- for uid in self.ed_mod._components['uids']:
- self.assertIn(uid, uid_l, "Component with uid %d was not fetched using me.components()" % uid)
-
- self.assertFalse(self.ed_mod.components(EmComponent))
- self.assertFalse(self.ed_mod.components(int))
-
- def test_component(self):
- """ Test component fetching by uid """
- #assert that __hash__, __eq__ and components() are corrects
- for comp in self.ed_mod.components():
- self.assertEqual(comp, self.ed_mod.component(comp.uid))
-
- for baduid in [-1, 0xffffff, "hello"]:
- self.assertFalse(self.ed_mod.component(baduid))
-
- def test_sort_components(self):
- """ Test that Model.sort_components method actually sort components """
- # disordering an EmClass
- cl_l = self.ed_mod.components(EmClass)
- last_class = cl_l[0]
- last_class.rank = 10000
- self.ed_mod.sort_components(EmClass)
- self.assertEqual(self.ed_mod._components['EmClass'][-1].uid, last_class.uid, "The sort_components method doesn't really sort by rank")
-
- def test_new_uid(self):
- """ Test that model.new_uid return a new uniq uid """
- new_uid = self.ed_mod.new_uid()
- self.assertNotIn(new_uid, self.ed_mod._components['uids'].keys())
-
- def test_create_component_fails(self):
- """ Test the create_component method with invalid arguments """
-
- test_datas = {
- 'name': 'FooBar',
- 'classtype': 'entity',
- 'help_text': None,
- 'string': None,
- }
-
- #Invalid uid
- used_uid = self.ed_mod.components()[0].uid
- for bad_uid in [used_uid, -1, -1000, 'HelloWorld']:
- with self.assertRaises(ValueError, msg="The component was created but the given uid (%s) whas invalid (allready used, negative or WTF)" % bad_uid):
- self.ed_mod.create_component('EmClass', test_datas, uid=bad_uid)
-
- #Invalid component_type
- for bad_comp_name in ['EmComponent', 'EmFoobar', 'int', int]:
- with self.assertRaises(ValueError, msg="The create_component don't raise when an invalid classname (%s) is given as parameter" % bad_comp_name):
- self.ed_mod.create_component(bad_comp_name, test_datas)
-
- #Invalid rank
- for invalid_rank in [-1, 10000]:
- with self.assertRaises(ValueError, msg="A invalid rank (%s) was given" % invalid_rank):
- foodat = test_datas.copy()
- foodat['rank'] = invalid_rank
- self.ed_mod.create_component('EmClass', foodat)
- with self.assertRaises(TypeError, msg="A non integer rank was given"):
- foodat = test_datas.copy()
- foodat['rank'] = 'hello world'
- self.ed_mod.create_component('EmClass', foodat)
-
- #Invalid datas
- for invalid_datas in [dict(), [1, 2, 3, 4], ('hello', 'world')]:
- with self.assertRaises(TypeError, msg="Invalid datas was given in parameters"):
- self.ed_mod.create_component('EmClass', invalid_datas)
-
- def test_create_components(self):
- """ Test the create_component method mocking the EmComponent constructors """
-
- params = {
- 'EmClass': {
- 'cls': EmClass,
- 'cdats': {
- 'name': 'FooClass',
- 'classtype': 'entity',
- }
- },
- 'EmType': {
- 'cls': EmType,
- 'cdats': {
- 'name': 'FooType',
- 'class_id': self.ed_mod.components(EmClass)[0].uid,
- 'fields_list': [],
- }
- },
- 'EmField': {
- 'cls': EmField,
- 'cdats': {
- 'name': 'FooField',
- 'class_id': self.ed_mod.components(EmClass)[0].uid,
- 'fieldtype': 'char',
- 'max_length': 64,
- 'optional': True,
- 'internal': False,
- 'rel_field_id': None,
- 'icon': '0',
- 'nullable': False,
- 'uniq': True,
- }
- }
- }
-
- for cnt in params:
- tmpuid = self.ed_mod.new_uid()
- cdats = params[cnt]['cdats']
- cdats['string'] = MlString()
- cdats['help_text'] = MlString()
- with patch.object(params[cnt]['cls'], '__init__', return_value=None) as initmock:
- try:
- self.ed_mod.create_component(cnt, params[cnt]['cdats'])
- except AttributeError: # Raises because the component is a MagicMock
- pass
- cdats['uid'] = tmpuid
- cdats['model'] = self.ed_mod
- #Check that the component __init__ method was called with the good arguments
- initmock.assert_called_once_with(**cdats)
-
- def test_delete_component(self):
- """ Test the delete_component method """
-
- #Test that the delete_check() method is called
- for comp in self.ed_mod.components():
- with patch.object(comp.__class__, 'delete_check', return_value=False) as del_check_mock:
- ret = self.ed_mod.delete_component(comp.uid)
- del_check_mock.assert_called_once_with()
- #Check that when the delete_check() returns False de delete_component() too
- self.assertFalse(ret)
-
- #Using a new me for deletion test
- new_em = Model(EmBackendJson('EditorialModel/test/me.json'))
- for comp in new_em.components():
- cuid = comp.uid
- cname = new_em.name_from_emclass(comp.__class__)
- #Simulate that the delete_check() method returns True
- with patch.object(comp.__class__, 'delete_check', return_value=True) as del_check_mock:
- ret = new_em.delete_component(cuid)
- self.assertTrue(ret)
- self.assertNotIn(cuid, new_em._components['uids'])
- self.assertNotIn(comp, new_em._components[cname])
-
- def test_set_backend(self):
- """ Test the set_backend method """
-
- for backend in [EmBackendJson('EditorialModel/test/me.json'), EmBackendDummy()]:
- self.ed_mod.set_backend(backend)
- self.assertEqual(self.ed_mod.backend, backend)
-
- for bad_backend in [None, 'wow', int, EmBackendJson]:
- with self.assertRaises(TypeError, msg="But bad argument (%s %s) was given" % (type(bad_backend), bad_backend)):
- self.ed_mod.set_backend(bad_backend)
-
- def test_migrate_handler_order(self):
- """ Test that the migrate_handler() method create component in a good order """
- with patch.object(Model, 'create_component', return_value=None) as create_mock:
- try:
- self.ed_mod.migrate_handler(None)
- except AttributeError: # Raises because of the mock
- pass
- order_comp = ['EmClass', 'EmType', 'EmFieldGroup', 'EmField'] # Excpected creation order
- cur_comp = 0
- for mcall in create_mock.mock_calls:
- #Testing EmComponent order of creation
- while order_comp[cur_comp] != mcall[1][0]:
- cur_comp += 1
- if cur_comp >= len(order_comp):
- self.fail('The order of create_component() calls was not respected by migrate_handler() methods')
-
- #Testing uid
- comp = self.ed_mod.component(mcall[1][2])
- ctype = self.ed_mod.name_from_emclass(comp.__class__)
- self.assertEqual(mcall[1][0], ctype, "A component was created using a uid belonging to another component type")
- #Testing arguments of create_component
- comp_dump = comp.attr_dump()
- if 'fields_list' in comp_dump and comp_dump['fields_list']:
- del(comp_dump['fields_list'])
- if 'superiors_list' in comp_dump and comp_dump['superiors_list']:
- del(comp_dump['superiors_list'])
-
- self.assertEqual(mcall[1][1], comp_dump)
-
- def test_migrate_handler_relations(self):
- """ Test that the migrate_handler() method create Type relations correctly (selected fields and type hierarchy) """
- field_list_orig = []
- superiors_list_orig = dict()
- field_list_new = []
- superiors_list_new = dict()
-
- for emtype in self.ed_mod.components(EmType):
- for fluid in emtype.fields_list:
- field_list_orig.append(fluid)
- for nat, sup_l in emtype.superiors().items():
- superiors_list_orig[nat] = [sup.uid for sup in sup_l]
-
- with patch.object(DummyMigrationHandler, 'register_change', return_value=None) as mh_mock:
- self.ed_mod.migrate_handler(DummyMigrationHandler())
- #Getting cloned EM instance
- new_me = mh_mock.mock_calls[-1][1][0]
- for emtype in new_me.components(EmType):
- for fluid in emtype.fields_list:
- field_list_new.append(fluid)
- for nat, sup_l in emtype.superiors().items():
- superiors_list_new[nat] = [sup.uid for sup in sup_l]
-
- for fluid in field_list_orig:
- self.assertIn(fluid, field_list_orig, "Missing selected field (%d) when migrate_handler() is run" % fluid)
- for fluid in field_list_new:
- self.assertIn(fluid, field_list_new, "A field (%d) is selected when migrate_handler() is run but shouldn't be" % fluid)
- for nat, sup_l in superiors_list_orig.items():
- for supuid in sup_l:
- self.assertIn(supuid, superiors_list_new[nat], "Missing superiors (%d) when migrate_handler() is run" % supuid)
- for nat, sup_l in superiors_list_new.items():
- for supuid in sup_l:
- self.assertIn(supuid, superiors_list_orig[nat], "A superior (%d) is present when migrate_handler is called but shouldn't be" % supuid)
-
- def test_migrate_handler_hashes(self):
- """ Testing that the migrate_handler() method create an EM with the same hash as the original EM """
- with patch.object(DummyMigrationHandler, 'register_change', return_value=None) as mh_mock:
- self.ed_mod.migrate_handler(DummyMigrationHandler())
- #Getting the cloned EM instance
- last_call = mh_mock.mock_calls[-1]
- self.assertEqual(hash(last_call[1][0]), hash(self.ed_mod))
-
- def test_hash(self):
- """ Test that __hash__ and __eq__ work properly on models """
- me1 = Model(EmBackendJson('EditorialModel/test/me.json'))
- me2 = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DummyMigrationHandler())
-
- self.assertEqual(hash(me1), hash(me2), "When instanciate from the same backend & file but with another migration handler the hashes differs")
- self.assertTrue(me1.__eq__(me2))
-
- cl_l = me1.classes()
- cl_l[0].modify_rank(1)
-
- self.assertNotEqual(hash(me1), hash(me2), "After a class rank modification the hashes are the same")
- self.assertFalse(me1.__eq__(me2))
-
- cl_l = me2.classes()
- cl_l[0].modify_rank(1)
-
- self.assertEqual(hash(me1), hash(me2), "After doing sames modifications in the two models the hashes differs")
- self.assertTrue(me1.__eq__(me2))
-
- def test_compclass_getter(self):
- """ Test the Model methods that handles name <-> EmComponent conversion """
- for classname in ['EmField', 'EmClass', 'EmType']:
- cls = Model.emclass_from_name(classname)
- self.assertNotEqual(cls, False, "emclass_from_name return False when '%s' given as parameter" % classname)
- self.assertEqual(cls.__name__, classname)
-
- for classname in ['EmComponent', 'EmFoobar', int, EmClass]:
- self.assertFalse(Model.emclass_from_name(classname))
-
- for comp_cls in [EmClass, EmField, EmType]:
- self.assertEqual(Model.name_from_emclass(comp_cls), comp_cls.__name__)
- for comp in self.ed_mod.components(EmField):
- self.assertEqual(Model.name_from_emclass(comp.__class__), 'EmField')
-
- for cls in [EmComponent, int, str]:
- self.assertFalse(Model.name_from_emclass(cls))
|