controller_tests.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. """Tests for cement.core.controller."""
  2. from cement.core import exc, controller, handler
  3. from cement.utils import test
  4. class BogusController(controller.CementBaseController):
  5. class Meta:
  6. interface = controller.IController
  7. label = None
  8. class BogusController2(controller.CementBaseController):
  9. class Meta:
  10. interface = controller.IController
  11. label = 'bogus2'
  12. description = 'Bogus Base Controller2'
  13. config_defaults = {}
  14. arguments = ['bad']
  15. hide = False
  16. stacked_on = 'base'
  17. class BogusController3(controller.CementBaseController):
  18. class Meta:
  19. interface = controller.IController
  20. label = 'bogus3'
  21. description = 'Bogus Base Controller3'
  22. config_defaults = {}
  23. arguments = [(['--ok'], 'bad')]
  24. hide = False
  25. stacked_on = 'base'
  26. class BogusController4(controller.CementBaseController):
  27. class Meta:
  28. interface = controller.IController
  29. label = 'bogus4'
  30. description = 'Bogus Base Controller4'
  31. config_defaults = {}
  32. arguments = [('bad', dict())]
  33. hide = False
  34. stacked_on = 'base'
  35. class TestBaseController(controller.CementBaseController):
  36. class Meta:
  37. interface = controller.IController
  38. label = 'base'
  39. description = 'Test Base Controller'
  40. config_section = 'base'
  41. config_defaults = dict(test_base_default=1)
  42. arguments = []
  43. hide = False
  44. @controller.expose()
  45. def default(self):
  46. print('Default')
  47. @controller.expose(aliases=['mycmd'])
  48. def my_command(self):
  49. print('My Command')
  50. class TestBaseController2(controller.CementBaseController):
  51. class Meta:
  52. interface = controller.IController
  53. label = 'base'
  54. description = 'Test Base Controller2'
  55. config_defaults = {}
  56. arguments = []
  57. hide = False
  58. epilog = 'Test Epilog'
  59. usage = 'Test Usage'
  60. @controller.expose()
  61. def my_command(self):
  62. pass
  63. @controller.expose()
  64. def my_command(self):
  65. pass
  66. class TestStackedController(controller.CementBaseController):
  67. class Meta:
  68. interface = controller.IController
  69. label = 'test_stacked'
  70. description = 'Test Stacked Controller'
  71. config_section = 'base'
  72. config_defaults = dict(test_stacked_default=2)
  73. arguments = [
  74. (['--foo-stacked'], dict(action='store'))
  75. ]
  76. stacked_on = 'base'
  77. hide = False
  78. @controller.expose(aliases=['my-stckd-cmd'], help='my stacked command')
  79. def my_stacked_command(self):
  80. pass
  81. class DoubleStackedController(controller.CementBaseController):
  82. class Meta:
  83. interface = controller.IController
  84. label = 'double_stacked'
  85. description = 'Double Stacked Controller'
  86. config_defaults = None
  87. defaults = dict(foo='bar') # covers deprecated code
  88. arguments = []
  89. stacked_on = 'test_stacked'
  90. @controller.expose()
  91. def double_stacked_command(self):
  92. pass
  93. class TestSecondaryController(controller.CementBaseController):
  94. class Meta:
  95. interface = controller.IController
  96. label = 'test_secondary'
  97. description = 'Test Secondary Controller'
  98. config_defaults = dict(test_secondary_default=3)
  99. aliases = ['sec']
  100. arguments = [
  101. (['-f2', '--foo2'], dict(action='store'))
  102. ]
  103. @controller.expose()
  104. def my_secondary_command(self):
  105. pass
  106. class TestDuplicateController(controller.CementBaseController):
  107. class Meta:
  108. interface = controller.IController
  109. label = 'test_duplicate'
  110. description = 'Test Duplicate Controller'
  111. stacked_on = 'base'
  112. config_defaults = dict(
  113. foo='bar',
  114. )
  115. arguments = [
  116. (['-f2', '--foo2'], dict(action='store'))
  117. ]
  118. @controller.expose()
  119. def my_command(self):
  120. pass
  121. class TestDuplicate2Controller(controller.CementBaseController):
  122. class Meta:
  123. interface = controller.IController
  124. label = 'test_duplicate2'
  125. description = 'Test Duplicate2 Controller'
  126. stacked_on = 'base'
  127. config_defaults = dict(
  128. foo='bar',
  129. )
  130. arguments = [
  131. (['-f2', '--foo2'], dict(action='store'))
  132. ]
  133. @controller.expose(hide=True, aliases=['my_command'])
  134. def mycmd(self):
  135. pass
  136. class TestDuplicate3Controller(controller.CementBaseController):
  137. class Meta:
  138. interface = controller.IController
  139. label = 'test_duplicate3'
  140. description = 'Test Duplicate3 Controller'
  141. stacked_on = 'base'
  142. config_defaults = dict(
  143. foo='bar',
  144. )
  145. arguments = [
  146. (['-f2', '--foo2'], dict(action='store'))
  147. ]
  148. @controller.expose(hide=True, aliases=['mycmd'])
  149. def dup3(self):
  150. pass
  151. class SameNameController(controller.CementBaseController):
  152. class Meta:
  153. interface = controller.IController
  154. label = 'same_name'
  155. description = 'Same Name Controller'
  156. config_defaults = dict()
  157. arguments = []
  158. stacked_on = 'base'
  159. @controller.expose()
  160. def same_name(self):
  161. pass
  162. class SameNameAliasController(controller.CementBaseController):
  163. class Meta:
  164. interface = controller.IController
  165. label = 'same_name_alias'
  166. description = 'Same Name Alias Controller'
  167. config_defaults = dict()
  168. arguments = []
  169. stacked_on = 'base'
  170. @controller.expose(aliases=['test_secondary'])
  171. def test_command(self):
  172. pass
  173. class ControllerTestCase(test.CementTestCase):
  174. def setUp(self):
  175. self.app = self.make_app(
  176. argv=['my-command'],
  177. base_controller=TestBaseController
  178. )
  179. @test.raises(exc.InterfaceError)
  180. def test_invalid_controller(self):
  181. handler.register(BogusController)
  182. @test.raises(exc.InterfaceError)
  183. def test_invalid_arguments_tuple(self):
  184. handler.register(BogusController2)
  185. self.app.setup()
  186. self.app.run()
  187. @test.raises(exc.InterfaceError)
  188. def test_invalid_arguments_dict(self):
  189. handler.register(BogusController3)
  190. self.app.setup()
  191. self.app.run()
  192. @test.raises(exc.InterfaceError)
  193. def test_invalid_arguments_list(self):
  194. handler.register(BogusController4)
  195. self.app.setup()
  196. self.app.run()
  197. def test_base_controller(self):
  198. self.app.setup()
  199. self.app.run()
  200. def test_base_controller_by_name(self):
  201. self.app = self.make_app(
  202. argv=['my-command'],
  203. base_controller=None
  204. )
  205. handler.register(TestBaseController)
  206. self.app.setup()
  207. def test_stacked_controller(self):
  208. app = self.make_app(
  209. argv=['my-stacked-command',],
  210. base_controller=TestBaseController,
  211. )
  212. handler.register(TestStackedController)
  213. handler.register(DoubleStackedController)
  214. app.setup()
  215. app.run()
  216. def test_secondary_controller(self):
  217. app = self.make_app(
  218. argv=['test_secondary', 'my-secondary-command'],
  219. base_controller=TestBaseController,
  220. )
  221. handler.register(TestSecondaryController)
  222. app.setup()
  223. app.controller._setup(app)
  224. app.run()
  225. def test_controller_alias(self):
  226. app = self.make_app(
  227. argv=['sec', 'my-secondary-command'],
  228. base_controller=TestBaseController,
  229. )
  230. handler.register(TestSecondaryController)
  231. app.setup()
  232. app.controller._setup(app)
  233. app.run()
  234. self.eq(app.controller._meta.label, 'test_secondary')
  235. @test.raises(SystemExit)
  236. def test_bad_command(self):
  237. app = self.make_app(argv=['bogus-command'])
  238. app.setup()
  239. app.run()
  240. def test_default_command(self):
  241. app = self.make_app(argv=[], base_controller=TestBaseController)
  242. app.setup()
  243. app.run()
  244. def test_command_alias(self):
  245. app = self.make_app(argv=['mycmd'], base_controller=TestBaseController)
  246. app.setup()
  247. app.run()
  248. def test_stacked_command(self):
  249. app = self.make_app(
  250. argv=['my-command'],
  251. base_controller=TestBaseController
  252. )
  253. app.setup()
  254. app.run()
  255. @test.raises(exc.FrameworkError)
  256. def test_duplicate_command(self):
  257. handler.register(TestDuplicateController)
  258. self.app.setup()
  259. try:
  260. self.app.run()
  261. except exc.FrameworkError as e:
  262. self.ok(e.msg.find('duplicate'))
  263. raise
  264. @test.raises(exc.FrameworkError)
  265. def test_duplicate_hidden_command(self):
  266. handler.register(TestDuplicate2Controller)
  267. self.app.setup()
  268. try:
  269. self.app.run()
  270. except exc.FrameworkError:
  271. # FIX ME: Check the error message is right error
  272. raise
  273. @test.raises(SystemExit)
  274. def test_bad_command(self):
  275. self.app = self.make_app(
  276. argv=['bogus-command'],
  277. base_controller=TestBaseController
  278. )
  279. self.app.setup()
  280. try:
  281. self.app.run()
  282. except SystemExit:
  283. raise
  284. def test_bad_command2(self):
  285. self.app = self.make_app(
  286. argv=[],
  287. base_controller=TestBaseController
  288. )
  289. self.app.setup()
  290. self.app.controller.command = None
  291. try:
  292. self.app.run()
  293. except SystemExit:
  294. raise
  295. def test_controller_defaults(self):
  296. self.app = self.make_app(
  297. argv=['my-command'],
  298. base_controller=TestBaseController,
  299. )
  300. handler.register(TestStackedController)
  301. self.app.setup()
  302. self.app.run()
  303. self.eq(self.app.config.get('base', 'test_base_default'), 1)
  304. self.eq(self.app.config.get('base', 'test_stacked_default'), 2)
  305. @test.raises(exc.FrameworkError)
  306. def test_same_name_controller(self):
  307. handler.register(SameNameController)
  308. self.app.setup()
  309. @test.raises(exc.FrameworkError)
  310. def test_same_name_alias_controller(self):
  311. handler.register(TestSecondaryController)
  312. handler.register(SameNameAliasController)
  313. self.app.setup()
  314. self.app.run()
  315. @test.raises(exc.FrameworkError)
  316. def test_duplicate_alias(self):
  317. handler.register(TestSecondaryController)
  318. handler.register(TestDuplicate3Controller)
  319. self.app.setup()
  320. try:
  321. self.app.run()
  322. except exc.FrameworkError as e:
  323. self.ok(e.msg.find('collides'))
  324. raise
  325. def test_usage_text(self):
  326. self.app.setup()
  327. contr = TestBaseController2()
  328. contr._setup(self.app)
  329. self.eq(contr._usage_text, 'Test Usage')