Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
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_usage.py 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.python.usage}, a command line option parsing library.
  5. """
  6. from twisted.python import usage
  7. from twisted.trial import unittest
  8. class WellBehaved(usage.Options):
  9. optParameters = [
  10. ["long", "w", "default", "and a docstring"],
  11. ["another", "n", "no docstring"],
  12. ["longonly", None, "noshort"],
  13. ["shortless", None, "except", "this one got docstring"],
  14. ]
  15. optFlags = [
  16. [
  17. "aflag",
  18. "f",
  19. """
  20. flagallicious docstringness for this here
  21. """,
  22. ],
  23. ["flout", "o"],
  24. ]
  25. def opt_myflag(self):
  26. self.opts["myflag"] = "PONY!"
  27. def opt_myparam(self, value):
  28. self.opts["myparam"] = f"{value} WITH A PONY!"
  29. class ParseCorrectnessTests(unittest.TestCase):
  30. """
  31. Test L{usage.Options.parseOptions} for correct values under
  32. good conditions.
  33. """
  34. def setUp(self):
  35. """
  36. Instantiate and parseOptions a well-behaved Options class.
  37. """
  38. self.niceArgV = (
  39. "--long Alpha -n Beta " "--shortless Gamma -f --myflag " "--myparam Tofu"
  40. ).split()
  41. self.nice = WellBehaved()
  42. self.nice.parseOptions(self.niceArgV)
  43. def test_checkParameters(self):
  44. """
  45. Parameters have correct values.
  46. """
  47. self.assertEqual(self.nice.opts["long"], "Alpha")
  48. self.assertEqual(self.nice.opts["another"], "Beta")
  49. self.assertEqual(self.nice.opts["longonly"], "noshort")
  50. self.assertEqual(self.nice.opts["shortless"], "Gamma")
  51. def test_checkFlags(self):
  52. """
  53. Flags have correct values.
  54. """
  55. self.assertEqual(self.nice.opts["aflag"], 1)
  56. self.assertEqual(self.nice.opts["flout"], 0)
  57. def test_checkCustoms(self):
  58. """
  59. Custom flags and parameters have correct values.
  60. """
  61. self.assertEqual(self.nice.opts["myflag"], "PONY!")
  62. self.assertEqual(self.nice.opts["myparam"], "Tofu WITH A PONY!")
  63. class TypedOptions(usage.Options):
  64. optParameters = [
  65. ["fooint", None, 392, "Foo int", int],
  66. ["foofloat", None, 4.23, "Foo float", float],
  67. ["eggint", None, None, "Egg int without default", int],
  68. ["eggfloat", None, None, "Egg float without default", float],
  69. ]
  70. def opt_under_score(self, value):
  71. """
  72. This option has an underscore in its name to exercise the _ to -
  73. translation.
  74. """
  75. self.underscoreValue = value
  76. opt_u = opt_under_score
  77. class TypedTests(unittest.TestCase):
  78. """
  79. Test L{usage.Options.parseOptions} for options with forced types.
  80. """
  81. def setUp(self):
  82. self.usage = TypedOptions()
  83. def test_defaultValues(self):
  84. """
  85. Default values are parsed.
  86. """
  87. argV = []
  88. self.usage.parseOptions(argV)
  89. self.assertEqual(self.usage.opts["fooint"], 392)
  90. self.assertIsInstance(self.usage.opts["fooint"], int)
  91. self.assertEqual(self.usage.opts["foofloat"], 4.23)
  92. self.assertIsInstance(self.usage.opts["foofloat"], float)
  93. self.assertIsNone(self.usage.opts["eggint"])
  94. self.assertIsNone(self.usage.opts["eggfloat"])
  95. def test_parsingValues(self):
  96. """
  97. int and float values are parsed.
  98. """
  99. argV = ("--fooint 912 --foofloat -823.1 " "--eggint 32 --eggfloat 21").split()
  100. self.usage.parseOptions(argV)
  101. self.assertEqual(self.usage.opts["fooint"], 912)
  102. self.assertIsInstance(self.usage.opts["fooint"], int)
  103. self.assertEqual(self.usage.opts["foofloat"], -823.1)
  104. self.assertIsInstance(self.usage.opts["foofloat"], float)
  105. self.assertEqual(self.usage.opts["eggint"], 32)
  106. self.assertIsInstance(self.usage.opts["eggint"], int)
  107. self.assertEqual(self.usage.opts["eggfloat"], 21.0)
  108. self.assertIsInstance(self.usage.opts["eggfloat"], float)
  109. def test_underscoreOption(self):
  110. """
  111. A dash in an option name is translated to an underscore before being
  112. dispatched to a handler.
  113. """
  114. self.usage.parseOptions(["--under-score", "foo"])
  115. self.assertEqual(self.usage.underscoreValue, "foo")
  116. def test_underscoreOptionAlias(self):
  117. """
  118. An option name with a dash in it can have an alias.
  119. """
  120. self.usage.parseOptions(["-u", "bar"])
  121. self.assertEqual(self.usage.underscoreValue, "bar")
  122. def test_invalidValues(self):
  123. """
  124. Passing wrong values raises an error.
  125. """
  126. argV = "--fooint egg".split()
  127. self.assertRaises(usage.UsageError, self.usage.parseOptions, argV)
  128. class WrongTypedOptions(usage.Options):
  129. optParameters = [["barwrong", None, None, "Bar with wrong coerce", "he"]]
  130. class WeirdCallableOptions(usage.Options):
  131. def _bar(value):
  132. raise RuntimeError("Ouch")
  133. def _foo(value):
  134. raise ValueError("Yay")
  135. optParameters = [
  136. ["barwrong", None, None, "Bar with strange callable", _bar],
  137. ["foowrong", None, None, "Foo with strange callable", _foo],
  138. ]
  139. class WrongTypedTests(unittest.TestCase):
  140. """
  141. Test L{usage.Options.parseOptions} for wrong coerce options.
  142. """
  143. def test_nonCallable(self):
  144. """
  145. Using a non-callable type fails.
  146. """
  147. us = WrongTypedOptions()
  148. argV = "--barwrong egg".split()
  149. self.assertRaises(TypeError, us.parseOptions, argV)
  150. def test_notCalledInDefault(self):
  151. """
  152. The coerce functions are not called if no values are provided.
  153. """
  154. us = WeirdCallableOptions()
  155. argV = []
  156. us.parseOptions(argV)
  157. def test_weirdCallable(self):
  158. """
  159. Errors raised by coerce functions are handled properly.
  160. """
  161. us = WeirdCallableOptions()
  162. argV = "--foowrong blah".split()
  163. # ValueError is swallowed as UsageError
  164. e = self.assertRaises(usage.UsageError, us.parseOptions, argV)
  165. self.assertEqual(str(e), "Parameter type enforcement failed: Yay")
  166. us = WeirdCallableOptions()
  167. argV = "--barwrong blah".split()
  168. # RuntimeError is not swallowed
  169. self.assertRaises(RuntimeError, us.parseOptions, argV)
  170. class OutputTests(unittest.TestCase):
  171. def test_uppercasing(self):
  172. """
  173. Error output case adjustment does not mangle options
  174. """
  175. opt = WellBehaved()
  176. e = self.assertRaises(usage.UsageError, opt.parseOptions, ["-Z"])
  177. self.assertEqual(str(e), "option -Z not recognized")
  178. class InquisitionOptions(usage.Options):
  179. optFlags = [
  180. ("expect", "e"),
  181. ]
  182. optParameters = [
  183. ("torture-device", "t", "comfy-chair", "set preferred torture device"),
  184. ]
  185. class HolyQuestOptions(usage.Options):
  186. optFlags = [
  187. ("horseback", "h", "use a horse"),
  188. ("for-grail", "g"),
  189. ]
  190. class SubCommandOptions(usage.Options):
  191. optFlags = [
  192. ("europian-swallow", None, "set default swallow type to Europian"),
  193. ]
  194. subCommands = [
  195. ("inquisition", "inquest", InquisitionOptions, "Perform an inquisition"),
  196. ("holyquest", "quest", HolyQuestOptions, "Embark upon a holy quest"),
  197. ]
  198. class SubCommandTests(unittest.TestCase):
  199. """
  200. Test L{usage.Options.parseOptions} for options with subcommands.
  201. """
  202. def test_simpleSubcommand(self):
  203. """
  204. A subcommand is recognized.
  205. """
  206. o = SubCommandOptions()
  207. o.parseOptions(["--europian-swallow", "inquisition"])
  208. self.assertTrue(o["europian-swallow"])
  209. self.assertEqual(o.subCommand, "inquisition")
  210. self.assertIsInstance(o.subOptions, InquisitionOptions)
  211. self.assertFalse(o.subOptions["expect"])
  212. self.assertEqual(o.subOptions["torture-device"], "comfy-chair")
  213. def test_subcommandWithFlagsAndOptions(self):
  214. """
  215. Flags and options of a subcommand are assigned.
  216. """
  217. o = SubCommandOptions()
  218. o.parseOptions(["inquisition", "--expect", "--torture-device=feather"])
  219. self.assertFalse(o["europian-swallow"])
  220. self.assertEqual(o.subCommand, "inquisition")
  221. self.assertIsInstance(o.subOptions, InquisitionOptions)
  222. self.assertTrue(o.subOptions["expect"])
  223. self.assertEqual(o.subOptions["torture-device"], "feather")
  224. def test_subcommandAliasWithFlagsAndOptions(self):
  225. """
  226. Flags and options of a subcommand alias are assigned.
  227. """
  228. o = SubCommandOptions()
  229. o.parseOptions(["inquest", "--expect", "--torture-device=feather"])
  230. self.assertFalse(o["europian-swallow"])
  231. self.assertEqual(o.subCommand, "inquisition")
  232. self.assertIsInstance(o.subOptions, InquisitionOptions)
  233. self.assertTrue(o.subOptions["expect"])
  234. self.assertEqual(o.subOptions["torture-device"], "feather")
  235. def test_anotherSubcommandWithFlagsAndOptions(self):
  236. """
  237. Flags and options of another subcommand are assigned.
  238. """
  239. o = SubCommandOptions()
  240. o.parseOptions(["holyquest", "--for-grail"])
  241. self.assertFalse(o["europian-swallow"])
  242. self.assertEqual(o.subCommand, "holyquest")
  243. self.assertIsInstance(o.subOptions, HolyQuestOptions)
  244. self.assertFalse(o.subOptions["horseback"])
  245. self.assertTrue(o.subOptions["for-grail"])
  246. def test_noSubcommand(self):
  247. """
  248. If no subcommand is specified and no default subcommand is assigned,
  249. a subcommand will not be implied.
  250. """
  251. o = SubCommandOptions()
  252. o.parseOptions(["--europian-swallow"])
  253. self.assertTrue(o["europian-swallow"])
  254. self.assertIsNone(o.subCommand)
  255. self.assertFalse(hasattr(o, "subOptions"))
  256. def test_defaultSubcommand(self):
  257. """
  258. Flags and options in the default subcommand are assigned.
  259. """
  260. o = SubCommandOptions()
  261. o.defaultSubCommand = "inquest"
  262. o.parseOptions(["--europian-swallow"])
  263. self.assertTrue(o["europian-swallow"])
  264. self.assertEqual(o.subCommand, "inquisition")
  265. self.assertIsInstance(o.subOptions, InquisitionOptions)
  266. self.assertFalse(o.subOptions["expect"])
  267. self.assertEqual(o.subOptions["torture-device"], "comfy-chair")
  268. def test_subCommandParseOptionsHasParent(self):
  269. """
  270. The parseOptions method from the Options object specified for the
  271. given subcommand is called.
  272. """
  273. class SubOpt(usage.Options):
  274. def parseOptions(self, *a, **kw):
  275. self.sawParent = self.parent
  276. usage.Options.parseOptions(self, *a, **kw)
  277. class Opt(usage.Options):
  278. subCommands = [
  279. ("foo", "f", SubOpt, "bar"),
  280. ]
  281. o = Opt()
  282. o.parseOptions(["foo"])
  283. self.assertTrue(hasattr(o.subOptions, "sawParent"))
  284. self.assertEqual(o.subOptions.sawParent, o)
  285. def test_subCommandInTwoPlaces(self):
  286. """
  287. The .parent pointer is correct even when the same Options class is
  288. used twice.
  289. """
  290. class SubOpt(usage.Options):
  291. pass
  292. class OptFoo(usage.Options):
  293. subCommands = [
  294. ("foo", "f", SubOpt, "quux"),
  295. ]
  296. class OptBar(usage.Options):
  297. subCommands = [
  298. ("bar", "b", SubOpt, "quux"),
  299. ]
  300. oFoo = OptFoo()
  301. oFoo.parseOptions(["foo"])
  302. oBar = OptBar()
  303. oBar.parseOptions(["bar"])
  304. self.assertTrue(hasattr(oFoo.subOptions, "parent"))
  305. self.assertTrue(hasattr(oBar.subOptions, "parent"))
  306. self.failUnlessIdentical(oFoo.subOptions.parent, oFoo)
  307. self.failUnlessIdentical(oBar.subOptions.parent, oBar)
  308. class HelpStringTests(unittest.TestCase):
  309. """
  310. Test generated help strings.
  311. """
  312. def setUp(self):
  313. """
  314. Instantiate a well-behaved Options class.
  315. """
  316. self.niceArgV = (
  317. "--long Alpha -n Beta " "--shortless Gamma -f --myflag " "--myparam Tofu"
  318. ).split()
  319. self.nice = WellBehaved()
  320. def test_noGoBoom(self):
  321. """
  322. __str__ shouldn't go boom.
  323. """
  324. try:
  325. self.nice.__str__()
  326. except Exception as e:
  327. self.fail(e)
  328. def test_whitespaceStripFlagsAndParameters(self):
  329. """
  330. Extra whitespace in flag and parameters docs is stripped.
  331. """
  332. # We test this by making sure aflag and it's help string are on the
  333. # same line.
  334. lines = [s for s in str(self.nice).splitlines() if s.find("aflag") >= 0]
  335. self.assertTrue(len(lines) > 0)
  336. self.assertTrue(lines[0].find("flagallicious") >= 0)
  337. class PortCoerceTests(unittest.TestCase):
  338. """
  339. Test the behavior of L{usage.portCoerce}.
  340. """
  341. def test_validCoerce(self):
  342. """
  343. Test the answers with valid input.
  344. """
  345. self.assertEqual(0, usage.portCoerce("0"))
  346. self.assertEqual(3210, usage.portCoerce("3210"))
  347. self.assertEqual(65535, usage.portCoerce("65535"))
  348. def test_errorCoerce(self):
  349. """
  350. Test error path.
  351. """
  352. self.assertRaises(ValueError, usage.portCoerce, "")
  353. self.assertRaises(ValueError, usage.portCoerce, "-21")
  354. self.assertRaises(ValueError, usage.portCoerce, "212189")
  355. self.assertRaises(ValueError, usage.portCoerce, "foo")
  356. class ZshCompleterTests(unittest.TestCase):
  357. """
  358. Test the behavior of the various L{twisted.usage.Completer} classes
  359. for producing output usable by zsh tab-completion system.
  360. """
  361. def test_completer(self):
  362. """
  363. Completer produces zsh shell-code that produces no completion matches.
  364. """
  365. c = usage.Completer()
  366. got = c._shellCode("some-option", usage._ZSH)
  367. self.assertEqual(got, ":some-option:")
  368. c = usage.Completer(descr="some action", repeat=True)
  369. got = c._shellCode("some-option", usage._ZSH)
  370. self.assertEqual(got, "*:some action:")
  371. def test_files(self):
  372. """
  373. CompleteFiles produces zsh shell-code that completes file names
  374. according to a glob.
  375. """
  376. c = usage.CompleteFiles()
  377. got = c._shellCode("some-option", usage._ZSH)
  378. self.assertEqual(got, ':some-option (*):_files -g "*"')
  379. c = usage.CompleteFiles("*.py")
  380. got = c._shellCode("some-option", usage._ZSH)
  381. self.assertEqual(got, ':some-option (*.py):_files -g "*.py"')
  382. c = usage.CompleteFiles("*.py", descr="some action", repeat=True)
  383. got = c._shellCode("some-option", usage._ZSH)
  384. self.assertEqual(got, '*:some action (*.py):_files -g "*.py"')
  385. def test_dirs(self):
  386. """
  387. CompleteDirs produces zsh shell-code that completes directory names.
  388. """
  389. c = usage.CompleteDirs()
  390. got = c._shellCode("some-option", usage._ZSH)
  391. self.assertEqual(got, ":some-option:_directories")
  392. c = usage.CompleteDirs(descr="some action", repeat=True)
  393. got = c._shellCode("some-option", usage._ZSH)
  394. self.assertEqual(got, "*:some action:_directories")
  395. def test_list(self):
  396. """
  397. CompleteList produces zsh shell-code that completes words from a fixed
  398. list of possibilities.
  399. """
  400. c = usage.CompleteList("ABC")
  401. got = c._shellCode("some-option", usage._ZSH)
  402. self.assertEqual(got, ":some-option:(A B C)")
  403. c = usage.CompleteList(["1", "2", "3"])
  404. got = c._shellCode("some-option", usage._ZSH)
  405. self.assertEqual(got, ":some-option:(1 2 3)")
  406. c = usage.CompleteList(["1", "2", "3"], descr="some action", repeat=True)
  407. got = c._shellCode("some-option", usage._ZSH)
  408. self.assertEqual(got, "*:some action:(1 2 3)")
  409. def test_multiList(self):
  410. """
  411. CompleteMultiList produces zsh shell-code that completes multiple
  412. comma-separated words from a fixed list of possibilities.
  413. """
  414. c = usage.CompleteMultiList("ABC")
  415. got = c._shellCode("some-option", usage._ZSH)
  416. self.assertEqual(got, ":some-option:_values -s , 'some-option' A B C")
  417. c = usage.CompleteMultiList(["1", "2", "3"])
  418. got = c._shellCode("some-option", usage._ZSH)
  419. self.assertEqual(got, ":some-option:_values -s , 'some-option' 1 2 3")
  420. c = usage.CompleteMultiList(["1", "2", "3"], descr="some action", repeat=True)
  421. got = c._shellCode("some-option", usage._ZSH)
  422. expected = "*:some action:_values -s , 'some action' 1 2 3"
  423. self.assertEqual(got, expected)
  424. def test_usernames(self):
  425. """
  426. CompleteUsernames produces zsh shell-code that completes system
  427. usernames.
  428. """
  429. c = usage.CompleteUsernames()
  430. out = c._shellCode("some-option", usage._ZSH)
  431. self.assertEqual(out, ":some-option:_users")
  432. c = usage.CompleteUsernames(descr="some action", repeat=True)
  433. out = c._shellCode("some-option", usage._ZSH)
  434. self.assertEqual(out, "*:some action:_users")
  435. def test_groups(self):
  436. """
  437. CompleteGroups produces zsh shell-code that completes system group
  438. names.
  439. """
  440. c = usage.CompleteGroups()
  441. out = c._shellCode("some-option", usage._ZSH)
  442. self.assertEqual(out, ":group:_groups")
  443. c = usage.CompleteGroups(descr="some action", repeat=True)
  444. out = c._shellCode("some-option", usage._ZSH)
  445. self.assertEqual(out, "*:some action:_groups")
  446. def test_hostnames(self):
  447. """
  448. CompleteHostnames produces zsh shell-code that completes hostnames.
  449. """
  450. c = usage.CompleteHostnames()
  451. out = c._shellCode("some-option", usage._ZSH)
  452. self.assertEqual(out, ":some-option:_hosts")
  453. c = usage.CompleteHostnames(descr="some action", repeat=True)
  454. out = c._shellCode("some-option", usage._ZSH)
  455. self.assertEqual(out, "*:some action:_hosts")
  456. def test_userAtHost(self):
  457. """
  458. CompleteUserAtHost produces zsh shell-code that completes hostnames or
  459. a word of the form <username>@<hostname>.
  460. """
  461. c = usage.CompleteUserAtHost()
  462. out = c._shellCode("some-option", usage._ZSH)
  463. self.assertTrue(out.startswith(":host | user@host:"))
  464. c = usage.CompleteUserAtHost(descr="some action", repeat=True)
  465. out = c._shellCode("some-option", usage._ZSH)
  466. self.assertTrue(out.startswith("*:some action:"))
  467. def test_netInterfaces(self):
  468. """
  469. CompleteNetInterfaces produces zsh shell-code that completes system
  470. network interface names.
  471. """
  472. c = usage.CompleteNetInterfaces()
  473. out = c._shellCode("some-option", usage._ZSH)
  474. self.assertEqual(out, ":some-option:_net_interfaces")
  475. c = usage.CompleteNetInterfaces(descr="some action", repeat=True)
  476. out = c._shellCode("some-option", usage._ZSH)
  477. self.assertEqual(out, "*:some action:_net_interfaces")
  478. class CompleterNotImplementedTests(unittest.TestCase):
  479. """
  480. Using an unknown shell constant with the various Completer() classes
  481. should raise NotImplementedError
  482. """
  483. def test_unknownShell(self):
  484. """
  485. Using an unknown shellType should raise NotImplementedError
  486. """
  487. classes = [
  488. usage.Completer,
  489. usage.CompleteFiles,
  490. usage.CompleteDirs,
  491. usage.CompleteList,
  492. usage.CompleteMultiList,
  493. usage.CompleteUsernames,
  494. usage.CompleteGroups,
  495. usage.CompleteHostnames,
  496. usage.CompleteUserAtHost,
  497. usage.CompleteNetInterfaces,
  498. ]
  499. for cls in classes:
  500. try:
  501. action = cls()
  502. except BaseException:
  503. action = cls(None)
  504. self.assertRaises(
  505. NotImplementedError, action._shellCode, None, "bad_shell_type"
  506. )
  507. class FlagFunctionTests(unittest.TestCase):
  508. """
  509. Tests for L{usage.flagFunction}.
  510. """
  511. class SomeClass:
  512. """
  513. Dummy class for L{usage.flagFunction} tests.
  514. """
  515. def oneArg(self, a):
  516. """
  517. A one argument method to be tested by L{usage.flagFunction}.
  518. @param a: a useless argument to satisfy the function's signature.
  519. """
  520. def noArg(self):
  521. """
  522. A no argument method to be tested by L{usage.flagFunction}.
  523. """
  524. def manyArgs(self, a, b, c):
  525. """
  526. A multiple arguments method to be tested by L{usage.flagFunction}.
  527. @param a: a useless argument to satisfy the function's signature.
  528. @param b: a useless argument to satisfy the function's signature.
  529. @param c: a useless argument to satisfy the function's signature.
  530. """
  531. def test_hasArg(self):
  532. """
  533. L{usage.flagFunction} returns C{False} if the method checked allows
  534. exactly one argument.
  535. """
  536. self.assertIs(False, usage.flagFunction(self.SomeClass().oneArg))
  537. def test_noArg(self):
  538. """
  539. L{usage.flagFunction} returns C{True} if the method checked allows
  540. exactly no argument.
  541. """
  542. self.assertIs(True, usage.flagFunction(self.SomeClass().noArg))
  543. def test_tooManyArguments(self):
  544. """
  545. L{usage.flagFunction} raises L{usage.UsageError} if the method checked
  546. allows more than one argument.
  547. """
  548. exc = self.assertRaises(
  549. usage.UsageError, usage.flagFunction, self.SomeClass().manyArgs
  550. )
  551. self.assertEqual("Invalid Option function for manyArgs", str(exc))
  552. def test_tooManyArgumentsAndSpecificErrorMessage(self):
  553. """
  554. L{usage.flagFunction} uses the given method name in the error message
  555. raised when the method allows too many arguments.
  556. """
  557. exc = self.assertRaises(
  558. usage.UsageError, usage.flagFunction, self.SomeClass().manyArgs, "flubuduf"
  559. )
  560. self.assertEqual("Invalid Option function for flubuduf", str(exc))
  561. class OptionsInternalTests(unittest.TestCase):
  562. """
  563. Tests internal behavior of C{usage.Options}.
  564. """
  565. def test_optionsAliasesOrder(self):
  566. """
  567. Options which are synonyms to another option are aliases towards the
  568. longest option name.
  569. """
  570. class Opts(usage.Options):
  571. def opt_very_very_long(self):
  572. """
  573. This is an option method with a very long name, that is going to
  574. be aliased.
  575. """
  576. opt_short = opt_very_very_long
  577. opt_s = opt_very_very_long
  578. opts = Opts()
  579. self.assertEqual(
  580. dict.fromkeys(["s", "short", "very-very-long"], "very-very-long"),
  581. {
  582. "s": opts.synonyms["s"],
  583. "short": opts.synonyms["short"],
  584. "very-very-long": opts.synonyms["very-very-long"],
  585. },
  586. )