/pyface/tasks/tests/test_action_manager_builder.py

https://github.com/pankajp/pyface · Python · 347 lines · 286 code · 32 blank · 29 comment · 9 complexity · 1e3dd41d331176474ae6d0c532e2031a MD5 · raw file

  1. # Standard library imports.
  2. import unittest
  3. # Enthought library imports.
  4. from pyface.action.api import Action, ActionItem, ActionManager, Group, \
  5. MenuManager, MenuBarManager
  6. from pyface.tasks.action.api import GroupSchema, MenuSchema, MenuBarSchema, \
  7. SchemaAddition
  8. from pyface.tasks.action.task_action_manager_builder import \
  9. TaskActionManagerBuilder
  10. from pyface.tasks.api import Task
  11. class ActionManagerBuilderTestCase(unittest.TestCase):
  12. #### 'TestCase' protocol ##################################################
  13. def setUp(self):
  14. """ Create some dummy actions to use while testing.
  15. """
  16. for i in xrange(1, 7):
  17. action_id = 'action%i' % i
  18. setattr(self, action_id, Action(id=action_id, name='Action %i'%i))
  19. #### 'ActionManagerBuilderTestCase' protocol ##############################
  20. def assertActionElementsEqual(self, first, second):
  21. """ Checks that two action managers are (logically) equivalent.
  22. """
  23. children1 = children2 = []
  24. self.assertEquals(type(first), type(second))
  25. self.assertEquals(first.id, second.id)
  26. if isinstance(first, ActionItem):
  27. self.assertEquals(first.action.name, second.action.name)
  28. elif isinstance(first, ActionManager):
  29. if not isinstance(first, MenuBarManager):
  30. self.assertEquals(first.name, second.name)
  31. children1, children2 = first.groups, second.groups
  32. elif isinstance(first, Group):
  33. self.assertEquals(first.separator, second.separator)
  34. children1, children2 = first.items, second.items
  35. self.assertEquals(len(children1), len(children2))
  36. for i in xrange(len(children1)):
  37. self.assertActionElementsEqual(children1[i], children2[i])
  38. #### Tests ################################################################
  39. def test_simple_menu_bar(self):
  40. """ Does constructing a simple menu with no additions work?
  41. """
  42. schema = MenuBarSchema(
  43. MenuSchema(self.action1, self.action2, id='File', name='&File'),
  44. MenuSchema(self.action3, self.action4, id='Edit', name='&Edit'))
  45. builder = TaskActionManagerBuilder(task=Task(menu_bar=schema))
  46. actual = builder.create_menu_bar_manager()
  47. desired = MenuBarManager(MenuManager(self.action1, self.action2,
  48. id='File', name='&File'),
  49. MenuManager(self.action3, self.action4,
  50. id='Edit', name='&Edit'),
  51. id='MenuBar')
  52. self.assertActionElementsEqual(actual, desired)
  53. #### Tests about schema additions #########################################
  54. def test_additions_menu_bar(self):
  55. """ Does constructing a menu with a few additions work?
  56. """
  57. schema = MenuBarSchema(
  58. MenuSchema(GroupSchema(self.action1, self.action2, id='FileGroup'),
  59. id='File'))
  60. extras = [ SchemaAddition(factory=lambda: self.action3,
  61. before='action1',
  62. path='MenuBar/File/FileGroup'),
  63. SchemaAddition(factory=lambda: self.action4,
  64. before='action1',
  65. path='MenuBar/File/FileGroup'),
  66. SchemaAddition(factory=lambda: self.action5,
  67. path='MenuBar/File/FileGroup')]
  68. builder = TaskActionManagerBuilder(task=Task(menu_bar=schema,
  69. extra_actions=extras))
  70. actual = builder.create_menu_bar_manager()
  71. desired = MenuBarManager(MenuManager(Group(self.action3, self.action4,
  72. self.action1, self.action2,
  73. self.action5,
  74. id='FileGroup'),
  75. id='File'),
  76. id='MenuBar')
  77. self.assertActionElementsEqual(actual, desired)
  78. def test_extra_menu(self):
  79. """ Test contributing a whole new menu to the menu bar. """
  80. # Initial menu.
  81. schema = MenuBarSchema(
  82. MenuSchema(GroupSchema(self.action1, id='FileGroup'),
  83. id='FileMenu')
  84. )
  85. # Contributed menu.
  86. extra_menu = MenuSchema(
  87. GroupSchema(self.action2, id='BarGroup'),
  88. id= 'DummyActionsMenu',
  89. )
  90. extra_actions = [
  91. SchemaAddition(path='MenuBar',
  92. factory=lambda : extra_menu,
  93. id='DummyActionsSMenu'),
  94. ]
  95. # Build the final menu.
  96. builder = TaskActionManagerBuilder(
  97. task=Task(menu_bar=schema, extra_actions=extra_actions)
  98. )
  99. actual = builder.create_menu_bar_manager()
  100. desired = MenuBarManager(
  101. MenuManager(Group(self.action1, id='FileGroup'),
  102. id='FileMenu'),
  103. MenuManager(Group(self.action2, id='BarGroup'),
  104. id='DummyActionsMenu'),
  105. id='MenuBar'
  106. )
  107. self.assertActionElementsEqual(actual, desired)
  108. #### Tests about merging schemas ##########################################
  109. def test_merging_redundant_items(self):
  110. """ Menus and groups with matching path are merged together. """
  111. # Initial menu.
  112. schema = MenuBarSchema(
  113. MenuSchema(GroupSchema(self.action1, id='FileGroup'),
  114. name='File menu number one', id='FileMenu')
  115. )
  116. # Contributed menus.
  117. extra_menu = MenuSchema(
  118. GroupSchema(self.action2, id='FileGroup'),
  119. name='File menu number two',
  120. id= 'FileMenu',
  121. )
  122. extra_actions = [
  123. SchemaAddition(path='MenuBar',
  124. factory=lambda : extra_menu,
  125. id='DummyActionsSMenu'),
  126. ]
  127. # Build the final menu.
  128. builder = TaskActionManagerBuilder(
  129. task=Task(menu_bar=schema, extra_actions=extra_actions)
  130. )
  131. actual = builder.create_menu_bar_manager()
  132. # Note that we expect the name of the menu to be inherited from
  133. # the menu in the menu bar schema that is defined first.
  134. desired = MenuBarManager(
  135. MenuManager(Group(self.action1, self.action2, id='FileGroup'),
  136. name='File menu number one', id='FileMenu'),
  137. id='MenuBar'
  138. )
  139. self.assertActionElementsEqual(actual, desired)
  140. def test_unwanted_merge(self):
  141. """ Test that we don't have automatic merges due to forgetting to set
  142. a schema ID. """
  143. # Initial menu.
  144. schema = MenuBarSchema(
  145. MenuSchema(GroupSchema(self.action1, id='FileGroup'),
  146. name='File 1')
  147. )
  148. # Contributed menus.
  149. extra_menu = MenuSchema(
  150. GroupSchema(self.action2, id='FileGroup'),
  151. name='File 2'
  152. )
  153. extra_actions = [
  154. SchemaAddition(path='MenuBar',
  155. factory=lambda : extra_menu,
  156. id='DummyActionsSMenu'),
  157. ]
  158. # Build the final menu.
  159. builder = TaskActionManagerBuilder(
  160. task=Task(menu_bar=schema, extra_actions=extra_actions)
  161. )
  162. actual = builder.create_menu_bar_manager()
  163. # Note that we expect the name of the menu to be inherited from
  164. # the menu in the menu bar schema that is defined first.
  165. desired = MenuBarManager(
  166. MenuManager(Group(self.action1, id='FileGroup'),
  167. name='File 1', id='MenuSchema_1'),
  168. MenuManager(Group(self.action2, id='FileGroup'),
  169. name='File 2', id='MenuSchema_2'),
  170. id='MenuBar'
  171. )
  172. self.assertActionElementsEqual(actual, desired)
  173. def test_merging_items_with_same_id_but_different_class(self):
  174. """ Schemas with the same path but different types (menus, groups)
  175. are not merged together.
  176. Having a group and a menu with the same path is of course bad practice,
  177. but we need a predictable outcome.
  178. """
  179. # Initial menu.
  180. schema = MenuBarSchema(
  181. MenuSchema(GroupSchema(self.action1, id='FileGroup'),
  182. id='FileSchema')
  183. )
  184. # Contributed menus.
  185. extra_group = GroupSchema(self.action2, id='FileSchema')
  186. extra_actions = [
  187. SchemaAddition(path='MenuBar',
  188. factory=(lambda : extra_group),
  189. id='DummyActionsSMenu'),
  190. ]
  191. # Build the final menu.
  192. builder = TaskActionManagerBuilder(
  193. task=Task(menu_bar=schema, extra_actions=extra_actions)
  194. )
  195. actual = builder.create_menu_bar_manager()
  196. desired = MenuBarManager(
  197. MenuManager(Group(self.action1, id='FileGroup'),
  198. id='FileSchema'),
  199. Group(self.action2, id='FileSchema'),
  200. id='MenuBar'
  201. )
  202. self.assertActionElementsEqual(actual, desired)
  203. def test_merging_redundant_items_that_are_not_schemas(self):
  204. """ Items that are not schemas cannot be merged, but we should
  205. not crash, either. """
  206. # Initial menu.
  207. schema = MenuBarSchema(
  208. # This menu is not a schema...
  209. MenuManager(Group(self.action1, id='FileGroup'),
  210. id='FileMenu')
  211. )
  212. # Contributed menus.
  213. extra_menu = MenuSchema(
  214. GroupSchema(self.action2, id='FileGroup'),
  215. id= 'FileMenu',
  216. )
  217. extra_actions = [
  218. SchemaAddition(path='MenuBar',
  219. factory=lambda : extra_menu,
  220. id='DummyActionsSMenu'),
  221. ]
  222. # Build the final menu.
  223. builder = TaskActionManagerBuilder(
  224. task=Task(menu_bar=schema, extra_actions=extra_actions)
  225. )
  226. actual = builder.create_menu_bar_manager()
  227. desired = MenuBarManager(
  228. MenuManager(Group(self.action1, id='FileGroup'),
  229. id='FileMenu'),
  230. MenuManager(Group(self.action2, id='FileGroup'),
  231. id='FileMenu'),
  232. id='MenuBar'
  233. )
  234. self.assertActionElementsEqual(actual, desired)
  235. #### Tests about ordering #################################################
  236. def test_absolute_ordering(self):
  237. """ Does specifying absolute_position work?
  238. """
  239. schema = MenuBarSchema(
  240. MenuSchema(GroupSchema(self.action1, self.action2, id='FileGroup'),
  241. id='File'))
  242. extras = [ SchemaAddition(factory=lambda: self.action3,
  243. absolute_position='last',
  244. path='MenuBar/File/FileGroup'),
  245. SchemaAddition(factory=lambda: self.action4,
  246. absolute_position='first',
  247. path='MenuBar/File/FileGroup'),
  248. SchemaAddition(factory=lambda: self.action5,
  249. absolute_position='first',
  250. path='MenuBar/File/FileGroup')]
  251. builder = TaskActionManagerBuilder(task=Task(menu_bar=schema,
  252. extra_actions=extras))
  253. actual = builder.create_menu_bar_manager()
  254. desired = MenuBarManager(MenuManager(Group(self.action4, self.action5,
  255. self.action1, self.action2,
  256. self.action3,
  257. id='FileGroup'),
  258. id='File'),
  259. id='MenuBar')
  260. self.assertActionElementsEqual(actual, desired)
  261. def test_absolute_and_before_after(self):
  262. """ Does specifying absolute_position along with before, after work?
  263. """
  264. schema = MenuBarSchema(
  265. MenuSchema(GroupSchema(self.action1, self.action2, id='FileGroup'),
  266. id='File'))
  267. extras = [ SchemaAddition(factory=lambda: self.action3,
  268. id='action3',
  269. after='action2',
  270. path='MenuBar/File/FileGroup'),
  271. SchemaAddition(factory=lambda: self.action4,
  272. after='action3',
  273. path='MenuBar/File/FileGroup'),
  274. SchemaAddition(factory=lambda: self.action5,
  275. id='action5',
  276. absolute_position='last',
  277. path='MenuBar/File/FileGroup'),
  278. SchemaAddition(factory=lambda: self.action6,
  279. absolute_position='last',
  280. before='action5',
  281. path='MenuBar/File/FileGroup')
  282. ]
  283. builder = TaskActionManagerBuilder(task=Task(menu_bar=schema,
  284. extra_actions=extras))
  285. actual = builder.create_menu_bar_manager()
  286. desired = MenuBarManager(MenuManager(Group(self.action1, self.action2,
  287. self.action3, self.action4,
  288. self.action6, self.action5,
  289. id='FileGroup'),
  290. id='File'),
  291. id='MenuBar')
  292. self.assertActionElementsEqual(actual, desired)
  293. if __name__ == '__main__':
  294. unittest.main()