No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_model.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #
  2. # This file is part of Lodel 2 (https://github.com/OpenEdition)
  3. #
  4. # Copyright (C) 2015-2017 Cléo UMS-3287
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as published
  8. # by the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import unittest
  20. import tests.loader_utils
  21. from lodel.editorial_model.model import EditorialModel
  22. from lodel.editorial_model.components import EmComponent, EmClass, EmField, EmGroup
  23. from lodel.utils.mlstring import MlString
  24. from lodel.editorial_model.exceptions import *
  25. class EditorialModelTestCase(unittest.TestCase):
  26. def test_d_hash(self):
  27. """ Test the deterministic hash method """
  28. model = EditorialModel("test model", description = "Test EM")
  29. cls1 = model.new_class('testclass1', display_name = 'Classe de test 1', help_text = 'super aide')
  30. c1f1 = cls1.new_field('c1testfield1', data_handler = 'varchar')
  31. c1f2 = cls1.new_field('c1testfield2', data_handler = 'varchar')
  32. cls2 = model.new_class('testclass2')
  33. c2f1 = cls2.new_field('c2testfield1', data_handler = 'varchar')
  34. c2f2 = cls2.new_field('c2testfield2', data_handler = 'varchar')
  35. grp1 = model.new_group('testgroup1')
  36. grp1.add_components((cls1, c1f1))
  37. grp2 = model.new_group('testgroup2')
  38. grp2.add_components((cls2, c1f2, c2f1, c2f2))
  39. grp2.add_dependency(grp1)
  40. e_hash = 0x250eab75e782e51bbf212f47c6159571
  41. self.assertEqual(model.d_hash(), e_hash)
  42. c2f1.uid = 'foobar'
  43. self.assertNotEqual(model.d_hash(), e_hash)
  44. c2f1.uid = 'c2testfield1'
  45. self.assertEqual(model.d_hash(), e_hash)
  46. def test_translator_from_name(self):
  47. """ Test the translator_from_name method """
  48. import lodel.editorial_model.translator.picklefile as expected
  49. translator = EditorialModel.translator_from_name('picklefile')
  50. self.assertEqual(translator, expected)
  51. def test_invalid_translator_from_name(self):
  52. """ Test the translator_from_name method when invalid names given as argument """
  53. import lodel.editorial_model.translator.picklefile
  54. invalid_names = [
  55. lodel.editorial_model.translator.picklefile,
  56. 'foobar',
  57. 42,
  58. ]
  59. for name in invalid_names:
  60. with self.assertRaises(NameError):
  61. EditorialModel.translator_from_name(name)
  62. class EmComponentTestCase(unittest.TestCase):
  63. def test_abstract_init(self):
  64. with self.assertRaises(NotImplementedError):
  65. EmComponent('test')
  66. class EmClassTestCase(unittest.TestCase):
  67. def test_init(self):
  68. cls = EmClass('testClass', 'test class', 'A test class')
  69. self.assertEqual(cls.uid, 'testClass')
  70. self.assertEqual(cls.display_name, MlString('test class'))
  71. self.assertEqual(cls.help_text, MlString('A test class'))
  72. def test_fields(self):
  73. """ Bad test on add field method (only check uid presence) """
  74. cls = EmClass('testClass', 'test_class', 'A test class')
  75. cls.new_field('name', data_handler = 'varchar')
  76. cls.new_field('string', data_handler = 'varchar')
  77. cls.new_field('lodel_id', data_handler = 'varchar')
  78. #Automatic field added
  79. fields = cls.fields()
  80. self.assertEqual(len(fields), 4)
  81. self.assertEqual(
  82. set([f.uid for f in fields]),
  83. set(['name', 'string', 'lodel_id', 'classname'])
  84. )
  85. def test_d_hash(self):
  86. """ Test the deterministic hash method """
  87. field = EmField('test field', 'varchar')
  88. e_hash = 0x23415e5cab5cabf29ab2d2db99998ba4
  89. self.assertEqual(field.d_hash(), e_hash)
  90. field.uid = 'test field.'
  91. self.assertNotEqual(field.d_hash(), e_hash)
  92. def test_field_override(self):
  93. """ Test EmClass field overriding in inheritance """
  94. cls1 = EmClass('testClass', 'test class')
  95. cls1.new_field('test', data_handler = 'varchar', max_length = 16, nullable=True)
  96. cls1.new_field('test2', data_handler = 'integer', nullable = True)
  97. cls2 = EmClass('testClass2', parents = cls1)
  98. cls2.new_field('test', data_handler = 'varchar', max_length = 16, nullable=False)
  99. cls2.new_field('test2', data_handler = 'integer', nullable = False)
  100. self.assertEqual(len(cls1.fields()), len(cls2.fields()))
  101. self.assertTrue(cls1.fields('test').data_handler_options['nullable'])
  102. self.assertFalse(cls2.fields('test').data_handler_options['nullable'])
  103. ## @todo add more test when data handlers implements compatibility checks
  104. def test_field_invalid_type_override(self):
  105. """ Testing invalid fields overriding (incompatible data_handler)"""
  106. cls1 = EmClass('testClass', 'test class')
  107. cls1.new_field('test', data_handler = 'varchar', max_length = 8)
  108. cls1.new_field('test2', data_handler = 'integer', nullable = True)
  109. cls2 = EmClass('testClass2', parents = cls1)
  110. with self.assertRaises(AttributeError):
  111. cls2.new_field('test', data_handler = 'integer')
  112. def test_field_invalid_options_overrid(self):
  113. """ Testing invalid fields overriding (incompatible data handler options) """
  114. cls1 = EmClass('testClass', 'test class')
  115. cls1.new_field('test', data_handler = 'varchar', max_length = 8)
  116. cls1.new_field('test2', data_handler = 'integer', nullable = True)
  117. cls2 = EmClass('testClass2', parents = cls1)
  118. with self.assertRaises(AttributeError):
  119. cls2.new_field('test', data_handler = 'varchar', max_length = 2)
  120. def test_parents_recc(self):
  121. """ Test the reccursive parents property """
  122. model = EditorialModel(
  123. "test_model",
  124. description = "Model for LeFactoryTestCase"
  125. )
  126. cls1 = model.new_class('testclass1')
  127. cls2 = model.new_class('testclass2')
  128. cls3 = model.new_class('testclass3', parents = [cls2])
  129. cls4 = model.new_class('testclass4', parents = [cls1, cls3])
  130. cls5 = model.new_class('testclass5', parents = [cls4])
  131. cls6 = model.new_class('testclass6')
  132. self.assertEqual(cls5.parents_recc, set((cls4, cls1, cls2, cls3)))
  133. self.assertEqual(cls1.parents_recc, set())
  134. self.assertEqual(cls4.parents_recc, set((cls1, cls2, cls3)))
  135. self.assertEqual(cls3.parents_recc, set((cls2,)))
  136. class EmGroupTestCase(unittest.TestCase):
  137. def test_init(self):
  138. """ Test EmGroup instanciation """
  139. grp = EmGroup('testgrp', display_name = "Test group", help_text="No Help")
  140. self.assertEqual(grp.uid, 'testgrp')
  141. self.assertEqual(grp.dependencies(), dict())
  142. self.assertEqual(grp.display_name, MlString("Test group"))
  143. self.assertEqual(grp.help_text, MlString("No Help"))
  144. grp2 = EmGroup('test')
  145. self.assertEqual(grp2.uid, 'test')
  146. self.assertEqual(grp2.display_name, None)
  147. self.assertEqual(grp2.help_text, None)
  148. grp3 = EmGroup('depends', depends = (grp, grp2))
  149. self.assertEqual(set(grp3.dependencies().values()), set((grp, grp2)))
  150. def test_add_comps(self):
  151. """ Test components adding in groups"""
  152. grp = EmGroup('grp')
  153. cpn1 = EmField('test1','integer')
  154. cpn2 = EmClass('testClass', 'test class')
  155. grp.add_components([cpn1,cpn2])
  156. s1=grp.components()
  157. s2=grp.components()
  158. s1.add(EmField('test2','varchar'))
  159. self.assertEqual(s2,set([cpn1,cpn2]));
  160. def test_deps(self):
  161. """ Test dependencies """
  162. grp1 = EmGroup('grp1')
  163. grp2 = EmGroup('grp2')
  164. grp3 = EmGroup('grp3')
  165. grp4 = EmGroup('grp4')
  166. grp2.add_dependency(grp1)
  167. grp3.add_dependency(grp2)
  168. grp4.add_dependency(grp2)
  169. grp4.add_dependency(grp1)
  170. self.assertEqual(set(grp1.dependencies().values()), set())
  171. self.assertEqual(set(grp2.dependencies().values()), set([grp1]))
  172. self.assertEqual(set(grp3.dependencies().values()), set([grp2]))
  173. self.assertEqual(set(grp4.dependencies().values()), set([grp2, grp1]))
  174. self.assertEqual(set(grp3.dependencies(True).values()), set([grp2, grp1]))
  175. self.assertEqual(set(grp4.dependencies(True).values()), set([grp2, grp1]))
  176. self.assertEqual(set(grp1.required_by.values()), set([grp2, grp4]))
  177. self.assertEqual(set(grp2.required_by.values()), set([grp3, grp4]))
  178. self.assertEqual(set(grp3.required_by.values()), set())
  179. self.assertEqual(set(grp4.required_by.values()), set())
  180. for grp in [grp1, grp2, grp3, grp4]:
  181. for uid, dep in grp.dependencies(recursive = True).items():
  182. self.assertEqual(uid, dep.uid)
  183. for uid, dep in grp.required_by.items():
  184. self.assertEqual(uid, dep.uid)
  185. def test_apps(self):
  186. """ Test applicants """
  187. grp1 = EmGroup('grp1')
  188. grp2 = EmGroup('grp2')
  189. grp3 = EmGroup('grp3')
  190. grp4 = EmGroup('grp4')
  191. grp2.add_applicant(grp1)
  192. grp3.add_applicant(grp2)
  193. grp4.add_applicant(grp2)
  194. grp4.add_applicant(grp1)
  195. self.assertEqual(set(grp1.applicants().values()), set())
  196. self.assertEqual(set(grp2.applicants().values()), set([grp1]))
  197. self.assertEqual(set(grp3.applicants().values()), set([grp2]))
  198. self.assertEqual(set(grp4.applicants().values()), set([grp2, grp1]))
  199. self.assertEqual(set(grp3.applicants(True).values()), set([grp2, grp1]))
  200. self.assertEqual(set(grp4.applicants(True).values()), set([grp2, grp1]))
  201. self.assertEqual(set(grp1.required_by.values()), set())
  202. self.assertEqual(set(grp2.required_by.values()), set([grp1]))
  203. self.assertEqual(set(grp3.required_by.values()), set([grp2]))
  204. self.assertEqual(set(grp4.required_by.values()), set([grp2,grp1]))
  205. for grp in [grp1, grp2, grp3, grp4]:
  206. for uid, dep in grp.applicants(recursive = True).items():
  207. self.assertEqual(uid, dep.uid)
  208. for uid, dep in grp.required_by.items():
  209. self.assertEqual(uid, dep.uid)
  210. def test_display_name(self):
  211. grp = EmGroup('grp',None,'Test affichage du nom')
  212. a = grp.get_display_name()
  213. b = a
  214. b = 'Test de copie du nom'
  215. self.assertEqual(a,'Test affichage du nom')
  216. grp1 = EmGroup('grp')
  217. c = grp1.get_display_name()
  218. self.assertEqual(c, None)
  219. with self.assertRaises(ValueError): grp.get_display_name('ita')
  220. def test_help_text(self):
  221. grp = EmGroup('grp',None,None,'Test affichage du nom')
  222. a = grp.get_help_text()
  223. b = a
  224. b = 'Test de copie du nom'
  225. self.assertEqual(a,'Test affichage du nom')
  226. grp1 = EmGroup('grp')
  227. c = grp1.get_help_text()
  228. self.assertEqual(c, None)
  229. with self.assertRaises(ValueError): grp.get_help_text('ita')
  230. def test_deps_complex(self):
  231. """ More complex dependencies handling test """
  232. grps = [ EmGroup('group%d' % i) for i in range(6) ]
  233. grps[5].add_dependency( (grps[1], grps[2], grps[4]) )
  234. grps[4].add_dependency( (grps[1], grps[3]) )
  235. grps[3].add_dependency( (grps[0],) )
  236. grps[1].add_dependency( (grps[2], grps[0]) )
  237. self.assertEqual(
  238. set(grps[5].dependencies(True).values()),
  239. set( grps[i] for i in range(5))
  240. )
  241. self.assertEqual(
  242. set(grps[4].dependencies(True).values()),
  243. set( grps[i] for i in range(4))
  244. )
  245. grps[2].add_dependency(grps[0])
  246. self.assertEqual(
  247. set(grps[5].dependencies(True).values()),
  248. set( grps[i] for i in range(5))
  249. )
  250. self.assertEqual(
  251. set(grps[4].dependencies(True).values()),
  252. set( grps[i] for i in range(4))
  253. )
  254. # Inserting circular deps
  255. with self.assertRaises(EditorialModelError):
  256. grps[0].add_dependency(grps[5])
  257. def test_circular_dep(self):
  258. """ Test circular dependencies detection """
  259. grps = [ EmGroup('group%d' % i) for i in range(10) ]
  260. for i in range(1,10):
  261. grps[i].add_dependency(grps[i-1])
  262. for i in range(1,10):
  263. for j in range(i+1,10):
  264. with self.assertRaises(EditorialModelError):
  265. grps[i].add_dependency(grps[j])
  266. def test_d_hash(self):
  267. """ Test the deterministic hash method """
  268. grp = EmGroup('testgrp', display_name = "Test group", help_text="No Help")
  269. e_hash = 0x74657374677270333130363537393137343730343438343139303233393838303936373730323936353536393032313839313536333632313037343435323138313735343936303237373532343436303639363137
  270. self.assertEqual(grp.d_hash(), e_hash)