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 |