| OLD | NEW |
| (Empty) |
| 1 | |
| 2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. | |
| 3 # See LICENSE for details. | |
| 4 | |
| 5 | |
| 6 from twisted.trial import unittest | |
| 7 from twisted.python import usage | |
| 8 | |
| 9 | |
| 10 class WellBehaved(usage.Options): | |
| 11 optParameters = [['long', 'w', 'default', 'and a docstring'], | |
| 12 ['another', 'n', 'no docstring'], | |
| 13 ['longonly', None, 'noshort'], | |
| 14 ['shortless', None, 'except', | |
| 15 'this one got docstring'], | |
| 16 ] | |
| 17 optFlags = [['aflag', 'f', | |
| 18 """ | |
| 19 | |
| 20 flagallicious docstringness for this here | |
| 21 | |
| 22 """], | |
| 23 ['flout', 'o'], | |
| 24 ] | |
| 25 | |
| 26 def opt_myflag(self): | |
| 27 self.opts['myflag'] = "PONY!" | |
| 28 | |
| 29 def opt_myparam(self, value): | |
| 30 self.opts['myparam'] = "%s WITH A PONY!" % (value,) | |
| 31 | |
| 32 | |
| 33 class ParseCorrectnessTest(unittest.TestCase): | |
| 34 """ | |
| 35 Test Options.parseArgs for correct values under good conditions. | |
| 36 """ | |
| 37 def setUp(self): | |
| 38 """ | |
| 39 Instantiate and parseOptions a well-behaved Options class. | |
| 40 """ | |
| 41 | |
| 42 self.niceArgV = ("--long Alpha -n Beta " | |
| 43 "--shortless Gamma -f --myflag " | |
| 44 "--myparam Tofu").split() | |
| 45 | |
| 46 self.nice = WellBehaved() | |
| 47 | |
| 48 self.nice.parseOptions(self.niceArgV) | |
| 49 | |
| 50 def test_checkParameters(self): | |
| 51 """ | |
| 52 Checking that parameters have correct values. | |
| 53 """ | |
| 54 self.failUnlessEqual(self.nice.opts['long'], "Alpha") | |
| 55 self.failUnlessEqual(self.nice.opts['another'], "Beta") | |
| 56 self.failUnlessEqual(self.nice.opts['longonly'], "noshort") | |
| 57 self.failUnlessEqual(self.nice.opts['shortless'], "Gamma") | |
| 58 | |
| 59 def test_checkFlags(self): | |
| 60 """ | |
| 61 Checking that flags have correct values. | |
| 62 """ | |
| 63 self.failUnlessEqual(self.nice.opts['aflag'], 1) | |
| 64 self.failUnlessEqual(self.nice.opts['flout'], 0) | |
| 65 | |
| 66 def test_checkCustoms(self): | |
| 67 """ | |
| 68 Checking that custom flags and parameters have correct values. | |
| 69 """ | |
| 70 self.failUnlessEqual(self.nice.opts['myflag'], "PONY!") | |
| 71 self.failUnlessEqual(self.nice.opts['myparam'], "Tofu WITH A PONY!") | |
| 72 | |
| 73 | |
| 74 class TypedOptions(usage.Options): | |
| 75 optParameters = [ | |
| 76 ['fooint', None, 392, 'Foo int', int], | |
| 77 ['foofloat', None, 4.23, 'Foo float', float], | |
| 78 ['eggint', None, None, 'Egg int without default', int], | |
| 79 ['eggfloat', None, None, 'Egg float without default', float], | |
| 80 ] | |
| 81 | |
| 82 | |
| 83 class TypedTestCase(unittest.TestCase): | |
| 84 """ | |
| 85 Test Options.parseArgs for options with forced types. | |
| 86 """ | |
| 87 def setUp(self): | |
| 88 self.usage = TypedOptions() | |
| 89 | |
| 90 def test_defaultValues(self): | |
| 91 """ | |
| 92 Test parsing of default values. | |
| 93 """ | |
| 94 argV = [] | |
| 95 self.usage.parseOptions(argV) | |
| 96 self.failUnlessEqual(self.usage.opts['fooint'], 392) | |
| 97 self.assert_(isinstance(self.usage.opts['fooint'], int)) | |
| 98 self.failUnlessEqual(self.usage.opts['foofloat'], 4.23) | |
| 99 self.assert_(isinstance(self.usage.opts['foofloat'], float)) | |
| 100 self.failUnlessEqual(self.usage.opts['eggint'], None) | |
| 101 self.failUnlessEqual(self.usage.opts['eggfloat'], None) | |
| 102 | |
| 103 def test_parsingValues(self): | |
| 104 """ | |
| 105 Test basic parsing of int and float values. | |
| 106 """ | |
| 107 argV = ("--fooint 912 --foofloat -823.1 " | |
| 108 "--eggint 32 --eggfloat 21").split() | |
| 109 self.usage.parseOptions(argV) | |
| 110 self.failUnlessEqual(self.usage.opts['fooint'], 912) | |
| 111 self.assert_(isinstance(self.usage.opts['fooint'], int)) | |
| 112 self.failUnlessEqual(self.usage.opts['foofloat'], -823.1) | |
| 113 self.assert_(isinstance(self.usage.opts['foofloat'], float)) | |
| 114 self.failUnlessEqual(self.usage.opts['eggint'], 32) | |
| 115 self.assert_(isinstance(self.usage.opts['eggint'], int)) | |
| 116 self.failUnlessEqual(self.usage.opts['eggfloat'], 21.) | |
| 117 self.assert_(isinstance(self.usage.opts['eggfloat'], float)) | |
| 118 | |
| 119 def test_invalidValues(self): | |
| 120 """ | |
| 121 Check that passing wrong values raises an error. | |
| 122 """ | |
| 123 argV = "--fooint egg".split() | |
| 124 self.assertRaises(usage.UsageError, self.usage.parseOptions, argV) | |
| 125 | |
| 126 | |
| 127 class WrongTypedOptions(usage.Options): | |
| 128 optParameters = [ | |
| 129 ['barwrong', None, None, 'Bar with wrong coerce', 'he'] | |
| 130 ] | |
| 131 | |
| 132 | |
| 133 class WeirdCallableOptions(usage.Options): | |
| 134 def _bar(value): | |
| 135 raise RuntimeError("Ouch") | |
| 136 def _foo(value): | |
| 137 raise ValueError("Yay") | |
| 138 optParameters = [ | |
| 139 ['barwrong', None, None, 'Bar with strange callable', _bar], | |
| 140 ['foowrong', None, None, 'Foo with strange callable', _foo] | |
| 141 ] | |
| 142 | |
| 143 | |
| 144 class WrongTypedTestCase(unittest.TestCase): | |
| 145 """ | |
| 146 Test Options.parseArgs for wrong coerce options. | |
| 147 """ | |
| 148 def test_nonCallable(self): | |
| 149 """ | |
| 150 Check that using a non callable type fails. | |
| 151 """ | |
| 152 us = WrongTypedOptions() | |
| 153 argV = "--barwrong egg".split() | |
| 154 self.assertRaises(TypeError, us.parseOptions, argV) | |
| 155 | |
| 156 def test_notCalledInDefault(self): | |
| 157 """ | |
| 158 Test that the coerce functions are not called if no values are | |
| 159 provided. | |
| 160 """ | |
| 161 us = WeirdCallableOptions() | |
| 162 argV = [] | |
| 163 us.parseOptions(argV) | |
| 164 | |
| 165 def test_weirdCallable(self): | |
| 166 """ | |
| 167 Test what happens when coerce functions raise errors. | |
| 168 """ | |
| 169 us = WeirdCallableOptions() | |
| 170 argV = "--foowrong blah".split() | |
| 171 # ValueError is swallowed as UsageError | |
| 172 e = self.assertRaises(usage.UsageError, us.parseOptions, argV) | |
| 173 self.assertEquals(str(e), "Parameter type enforcement failed: Yay") | |
| 174 | |
| 175 us = WeirdCallableOptions() | |
| 176 argV = "--barwrong blah".split() | |
| 177 # RuntimeError is not swallowed | |
| 178 self.assertRaises(RuntimeError, us.parseOptions, argV) | |
| 179 | |
| 180 | |
| 181 class OutputTest(unittest.TestCase): | |
| 182 def test_uppercasing(self): | |
| 183 """ | |
| 184 Error output case adjustment does not mangle options | |
| 185 """ | |
| 186 opt = WellBehaved() | |
| 187 e = self.assertRaises(usage.UsageError, | |
| 188 opt.parseOptions, ['-Z']) | |
| 189 self.assertEquals(str(e), 'option -Z not recognized') | |
| 190 | |
| 191 | |
| 192 class InquisitionOptions(usage.Options): | |
| 193 optFlags = [ | |
| 194 ('expect', 'e'), | |
| 195 ] | |
| 196 optParameters = [ | |
| 197 ('torture-device', 't', | |
| 198 'comfy-chair', | |
| 199 'set preferred torture device'), | |
| 200 ] | |
| 201 | |
| 202 | |
| 203 class HolyQuestOptions(usage.Options): | |
| 204 optFlags = [('horseback', 'h', | |
| 205 'use a horse'), | |
| 206 ('for-grail', 'g'), | |
| 207 ] | |
| 208 | |
| 209 | |
| 210 class SubCommandOptions(usage.Options): | |
| 211 optFlags = [('europian-swallow', None, | |
| 212 'set default swallow type to Europian'), | |
| 213 ] | |
| 214 subCommands = [ | |
| 215 ('inquisition', 'inquest', InquisitionOptions, | |
| 216 'Perform an inquisition'), | |
| 217 ('holyquest', 'quest', HolyQuestOptions, | |
| 218 'Embark upon a holy quest'), | |
| 219 ] | |
| 220 | |
| 221 | |
| 222 class SubCommandTest(unittest.TestCase): | |
| 223 | |
| 224 def test_simpleSubcommand(self): | |
| 225 o = SubCommandOptions() | |
| 226 o.parseOptions(['--europian-swallow', 'inquisition']) | |
| 227 self.failUnlessEqual(o['europian-swallow'], True) | |
| 228 self.failUnlessEqual(o.subCommand, 'inquisition') | |
| 229 self.failUnless(isinstance(o.subOptions, InquisitionOptions)) | |
| 230 self.failUnlessEqual(o.subOptions['expect'], False) | |
| 231 self.failUnlessEqual(o.subOptions['torture-device'], 'comfy-chair') | |
| 232 | |
| 233 def test_subcommandWithFlagsAndOptions(self): | |
| 234 o = SubCommandOptions() | |
| 235 o.parseOptions(['inquisition', '--expect', '--torture-device=feather']) | |
| 236 self.failUnlessEqual(o['europian-swallow'], False) | |
| 237 self.failUnlessEqual(o.subCommand, 'inquisition') | |
| 238 self.failUnless(isinstance(o.subOptions, InquisitionOptions)) | |
| 239 self.failUnlessEqual(o.subOptions['expect'], True) | |
| 240 self.failUnlessEqual(o.subOptions['torture-device'], 'feather') | |
| 241 | |
| 242 def test_subcommandAliasWithFlagsAndOptions(self): | |
| 243 o = SubCommandOptions() | |
| 244 o.parseOptions(['inquest', '--expect', '--torture-device=feather']) | |
| 245 self.failUnlessEqual(o['europian-swallow'], False) | |
| 246 self.failUnlessEqual(o.subCommand, 'inquisition') | |
| 247 self.failUnless(isinstance(o.subOptions, InquisitionOptions)) | |
| 248 self.failUnlessEqual(o.subOptions['expect'], True) | |
| 249 self.failUnlessEqual(o.subOptions['torture-device'], 'feather') | |
| 250 | |
| 251 def test_anotherSubcommandWithFlagsAndOptions(self): | |
| 252 o = SubCommandOptions() | |
| 253 o.parseOptions(['holyquest', '--for-grail']) | |
| 254 self.failUnlessEqual(o['europian-swallow'], False) | |
| 255 self.failUnlessEqual(o.subCommand, 'holyquest') | |
| 256 self.failUnless(isinstance(o.subOptions, HolyQuestOptions)) | |
| 257 self.failUnlessEqual(o.subOptions['horseback'], False) | |
| 258 self.failUnlessEqual(o.subOptions['for-grail'], True) | |
| 259 | |
| 260 def test_noSubcommand(self): | |
| 261 o = SubCommandOptions() | |
| 262 o.parseOptions(['--europian-swallow']) | |
| 263 self.failUnlessEqual(o['europian-swallow'], True) | |
| 264 self.failUnlessEqual(o.subCommand, None) | |
| 265 self.failIf(hasattr(o, 'subOptions')) | |
| 266 | |
| 267 def test_defaultSubcommand(self): | |
| 268 o = SubCommandOptions() | |
| 269 o.defaultSubCommand = 'inquest' | |
| 270 o.parseOptions(['--europian-swallow']) | |
| 271 self.failUnlessEqual(o['europian-swallow'], True) | |
| 272 self.failUnlessEqual(o.subCommand, 'inquisition') | |
| 273 self.failUnless(isinstance(o.subOptions, InquisitionOptions)) | |
| 274 self.failUnlessEqual(o.subOptions['expect'], False) | |
| 275 self.failUnlessEqual(o.subOptions['torture-device'], 'comfy-chair') | |
| 276 | |
| 277 def test_subCommandParseOptionsHasParent(self): | |
| 278 class SubOpt(usage.Options): | |
| 279 def parseOptions(self, *a, **kw): | |
| 280 self.sawParent = self.parent | |
| 281 usage.Options.parseOptions(self, *a, **kw) | |
| 282 class Opt(usage.Options): | |
| 283 subCommands = [ | |
| 284 ('foo', 'f', SubOpt, 'bar'), | |
| 285 ] | |
| 286 o = Opt() | |
| 287 o.parseOptions(['foo']) | |
| 288 self.failUnless(hasattr(o.subOptions, 'sawParent')) | |
| 289 self.failUnlessEqual(o.subOptions.sawParent , o) | |
| 290 | |
| 291 def test_subCommandInTwoPlaces(self): | |
| 292 """ | |
| 293 The .parent pointer is correct even when the same Options class is | |
| 294 used twice. | |
| 295 """ | |
| 296 class SubOpt(usage.Options): | |
| 297 pass | |
| 298 class OptFoo(usage.Options): | |
| 299 subCommands = [ | |
| 300 ('foo', 'f', SubOpt, 'quux'), | |
| 301 ] | |
| 302 class OptBar(usage.Options): | |
| 303 subCommands = [ | |
| 304 ('bar', 'b', SubOpt, 'quux'), | |
| 305 ] | |
| 306 oFoo = OptFoo() | |
| 307 oFoo.parseOptions(['foo']) | |
| 308 oBar=OptBar() | |
| 309 oBar.parseOptions(['bar']) | |
| 310 self.failUnless(hasattr(oFoo.subOptions, 'parent')) | |
| 311 self.failUnless(hasattr(oBar.subOptions, 'parent')) | |
| 312 self.failUnlessIdentical(oFoo.subOptions.parent, oFoo) | |
| 313 self.failUnlessIdentical(oBar.subOptions.parent, oBar) | |
| 314 | |
| 315 | |
| 316 class HelpStringTest(unittest.TestCase): | |
| 317 def setUp(self): | |
| 318 """ | |
| 319 Instantiate a well-behaved Options class. | |
| 320 """ | |
| 321 | |
| 322 self.niceArgV = ("--long Alpha -n Beta " | |
| 323 "--shortless Gamma -f --myflag " | |
| 324 "--myparam Tofu").split() | |
| 325 | |
| 326 self.nice = WellBehaved() | |
| 327 | |
| 328 def test_noGoBoom(self): | |
| 329 """ | |
| 330 __str__ shouldn't go boom. | |
| 331 """ | |
| 332 try: | |
| 333 self.nice.__str__() | |
| 334 except Exception, e: | |
| 335 self.fail(e) | |
| 336 | |
| 337 def test_whitespaceStripFlagsAndParameters(self): | |
| 338 """ | |
| 339 Extra whitespace in flag and parameters docs is stripped. | |
| 340 """ | |
| 341 # We test this by making sure aflag and it's help string are on the | |
| 342 # same line. | |
| 343 lines = [s for s in str(self.nice).splitlines() if s.find("aflag")>=0] | |
| 344 self.failUnless(len(lines) > 0) | |
| 345 self.failUnless(lines[0].find("flagallicious") >= 0) | |
| 346 | |
| 347 | |
| 348 class PortCoerceTestCase(unittest.TestCase): | |
| 349 """ | |
| 350 Test the behavior of L{usage.portCoerce}. | |
| 351 """ | |
| 352 def test_validCoerce(self): | |
| 353 """ | |
| 354 Test the answers with valid input. | |
| 355 """ | |
| 356 self.assertEquals(0, usage.portCoerce("0")) | |
| 357 self.assertEquals(3210, usage.portCoerce("3210")) | |
| 358 self.assertEquals(65535, usage.portCoerce("65535")) | |
| 359 | |
| 360 def test_errorCoerce(self): | |
| 361 """ | |
| 362 Test error path. | |
| 363 """ | |
| 364 self.assertRaises(ValueError, usage.portCoerce, "") | |
| 365 self.assertRaises(ValueError, usage.portCoerce, "-21") | |
| 366 self.assertRaises(ValueError, usage.portCoerce, "212189") | |
| 367 self.assertRaises(ValueError, usage.portCoerce, "foo") | |
| 368 | |
| 369 | |
| 370 if __name__ == '__main__': | |
| 371 unittest.main() | |
| 372 | |
| OLD | NEW |