2
# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
from twisted.trial import unittest
7
from twisted.python import usage
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'],
17
optFlags = [['aflag', 'f',
20
flagallicious docstringness for this here
27
self.opts['myflag'] = "PONY!"
29
def opt_myparam(self, value):
30
self.opts['myparam'] = "%s WITH A PONY!" % (value,)
33
class ParseCorrectnessTest(unittest.TestCase):
35
Test Options.parseArgs for correct values under good conditions.
39
Instantiate and parseOptions a well-behaved Options class.
42
self.niceArgV = ("--long Alpha -n Beta "
43
"--shortless Gamma -f --myflag "
44
"--myparam Tofu").split()
46
self.nice = WellBehaved()
48
self.nice.parseOptions(self.niceArgV)
50
def test_checkParameters(self):
52
Checking that parameters have correct values.
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")
59
def test_checkFlags(self):
61
Checking that flags have correct values.
63
self.failUnlessEqual(self.nice.opts['aflag'], 1)
64
self.failUnlessEqual(self.nice.opts['flout'], 0)
66
def test_checkCustoms(self):
68
Checking that custom flags and parameters have correct values.
70
self.failUnlessEqual(self.nice.opts['myflag'], "PONY!")
71
self.failUnlessEqual(self.nice.opts['myparam'], "Tofu WITH A PONY!")
74
class TypedOptions(usage.Options):
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],
83
class TypedTestCase(unittest.TestCase):
85
Test Options.parseArgs for options with forced types.
88
self.usage = TypedOptions()
90
def test_defaultValues(self):
92
Test parsing of default values.
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)
103
def test_parsingValues(self):
105
Test basic parsing of int and float values.
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))
119
def test_invalidValues(self):
121
Check that passing wrong values raises an error.
123
argV = "--fooint egg".split()
124
self.assertRaises(usage.UsageError, self.usage.parseOptions, argV)
127
class WrongTypedOptions(usage.Options):
129
['barwrong', None, None, 'Bar with wrong coerce', 'he']
133
class WeirdCallableOptions(usage.Options):
135
raise RuntimeError("Ouch")
137
raise ValueError("Yay")
139
['barwrong', None, None, 'Bar with strange callable', _bar],
140
['foowrong', None, None, 'Foo with strange callable', _foo]
144
class WrongTypedTestCase(unittest.TestCase):
146
Test Options.parseArgs for wrong coerce options.
148
def test_nonCallable(self):
150
Check that using a non callable type fails.
152
us = WrongTypedOptions()
153
argV = "--barwrong egg".split()
154
self.assertRaises(TypeError, us.parseOptions, argV)
156
def test_notCalledInDefault(self):
158
Test that the coerce functions are not called if no values are
161
us = WeirdCallableOptions()
163
us.parseOptions(argV)
165
def test_weirdCallable(self):
167
Test what happens when coerce functions raise errors.
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")
175
us = WeirdCallableOptions()
176
argV = "--barwrong blah".split()
177
# RuntimeError is not swallowed
178
self.assertRaises(RuntimeError, us.parseOptions, argV)
181
class OutputTest(unittest.TestCase):
182
def test_uppercasing(self):
184
Error output case adjustment does not mangle options
187
e = self.assertRaises(usage.UsageError,
188
opt.parseOptions, ['-Z'])
189
self.assertEquals(str(e), 'option -Z not recognized')
192
class InquisitionOptions(usage.Options):
197
('torture-device', 't',
199
'set preferred torture device'),
203
class HolyQuestOptions(usage.Options):
204
optFlags = [('horseback', 'h',
210
class SubCommandOptions(usage.Options):
211
optFlags = [('europian-swallow', None,
212
'set default swallow type to Europian'),
215
('inquisition', 'inquest', InquisitionOptions,
216
'Perform an inquisition'),
217
('holyquest', 'quest', HolyQuestOptions,
218
'Embark upon a holy quest'),
222
class SubCommandTest(unittest.TestCase):
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')
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')
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')
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)
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'))
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')
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):
284
('foo', 'f', SubOpt, 'bar'),
287
o.parseOptions(['foo'])
288
self.failUnless(hasattr(o.subOptions, 'sawParent'))
289
self.failUnlessEqual(o.subOptions.sawParent , o)
291
def test_subCommandInTwoPlaces(self):
293
The .parent pointer is correct even when the same Options class is
296
class SubOpt(usage.Options):
298
class OptFoo(usage.Options):
300
('foo', 'f', SubOpt, 'quux'),
302
class OptBar(usage.Options):
304
('bar', 'b', SubOpt, 'quux'),
307
oFoo.parseOptions(['foo'])
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)
316
class HelpStringTest(unittest.TestCase):
319
Instantiate a well-behaved Options class.
322
self.niceArgV = ("--long Alpha -n Beta "
323
"--shortless Gamma -f --myflag "
324
"--myparam Tofu").split()
326
self.nice = WellBehaved()
328
def test_noGoBoom(self):
330
__str__ shouldn't go boom.
337
def test_whitespaceStripFlagsAndParameters(self):
339
Extra whitespace in flag and parameters docs is stripped.
341
# We test this by making sure aflag and it's help string are on the
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)
348
class PortCoerceTestCase(unittest.TestCase):
350
Test the behavior of L{usage.portCoerce}.
352
def test_validCoerce(self):
354
Test the answers with valid input.
356
self.assertEquals(0, usage.portCoerce("0"))
357
self.assertEquals(3210, usage.portCoerce("3210"))
358
self.assertEquals(65535, usage.portCoerce("65535"))
360
def test_errorCoerce(self):
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")
370
if __name__ == '__main__':