OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 |
| 3 # Copyright (c) 2007, Google Inc. |
| 4 # All rights reserved. |
| 5 # |
| 6 # Redistribution and use in source and binary forms, with or without |
| 7 # modification, are permitted provided that the following conditions are |
| 8 # met: |
| 9 # |
| 10 # * Redistributions of source code must retain the above copyright |
| 11 # notice, this list of conditions and the following disclaimer. |
| 12 # * Redistributions in binary form must reproduce the above |
| 13 # copyright notice, this list of conditions and the following disclaimer |
| 14 # in the documentation and/or other materials provided with the |
| 15 # distribution. |
| 16 # * Neither the name of Google Inc. nor the names of its |
| 17 # contributors may be used to endorse or promote products derived from |
| 18 # this software without specific prior written permission. |
| 19 # |
| 20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 |
| 32 "Unittest for flags.py module" |
| 33 |
| 34 __pychecker__ = "no-local" # for unittest |
| 35 |
| 36 |
| 37 import sys |
| 38 import os |
| 39 import shutil |
| 40 import unittest |
| 41 |
| 42 # We use the name 'flags' internally in this test, for historical reasons. |
| 43 # Don't do this yourself! :-) Just do 'import gflags; FLAGS=gflags.FLAGS; etc' |
| 44 import gflags as flags |
| 45 FLAGS=flags.FLAGS |
| 46 |
| 47 def MultiLineEqual(expected_help, help): |
| 48 """Returns True if expected_help == help. Otherwise returns False |
| 49 and logs the difference in a human-readable way. |
| 50 """ |
| 51 if help == expected_help: |
| 52 return True |
| 53 |
| 54 print "Error: FLAGS.MainModuleHelp() didn't return the expected result." |
| 55 print "Got:" |
| 56 print help |
| 57 print "[End of got]" |
| 58 |
| 59 help_lines = help.split('\n') |
| 60 expected_help_lines = expected_help.split('\n') |
| 61 |
| 62 num_help_lines = len(help_lines) |
| 63 num_expected_help_lines = len(expected_help_lines) |
| 64 |
| 65 if num_help_lines != num_expected_help_lines: |
| 66 print "Number of help lines = %d, expected %d" % ( |
| 67 num_help_lines, num_expected_help_lines) |
| 68 |
| 69 num_to_match = min(num_help_lines, num_expected_help_lines) |
| 70 |
| 71 for i in range(num_to_match): |
| 72 if help_lines[i] != expected_help_lines[i]: |
| 73 print "One discrepancy: Got:" |
| 74 print help_lines[i] |
| 75 print "Expected:" |
| 76 print expected_help_lines[i] |
| 77 break |
| 78 else: |
| 79 # If we got here, found no discrepancy, print first new line. |
| 80 if num_help_lines > num_expected_help_lines: |
| 81 print "New help line:" |
| 82 print help_lines[num_expected_help_lines] |
| 83 elif num_expected_help_lines > num_help_lines: |
| 84 print "Missing expected help line:" |
| 85 print expected_help_lines[num_help_lines] |
| 86 else: |
| 87 print "Bug in this test -- discrepancy detected but not found." |
| 88 |
| 89 return False |
| 90 |
| 91 |
| 92 class FlagsUnitTest(unittest.TestCase): |
| 93 "Flags Unit Test" |
| 94 |
| 95 def test_flags(self): |
| 96 |
| 97 ############################################## |
| 98 # Test normal usage with no (expected) errors. |
| 99 |
| 100 # Define flags |
| 101 number_test_framework_flags = len(FLAGS.RegisteredFlags()) |
| 102 repeatHelp = "how many times to repeat (0-5)" |
| 103 flags.DEFINE_integer("repeat", 4, repeatHelp, |
| 104 lower_bound=0, short_name='r') |
| 105 flags.DEFINE_string("name", "Bob", "namehelp") |
| 106 flags.DEFINE_boolean("debug", 0, "debughelp") |
| 107 flags.DEFINE_boolean("q", 1, "quiet mode") |
| 108 flags.DEFINE_boolean("quack", 0, "superstring of 'q'") |
| 109 flags.DEFINE_boolean("noexec", 1, "boolean flag with no as prefix") |
| 110 flags.DEFINE_integer("x", 3, "how eXtreme to be") |
| 111 flags.DEFINE_integer("l", 0x7fffffff00000000L, "how long to be") |
| 112 flags.DEFINE_list('letters', 'a,b,c', "a list of letters") |
| 113 flags.DEFINE_enum("kwery", None, ['who', 'what', 'why', 'where', 'when'], |
| 114 "?") |
| 115 |
| 116 # Specify number of flags defined above. The short_name defined |
| 117 # for 'repeat' counts as an extra flag. |
| 118 number_defined_flags = 10 + 1 |
| 119 self.assertEqual(len(FLAGS.RegisteredFlags()), |
| 120 number_defined_flags + number_test_framework_flags) |
| 121 |
| 122 assert FLAGS.repeat == 4, "integer default values not set:" + FLAGS.repeat |
| 123 assert FLAGS.name == 'Bob', "default values not set:" + FLAGS.name |
| 124 assert FLAGS.debug == 0, "boolean default values not set:" + FLAGS.debug |
| 125 assert FLAGS.q == 1, "boolean default values not set:" + FLAGS.q |
| 126 assert FLAGS.x == 3, "integer default values not set:" + FLAGS.x |
| 127 assert FLAGS.l == 0x7fffffff00000000L, ("integer default values not set:" |
| 128 + FLAGS.l) |
| 129 assert FLAGS.letters == ['a', 'b', 'c'], "list default values not set:" \ |
| 130 + FLAGS.letters |
| 131 assert FLAGS.kwery is None, ("enum default None value not set:" |
| 132 + FLAGS.kwery) |
| 133 |
| 134 flag_values = FLAGS.FlagValuesDict() |
| 135 assert flag_values['repeat'] == 4 |
| 136 assert flag_values['name'] == 'Bob' |
| 137 assert flag_values['debug'] == 0 |
| 138 assert flag_values['r'] == 4 # short for of repeat |
| 139 assert flag_values['q'] == 1 |
| 140 assert flag_values['quack'] == 0 |
| 141 assert flag_values['x'] == 3 |
| 142 assert flag_values['l'] == 0x7fffffff00000000L |
| 143 assert flag_values['letters'] == ['a', 'b', 'c'] |
| 144 assert flag_values['kwery'] is None |
| 145 |
| 146 # Verify string form of defaults |
| 147 assert FLAGS['repeat'].default_as_str == "'4'" |
| 148 assert FLAGS['name'].default_as_str == "'Bob'" |
| 149 assert FLAGS['debug'].default_as_str == "'false'" |
| 150 assert FLAGS['q'].default_as_str == "'true'" |
| 151 assert FLAGS['quack'].default_as_str == "'false'" |
| 152 assert FLAGS['noexec'].default_as_str == "'true'" |
| 153 assert FLAGS['x'].default_as_str == "'3'" |
| 154 assert FLAGS['l'].default_as_str == "'9223372032559808512'" |
| 155 assert FLAGS['letters'].default_as_str == "'a,b,c'" |
| 156 |
| 157 # Verify that the iterator for flags yields all the keys |
| 158 keys = list(FLAGS) |
| 159 keys.sort() |
| 160 reg_flags = FLAGS.RegisteredFlags() |
| 161 reg_flags.sort() |
| 162 self.assertEqual(keys, reg_flags) |
| 163 |
| 164 # Parse flags |
| 165 # .. empty command line |
| 166 argv = ('./program',) |
| 167 argv = FLAGS(argv) |
| 168 assert len(argv) == 1, "wrong number of arguments pulled" |
| 169 assert argv[0]=='./program', "program name not preserved" |
| 170 |
| 171 # .. non-empty command line |
| 172 argv = ('./program', '--debug', '--name=Bob', '-q', '--x=8') |
| 173 argv = FLAGS(argv) |
| 174 assert len(argv) == 1, "wrong number of arguments pulled" |
| 175 assert argv[0]=='./program', "program name not preserved" |
| 176 assert FLAGS['debug'].present == 1 |
| 177 FLAGS['debug'].present = 0 # Reset |
| 178 assert FLAGS['name'].present == 1 |
| 179 FLAGS['name'].present = 0 # Reset |
| 180 assert FLAGS['q'].present == 1 |
| 181 FLAGS['q'].present = 0 # Reset |
| 182 assert FLAGS['x'].present == 1 |
| 183 FLAGS['x'].present = 0 # Reset |
| 184 |
| 185 # Flags list |
| 186 self.assertEqual(len(FLAGS.RegisteredFlags()), |
| 187 number_defined_flags + number_test_framework_flags) |
| 188 assert 'name' in FLAGS.RegisteredFlags() |
| 189 assert 'debug' in FLAGS.RegisteredFlags() |
| 190 assert 'repeat' in FLAGS.RegisteredFlags() |
| 191 assert 'r' in FLAGS.RegisteredFlags() |
| 192 assert 'q' in FLAGS.RegisteredFlags() |
| 193 assert 'quack' in FLAGS.RegisteredFlags() |
| 194 assert 'x' in FLAGS.RegisteredFlags() |
| 195 assert 'l' in FLAGS.RegisteredFlags() |
| 196 assert 'letters' in FLAGS.RegisteredFlags() |
| 197 |
| 198 # has_key |
| 199 assert FLAGS.has_key('name') |
| 200 assert not FLAGS.has_key('name2') |
| 201 assert 'name' in FLAGS |
| 202 assert 'name2' not in FLAGS |
| 203 |
| 204 # try deleting a flag |
| 205 del FLAGS.r |
| 206 self.assertEqual(len(FLAGS.RegisteredFlags()), |
| 207 number_defined_flags - 1 + number_test_framework_flags) |
| 208 assert not 'r' in FLAGS.RegisteredFlags() |
| 209 |
| 210 # .. command line with extra stuff |
| 211 argv = ('./program', '--debug', '--name=Bob', 'extra') |
| 212 argv = FLAGS(argv) |
| 213 assert len(argv) == 2, "wrong number of arguments pulled" |
| 214 assert argv[0]=='./program', "program name not preserved" |
| 215 assert argv[1]=='extra', "extra argument not preserved" |
| 216 assert FLAGS['debug'].present == 1 |
| 217 FLAGS['debug'].present = 0 # Reset |
| 218 assert FLAGS['name'].present == 1 |
| 219 FLAGS['name'].present = 0 # Reset |
| 220 |
| 221 # Test reset |
| 222 argv = ('./program', '--debug') |
| 223 argv = FLAGS(argv) |
| 224 assert len(argv) == 1, "wrong number of arguments pulled" |
| 225 assert argv[0] == './program', "program name not preserved" |
| 226 assert FLAGS['debug'].present == 1 |
| 227 assert FLAGS['debug'].value |
| 228 FLAGS.Reset() |
| 229 assert FLAGS['debug'].present == 0 |
| 230 assert not FLAGS['debug'].value |
| 231 |
| 232 # Test that reset restores default value when default value is None. |
| 233 argv = ('./program', '--kwery=who') |
| 234 argv = FLAGS(argv) |
| 235 assert len(argv) == 1, "wrong number of arguments pulled" |
| 236 assert argv[0] == './program', "program name not preserved" |
| 237 assert FLAGS['kwery'].present == 1 |
| 238 assert FLAGS['kwery'].value == 'who' |
| 239 FLAGS.Reset() |
| 240 assert FLAGS['kwery'].present == 0 |
| 241 assert FLAGS['kwery'].value == None |
| 242 |
| 243 # Test integer argument passing |
| 244 argv = ('./program', '--x', '0x12345') |
| 245 argv = FLAGS(argv) |
| 246 self.assertEquals(FLAGS.x, 0x12345) |
| 247 self.assertEquals(type(FLAGS.x), int) |
| 248 |
| 249 argv = ('./program', '--x', '0x1234567890ABCDEF1234567890ABCDEF') |
| 250 argv = FLAGS(argv) |
| 251 self.assertEquals(FLAGS.x, 0x1234567890ABCDEF1234567890ABCDEF) |
| 252 self.assertEquals(type(FLAGS.x), long) |
| 253 |
| 254 # Treat 0-prefixed parameters as base-10, not base-8 |
| 255 argv = ('./program', '--x', '012345') |
| 256 argv = FLAGS(argv) |
| 257 self.assertEquals(FLAGS.x, 12345) |
| 258 self.assertEquals(type(FLAGS.x), int) |
| 259 |
| 260 argv = ('./program', '--x', '0123459') |
| 261 argv = FLAGS(argv) |
| 262 self.assertEquals(FLAGS.x, 123459) |
| 263 self.assertEquals(type(FLAGS.x), int) |
| 264 |
| 265 argv = ('./program', '--x', '0x123efg') |
| 266 try: |
| 267 argv = FLAGS(argv) |
| 268 raise AssertionError("failed to detect invalid hex argument") |
| 269 except flags.IllegalFlagValue: |
| 270 pass |
| 271 |
| 272 argv = ('./program', '--x', '0X123efg') |
| 273 try: |
| 274 argv = FLAGS(argv) |
| 275 raise AssertionError("failed to detect invalid hex argument") |
| 276 except flags.IllegalFlagValue: |
| 277 pass |
| 278 |
| 279 # Test boolean argument parsing |
| 280 flags.DEFINE_boolean("test0", None, "test boolean parsing") |
| 281 argv = ('./program', '--notest0') |
| 282 argv = FLAGS(argv) |
| 283 assert FLAGS.test0 == 0 |
| 284 |
| 285 flags.DEFINE_boolean("test1", None, "test boolean parsing") |
| 286 argv = ('./program', '--test1') |
| 287 argv = FLAGS(argv) |
| 288 assert FLAGS.test1 == 1 |
| 289 |
| 290 FLAGS.test0 = None |
| 291 argv = ('./program', '--test0=false') |
| 292 argv = FLAGS(argv) |
| 293 assert FLAGS.test0 == 0 |
| 294 |
| 295 FLAGS.test1 = None |
| 296 argv = ('./program', '--test1=true') |
| 297 argv = FLAGS(argv) |
| 298 assert FLAGS.test1 == 1 |
| 299 |
| 300 FLAGS.test0 = None |
| 301 argv = ('./program', '--test0=0') |
| 302 argv = FLAGS(argv) |
| 303 assert FLAGS.test0 == 0 |
| 304 |
| 305 FLAGS.test1 = None |
| 306 argv = ('./program', '--test1=1') |
| 307 argv = FLAGS(argv) |
| 308 assert FLAGS.test1 == 1 |
| 309 |
| 310 # Test booleans that already have 'no' as a prefix |
| 311 FLAGS.noexec = None |
| 312 argv = ('./program', '--nonoexec', '--name', 'Bob') |
| 313 argv = FLAGS(argv) |
| 314 assert FLAGS.noexec == 0 |
| 315 |
| 316 FLAGS.noexec = None |
| 317 argv = ('./program', '--name', 'Bob', '--noexec') |
| 318 argv = FLAGS(argv) |
| 319 assert FLAGS.noexec == 1 |
| 320 |
| 321 # Test unassigned booleans |
| 322 flags.DEFINE_boolean("testnone", None, "test boolean parsing") |
| 323 argv = ('./program',) |
| 324 argv = FLAGS(argv) |
| 325 assert FLAGS.testnone == None |
| 326 |
| 327 # Test get with default |
| 328 flags.DEFINE_boolean("testget1", None, "test parsing with defaults") |
| 329 flags.DEFINE_boolean("testget2", None, "test parsing with defaults") |
| 330 flags.DEFINE_boolean("testget3", None, "test parsing with defaults") |
| 331 flags.DEFINE_integer("testget4", None, "test parsing with defaults") |
| 332 argv = ('./program','--testget1','--notestget2') |
| 333 argv = FLAGS(argv) |
| 334 assert FLAGS.get('testget1', 'foo') == 1 |
| 335 assert FLAGS.get('testget2', 'foo') == 0 |
| 336 assert FLAGS.get('testget3', 'foo') == 'foo' |
| 337 assert FLAGS.get('testget4', 'foo') == 'foo' |
| 338 |
| 339 # test list code |
| 340 lists = [['hello','moo','boo','1'], |
| 341 [],] |
| 342 |
| 343 flags.DEFINE_list('testlist', '', 'test lists parsing') |
| 344 flags.DEFINE_spaceseplist('testspacelist', '', 'tests space lists parsing') |
| 345 |
| 346 for name, sep in (('testlist', ','), ('testspacelist', ' '), |
| 347 ('testspacelist', '\n')): |
| 348 for lst in lists: |
| 349 argv = ('./program', '--%s=%s' % (name, sep.join(lst))) |
| 350 argv = FLAGS(argv) |
| 351 self.assertEquals(getattr(FLAGS, name), lst) |
| 352 |
| 353 # Test help text |
| 354 flagsHelp = str(FLAGS) |
| 355 assert flagsHelp.find("repeat") != -1, "cannot find flag in help" |
| 356 assert flagsHelp.find(repeatHelp) != -1, "cannot find help string in help" |
| 357 |
| 358 # Test flag specified twice |
| 359 argv = ('./program', '--repeat=4', '--repeat=2', '--debug', '--nodebug') |
| 360 argv = FLAGS(argv) |
| 361 self.assertEqual(FLAGS.get('repeat', None), 2) |
| 362 self.assertEqual(FLAGS.get('debug', None), 0) |
| 363 |
| 364 # Test MultiFlag with single default value |
| 365 flags.DEFINE_multistring('s_str', 'sing1', |
| 366 'string option that can occur multiple times', |
| 367 short_name='s') |
| 368 self.assertEqual(FLAGS.get('s_str', None), [ 'sing1', ]) |
| 369 |
| 370 # Test MultiFlag with list of default values |
| 371 multi_string_defs = [ 'def1', 'def2', ] |
| 372 flags.DEFINE_multistring('m_str', multi_string_defs, |
| 373 'string option that can occur multiple times', |
| 374 short_name='m') |
| 375 self.assertEqual(FLAGS.get('m_str', None), multi_string_defs) |
| 376 |
| 377 # Test flag specified multiple times with a MultiFlag |
| 378 argv = ('./program', '--m_str=str1', '-m', 'str2') |
| 379 argv = FLAGS(argv) |
| 380 self.assertEqual(FLAGS.get('m_str', None), [ 'str1', 'str2', ]) |
| 381 |
| 382 # Test single-letter flags; should support both single and double dash |
| 383 argv = ('./program', '-q', '-x8') |
| 384 argv = FLAGS(argv) |
| 385 self.assertEqual(FLAGS.get('q', None), 1) |
| 386 self.assertEqual(FLAGS.get('x', None), 8) |
| 387 |
| 388 argv = ('./program', '--q', '--x', '9', '--noqu') |
| 389 argv = FLAGS(argv) |
| 390 self.assertEqual(FLAGS.get('q', None), 1) |
| 391 self.assertEqual(FLAGS.get('x', None), 9) |
| 392 # --noqu should match '--noquack since it's a unique prefix |
| 393 self.assertEqual(FLAGS.get('quack', None), 0) |
| 394 |
| 395 argv = ('./program', '--noq', '--x=10', '--qu') |
| 396 argv = FLAGS(argv) |
| 397 self.assertEqual(FLAGS.get('q', None), 0) |
| 398 self.assertEqual(FLAGS.get('x', None), 10) |
| 399 self.assertEqual(FLAGS.get('quack', None), 1) |
| 400 |
| 401 #################################### |
| 402 # Test flag serialization code: |
| 403 |
| 404 oldtestlist = FLAGS.testlist |
| 405 oldtestspacelist = FLAGS.testspacelist |
| 406 |
| 407 argv = ('./program', |
| 408 FLAGS['test0'].Serialize(), |
| 409 FLAGS['test1'].Serialize(), |
| 410 FLAGS['testnone'].Serialize(), |
| 411 FLAGS['s_str'].Serialize()) |
| 412 argv = FLAGS(argv) |
| 413 self.assertEqual(FLAGS['test0'].Serialize(), '--notest0') |
| 414 self.assertEqual(FLAGS['test1'].Serialize(), '--test1') |
| 415 self.assertEqual(FLAGS['testnone'].Serialize(), '') |
| 416 self.assertEqual(FLAGS['s_str'].Serialize(), '--s_str=sing1') |
| 417 |
| 418 testlist1 = ['aa', 'bb'] |
| 419 testspacelist1 = ['aa', 'bb', 'cc'] |
| 420 FLAGS.testlist = list(testlist1) |
| 421 FLAGS.testspacelist = list(testspacelist1) |
| 422 argv = ('./program', |
| 423 FLAGS['testlist'].Serialize(), |
| 424 FLAGS['testspacelist'].Serialize()) |
| 425 argv = FLAGS(argv) |
| 426 self.assertEqual(FLAGS.testlist, testlist1) |
| 427 self.assertEqual(FLAGS.testspacelist, testspacelist1) |
| 428 |
| 429 testlist1 = ['aa some spaces', 'bb'] |
| 430 testspacelist1 = ['aa', 'bb,some,commas,', 'cc'] |
| 431 FLAGS.testlist = list(testlist1) |
| 432 FLAGS.testspacelist = list(testspacelist1) |
| 433 argv = ('./program', |
| 434 FLAGS['testlist'].Serialize(), |
| 435 FLAGS['testspacelist'].Serialize()) |
| 436 argv = FLAGS(argv) |
| 437 self.assertEqual(FLAGS.testlist, testlist1) |
| 438 self.assertEqual(FLAGS.testspacelist, testspacelist1) |
| 439 |
| 440 FLAGS.testlist = oldtestlist |
| 441 FLAGS.testspacelist = oldtestspacelist |
| 442 |
| 443 #################################### |
| 444 # Test flag-update: |
| 445 |
| 446 def ArgsString(): |
| 447 flagnames = FLAGS.RegisteredFlags() |
| 448 |
| 449 flagnames.sort() |
| 450 nonbool_flags = ['--%s %s' % (name, FLAGS.get(name, None)) |
| 451 for name in flagnames |
| 452 if not isinstance(FLAGS[name], flags.BooleanFlag)] |
| 453 |
| 454 truebool_flags = ['--%s' % (name) |
| 455 for name in flagnames |
| 456 if isinstance(FLAGS[name], flags.BooleanFlag) and |
| 457 FLAGS.get(name, None)] |
| 458 falsebool_flags = ['--no%s' % (name) |
| 459 for name in flagnames |
| 460 if isinstance(FLAGS[name], flags.BooleanFlag) and |
| 461 not FLAGS.get(name, None)] |
| 462 return ' '.join(nonbool_flags + truebool_flags + falsebool_flags) |
| 463 |
| 464 argv = ('./program', '--repeat=3', '--name=giants', '--nodebug') |
| 465 FLAGS(argv) |
| 466 self.assertEqual(FLAGS.get('repeat', None), 3) |
| 467 self.assertEqual(FLAGS.get('name', None), 'giants') |
| 468 self.assertEqual(FLAGS.get('debug', None), 0) |
| 469 self.assertEqual(ArgsString(), |
| 470 "--kwery None " |
| 471 "--l 9223372032559808512 " |
| 472 "--letters ['a', 'b', 'c'] " |
| 473 "--m ['str1', 'str2'] --m_str ['str1', 'str2'] " |
| 474 "--name giants " |
| 475 "--repeat 3 " |
| 476 "--s ['sing1'] --s_str ['sing1'] " |
| 477 "--testget4 None --testlist [] " |
| 478 "--testspacelist [] --x 10 " |
| 479 "--noexec --quack " |
| 480 "--test1 " |
| 481 "--testget1 --no? --nodebug --nohelp --nohelpshort " |
| 482 "--noq --notest0 --notestget2 " |
| 483 "--notestget3 --notestnone") |
| 484 |
| 485 argv = ('./program', '--debug', '--m_str=upd1', '-s', 'upd2') |
| 486 FLAGS(argv) |
| 487 self.assertEqual(FLAGS.get('repeat', None), 3) |
| 488 self.assertEqual(FLAGS.get('name', None), 'giants') |
| 489 self.assertEqual(FLAGS.get('debug', None), 1) |
| 490 |
| 491 # items appended to existing non-default value lists for --m/--m_str |
| 492 # new value overwrites default value (not appended to it) for --s/--s_str |
| 493 self.assertEqual(ArgsString(), |
| 494 "--kwery None " |
| 495 "--l 9223372032559808512 " |
| 496 "--letters ['a', 'b', 'c'] " |
| 497 "--m ['str1', 'str2', 'upd1'] " |
| 498 "--m_str ['str1', 'str2', 'upd1'] " |
| 499 "--name giants " |
| 500 "--repeat 3 " |
| 501 "--s ['upd2'] --s_str ['upd2'] " |
| 502 "--testget4 None --testlist [] " |
| 503 "--testspacelist [] --x 10 " |
| 504 "--debug --noexec --quack " |
| 505 "--test1 " |
| 506 "--testget1 --no? --nohelp --nohelpshort " |
| 507 "--noq --notest0 --notestget2 " |
| 508 "--notestget3 --notestnone") |
| 509 |
| 510 |
| 511 #################################### |
| 512 # Test all kind of error conditions. |
| 513 |
| 514 # Duplicate flag detection |
| 515 try: |
| 516 flags.DEFINE_boolean("run", 0, "runhelp", short_name='q') |
| 517 raise AssertionError("duplicate flag detection failed") |
| 518 except flags.DuplicateFlag, e: |
| 519 pass |
| 520 |
| 521 try: |
| 522 flags.DEFINE_boolean("zoom1", 0, "runhelp z1", short_name='z') |
| 523 flags.DEFINE_boolean("zoom2", 0, "runhelp z2", short_name='z') |
| 524 raise AssertionError("duplicate flag detection failed") |
| 525 except flags.DuplicateFlag, e: |
| 526 pass |
| 527 |
| 528 # Make sure allow_override works |
| 529 try: |
| 530 flags.DEFINE_boolean("dup1", 0, "runhelp d11", short_name='u', |
| 531 allow_override=0) |
| 532 flag = FLAGS.FlagDict()['dup1'] |
| 533 self.assertEqual(flag.default, 0) |
| 534 |
| 535 flags.DEFINE_boolean("dup1", 1, "runhelp d12", short_name='u', |
| 536 allow_override=1) |
| 537 flag = FLAGS.FlagDict()['dup1'] |
| 538 self.assertEqual(flag.default, 1) |
| 539 except flags.DuplicateFlag, e: |
| 540 raise AssertionError("allow_override did not permit a flag duplication") |
| 541 |
| 542 # Make sure allow_override works |
| 543 try: |
| 544 flags.DEFINE_boolean("dup2", 0, "runhelp d21", short_name='u', |
| 545 allow_override=1) |
| 546 flag = FLAGS.FlagDict()['dup2'] |
| 547 self.assertEqual(flag.default, 0) |
| 548 |
| 549 flags.DEFINE_boolean("dup2", 1, "runhelp d22", short_name='u', |
| 550 allow_override=0) |
| 551 flag = FLAGS.FlagDict()['dup2'] |
| 552 self.assertEqual(flag.default, 1) |
| 553 except flags.DuplicateFlag, e: |
| 554 raise AssertionError("allow_override did not permit a flag duplication") |
| 555 |
| 556 # Make sure allow_override doesn't work with None default |
| 557 try: |
| 558 flags.DEFINE_boolean("dup3", 0, "runhelp d31", short_name='u', |
| 559 allow_override=0) |
| 560 flag = FLAGS.FlagDict()['dup3'] |
| 561 self.assertEqual(flag.default, 0) |
| 562 |
| 563 flags.DEFINE_boolean("dup3", None, "runhelp d32", short_name='u', |
| 564 allow_override=1) |
| 565 raise AssertionError('Cannot override a flag with a default of None') |
| 566 except flags.DuplicateFlag, e: |
| 567 pass |
| 568 |
| 569 # Make sure that when we override, the help string gets updated correctly |
| 570 flags.DEFINE_boolean("dup3", 0, "runhelp d31", short_name='u', |
| 571 allow_override=1) |
| 572 flags.DEFINE_boolean("dup3", 1, "runhelp d32", short_name='u', |
| 573 allow_override=1) |
| 574 self.assert_(str(FLAGS).find('runhelp d31') == -1) |
| 575 self.assert_(str(FLAGS).find('runhelp d32') != -1) |
| 576 |
| 577 # Make sure AppendFlagValues works |
| 578 new_flags = flags.FlagValues() |
| 579 flags.DEFINE_boolean("new1", 0, "runhelp n1", flag_values=new_flags) |
| 580 flags.DEFINE_boolean("new2", 0, "runhelp n2", flag_values=new_flags) |
| 581 self.assertEqual(len(new_flags.FlagDict()), 2) |
| 582 old_len = len(FLAGS.FlagDict()) |
| 583 FLAGS.AppendFlagValues(new_flags) |
| 584 self.assertEqual(len(FLAGS.FlagDict())-old_len, 2) |
| 585 self.assertEqual("new1" in FLAGS.FlagDict(), True) |
| 586 self.assertEqual("new2" in FLAGS.FlagDict(), True) |
| 587 |
| 588 # Make sure AppendFlagValues works with flags with shortnames. |
| 589 new_flags = flags.FlagValues() |
| 590 flags.DEFINE_boolean("new3", 0, "runhelp n3", flag_values=new_flags) |
| 591 flags.DEFINE_boolean("new4", 0, "runhelp n4", flag_values=new_flags, |
| 592 short_name="n4") |
| 593 self.assertEqual(len(new_flags.FlagDict()), 3) |
| 594 old_len = len(FLAGS.FlagDict()) |
| 595 FLAGS.AppendFlagValues(new_flags) |
| 596 self.assertEqual(len(FLAGS.FlagDict())-old_len, 3) |
| 597 self.assertTrue("new3" in FLAGS.FlagDict()) |
| 598 self.assertTrue("new4" in FLAGS.FlagDict()) |
| 599 self.assertTrue("n4" in FLAGS.FlagDict()) |
| 600 self.assertEqual(FLAGS.FlagDict()['n4'], FLAGS.FlagDict()['new4']) |
| 601 |
| 602 # Make sure AppendFlagValues fails on duplicates |
| 603 flags.DEFINE_boolean("dup4", 0, "runhelp d41") |
| 604 new_flags = flags.FlagValues() |
| 605 flags.DEFINE_boolean("dup4", 0, "runhelp d42", flag_values=new_flags) |
| 606 try: |
| 607 FLAGS.AppendFlagValues(new_flags) |
| 608 raise AssertionError("ignore_copy was not set but caused no exception") |
| 609 except flags.DuplicateFlag, e: |
| 610 pass |
| 611 |
| 612 # Integer out of bounds |
| 613 try: |
| 614 argv = ('./program', '--repeat=-4') |
| 615 FLAGS(argv) |
| 616 raise AssertionError('integer bounds exception not raised:' |
| 617 + str(FLAGS.repeat)) |
| 618 except flags.IllegalFlagValue: |
| 619 pass |
| 620 |
| 621 # Non-integer |
| 622 try: |
| 623 argv = ('./program', '--repeat=2.5') |
| 624 FLAGS(argv) |
| 625 raise AssertionError("malformed integer value exception not raised") |
| 626 except flags.IllegalFlagValue: |
| 627 pass |
| 628 |
| 629 # Missing required arugment |
| 630 try: |
| 631 argv = ('./program', '--name') |
| 632 FLAGS(argv) |
| 633 raise AssertionError("Flag argument required exception not raised") |
| 634 except flags.FlagsError: |
| 635 pass |
| 636 |
| 637 # Non-boolean arguments for boolean |
| 638 try: |
| 639 argv = ('./program', '--debug=goofup') |
| 640 FLAGS(argv) |
| 641 raise AssertionError("Illegal flag value exception not raised") |
| 642 except flags.IllegalFlagValue: |
| 643 pass |
| 644 |
| 645 try: |
| 646 argv = ('./program', '--debug=42') |
| 647 FLAGS(argv) |
| 648 raise AssertionError("Illegal flag value exception not raised") |
| 649 except flags.IllegalFlagValue: |
| 650 pass |
| 651 |
| 652 |
| 653 # Non-numeric argument for integer flag --repeat |
| 654 try: |
| 655 argv = ('./program', '--repeat', 'Bob', 'extra') |
| 656 FLAGS(argv) |
| 657 raise AssertionError("Illegal flag value exception not raised") |
| 658 except flags.IllegalFlagValue: |
| 659 pass |
| 660 |
| 661 ################################################ |
| 662 # Code to test the flagfile=<> loading behavior |
| 663 ################################################ |
| 664 def _SetupTestFiles(self): |
| 665 """ Creates and sets up some dummy flagfile files with bogus flags""" |
| 666 |
| 667 # Figure out where to create temporary files |
| 668 tmp_path = '/tmp/flags_unittest' |
| 669 if os.path.exists(tmp_path): |
| 670 shutil.rmtree(tmp_path) |
| 671 os.makedirs(tmp_path) |
| 672 |
| 673 try: |
| 674 tmp_flag_file_1 = open((tmp_path + '/UnitTestFile1.tst'), 'w') |
| 675 tmp_flag_file_2 = open((tmp_path + '/UnitTestFile2.tst'), 'w') |
| 676 tmp_flag_file_3 = open((tmp_path + '/UnitTestFile3.tst'), 'w') |
| 677 except IOError, e_msg: |
| 678 print e_msg |
| 679 print 'FAIL\n File Creation problem in Unit Test' |
| 680 sys.exit(1) |
| 681 |
| 682 # put some dummy flags in our test files |
| 683 tmp_flag_file_1.write('#A Fake Comment\n') |
| 684 tmp_flag_file_1.write('--UnitTestMessage1=tempFile1!\n') |
| 685 tmp_flag_file_1.write('\n') |
| 686 tmp_flag_file_1.write('--UnitTestNumber=54321\n') |
| 687 tmp_flag_file_1.write('--noUnitTestBoolFlag\n') |
| 688 file_list = [tmp_flag_file_1.name] |
| 689 # this one includes test file 1 |
| 690 tmp_flag_file_2.write('//A Different Fake Comment\n') |
| 691 tmp_flag_file_2.write('--flagfile=%s\n' % tmp_flag_file_1.name) |
| 692 tmp_flag_file_2.write('--UnitTestMessage2=setFromTempFile2\n') |
| 693 tmp_flag_file_2.write('\t\t\n') |
| 694 tmp_flag_file_2.write('--UnitTestNumber=6789a\n') |
| 695 file_list.append(tmp_flag_file_2.name) |
| 696 # this file points to itself |
| 697 tmp_flag_file_3.write('--flagfile=%s\n' % tmp_flag_file_3.name) |
| 698 tmp_flag_file_3.write('--UnitTestMessage1=setFromTempFile3\n') |
| 699 tmp_flag_file_3.write('#YAFC\n') |
| 700 tmp_flag_file_3.write('--UnitTestBoolFlag\n') |
| 701 file_list.append(tmp_flag_file_3.name) |
| 702 |
| 703 tmp_flag_file_1.close() |
| 704 tmp_flag_file_2.close() |
| 705 tmp_flag_file_3.close() |
| 706 |
| 707 return file_list # these are just the file names |
| 708 # end SetupFiles def |
| 709 |
| 710 def _RemoveTestFiles(self, tmp_file_list): |
| 711 """Closes the files we just created. tempfile deletes them for us """ |
| 712 for file_name in tmp_file_list: |
| 713 try: |
| 714 os.remove(file_name) |
| 715 except OSError, e_msg: |
| 716 print '%s\n, Problem deleting test file' % e_msg |
| 717 #end RemoveTestFiles def |
| 718 |
| 719 def __DeclareSomeFlags(self): |
| 720 flags.DEFINE_string('UnitTestMessage1', 'Foo!', 'You Add Here.') |
| 721 flags.DEFINE_string('UnitTestMessage2', 'Bar!', 'Hello, Sailor!') |
| 722 flags.DEFINE_boolean('UnitTestBoolFlag', 0, 'Some Boolean thing') |
| 723 flags.DEFINE_integer('UnitTestNumber', 12345, 'Some integer', |
| 724 lower_bound=0) |
| 725 flags.DEFINE_list('UnitTestList', "1,2,3", 'Some list') |
| 726 |
| 727 def _UndeclareSomeFlags(self): |
| 728 FLAGS.__delattr__('UnitTestMessage1') |
| 729 FLAGS.__delattr__('UnitTestMessage2') |
| 730 FLAGS.__delattr__('UnitTestBoolFlag') |
| 731 FLAGS.__delattr__('UnitTestNumber') |
| 732 FLAGS.__delattr__('UnitTestList') |
| 733 |
| 734 #### Flagfile Unit Tests #### |
| 735 def testMethod_flagfiles_1(self): |
| 736 """ Test trivial case with no flagfile based options. """ |
| 737 self.__DeclareSomeFlags() |
| 738 fake_cmd_line = 'fooScript --UnitTestBoolFlag' |
| 739 fake_argv = fake_cmd_line.split(' ') |
| 740 FLAGS(fake_argv) |
| 741 self.assertEqual( FLAGS.UnitTestBoolFlag, 1) |
| 742 self.assertEqual( fake_argv, FLAGS.ReadFlagsFromFiles(fake_argv)) |
| 743 self._UndeclareSomeFlags() |
| 744 # end testMethodOne |
| 745 |
| 746 def testMethod_flagfiles_2(self): |
| 747 """Tests parsing one file + arguments off simulated argv""" |
| 748 self.__DeclareSomeFlags() |
| 749 tmp_files = self._SetupTestFiles() |
| 750 # specify our temp file on the fake cmd line |
| 751 fake_cmd_line = 'fooScript --q --flagfile=%s' % tmp_files[0] |
| 752 fake_argv = fake_cmd_line.split(' ') |
| 753 |
| 754 # We should see the original cmd line with the file's contents spliced in. |
| 755 # Note that these will be in REVERSE order from order encountered in file |
| 756 # This is done so arguements we encounter sooner will have priority. |
| 757 expected_results = ['fooScript', |
| 758 '--UnitTestMessage1=tempFile1!', |
| 759 '--UnitTestNumber=54321', |
| 760 '--noUnitTestBoolFlag', |
| 761 '--q'] |
| 762 test_results = FLAGS.ReadFlagsFromFiles(fake_argv) |
| 763 self.assertEqual(expected_results, test_results) |
| 764 self._RemoveTestFiles(tmp_files) |
| 765 self._UndeclareSomeFlags() |
| 766 # end testTwo def |
| 767 |
| 768 def testMethod_flagfiles_3(self): |
| 769 """Tests parsing nested files + arguments of simulated argv""" |
| 770 self.__DeclareSomeFlags() |
| 771 tmp_files = self._SetupTestFiles() |
| 772 # specify our temp file on the fake cmd line |
| 773 fake_cmd_line = ('fooScript --UnitTestNumber=77 --flagfile=%s' |
| 774 % tmp_files[1]) |
| 775 fake_argv = fake_cmd_line.split(' ') |
| 776 |
| 777 expected_results = ['fooScript', |
| 778 '--UnitTestMessage1=tempFile1!', |
| 779 '--UnitTestNumber=54321', |
| 780 '--noUnitTestBoolFlag', |
| 781 '--UnitTestMessage2=setFromTempFile2', |
| 782 '--UnitTestNumber=6789a', |
| 783 '--UnitTestNumber=77'] |
| 784 test_results = FLAGS.ReadFlagsFromFiles(fake_argv) |
| 785 self.assertEqual(expected_results, test_results) |
| 786 self._RemoveTestFiles(tmp_files) |
| 787 self._UndeclareSomeFlags() |
| 788 # end testThree def |
| 789 |
| 790 def testMethod_flagfiles_4(self): |
| 791 """Tests parsing self-referential files + arguments of simulated argv. |
| 792 This test should print a warning to stderr of some sort. |
| 793 """ |
| 794 self.__DeclareSomeFlags() |
| 795 tmp_files = self._SetupTestFiles() |
| 796 # specify our temp file on the fake cmd line |
| 797 fake_cmd_line = ('fooScript --flagfile=%s --noUnitTestBoolFlag' |
| 798 % tmp_files[2]) |
| 799 fake_argv = fake_cmd_line.split(' ') |
| 800 expected_results = ['fooScript', |
| 801 '--UnitTestMessage1=setFromTempFile3', |
| 802 '--UnitTestBoolFlag', |
| 803 '--noUnitTestBoolFlag' ] |
| 804 |
| 805 test_results = FLAGS.ReadFlagsFromFiles(fake_argv) |
| 806 self.assertEqual(expected_results, test_results) |
| 807 self._RemoveTestFiles(tmp_files) |
| 808 self._UndeclareSomeFlags() |
| 809 |
| 810 def test_flagfiles_user_path_expansion(self): |
| 811 """Test that user directory referenced paths (ie. ~/foo) are correctly |
| 812 expanded. This test depends on whatever account's running the unit test |
| 813 to have read/write access to their own home directory, otherwise it'll |
| 814 FAIL. |
| 815 """ |
| 816 self.__DeclareSomeFlags() |
| 817 fake_flagfile_item_style_1 = '--flagfile=~/foo.file' |
| 818 fake_flagfile_item_style_2 = '-flagfile=~/foo.file' |
| 819 |
| 820 expected_results = os.path.expanduser('~/foo.file') |
| 821 |
| 822 test_results = FLAGS.ExtractFilename(fake_flagfile_item_style_1) |
| 823 self.assertEqual(expected_results, test_results) |
| 824 |
| 825 test_results = FLAGS.ExtractFilename(fake_flagfile_item_style_2) |
| 826 self.assertEqual(expected_results, test_results) |
| 827 |
| 828 self._UndeclareSomeFlags() |
| 829 |
| 830 # end testFour def |
| 831 |
| 832 def test_no_touchy_non_flags(self): |
| 833 """ |
| 834 Test that the flags parser does not mutilate arguments which are |
| 835 not supposed to be flags |
| 836 """ |
| 837 self.__DeclareSomeFlags() |
| 838 fake_argv = ['fooScript', '--UnitTestBoolFlag', |
| 839 'command', '--command_arg1', '--UnitTestBoom', '--UnitTestB'] |
| 840 argv = FLAGS(fake_argv) |
| 841 self.assertEqual(argv, fake_argv[:1] + fake_argv[2:]) |
| 842 self._UndeclareSomeFlags() |
| 843 |
| 844 def test_SetDefault(self): |
| 845 """ |
| 846 Test changing flag defaults. |
| 847 """ |
| 848 self.__DeclareSomeFlags() |
| 849 # Test that SetDefault changes both the default and the value, |
| 850 # and that the value is changed when one is given as an option. |
| 851 FLAGS['UnitTestMessage1'].SetDefault('New value') |
| 852 self.assertEqual(FLAGS.UnitTestMessage1, 'New value') |
| 853 self.assertEqual(FLAGS['UnitTestMessage1'].default_as_str,"'New value'") |
| 854 FLAGS([ 'dummyscript', '--UnitTestMessage1=Newer value' ]) |
| 855 self.assertEqual(FLAGS.UnitTestMessage1, 'Newer value') |
| 856 |
| 857 # Test that setting the default to None works correctly. |
| 858 FLAGS['UnitTestNumber'].SetDefault(None) |
| 859 self.assertEqual(FLAGS.UnitTestNumber, None) |
| 860 self.assertEqual(FLAGS['UnitTestNumber'].default_as_str, None) |
| 861 FLAGS([ 'dummyscript', '--UnitTestNumber=56' ]) |
| 862 self.assertEqual(FLAGS.UnitTestNumber, 56) |
| 863 |
| 864 # Test that setting the default to zero works correctly. |
| 865 FLAGS['UnitTestNumber'].SetDefault(0) |
| 866 self.assertEqual(FLAGS.UnitTestNumber, 0) |
| 867 self.assertEqual(FLAGS['UnitTestNumber'].default_as_str, "'0'") |
| 868 FLAGS([ 'dummyscript', '--UnitTestNumber=56' ]) |
| 869 self.assertEqual(FLAGS.UnitTestNumber, 56) |
| 870 |
| 871 # Test that setting the default to "" works correctly. |
| 872 FLAGS['UnitTestMessage1'].SetDefault("") |
| 873 self.assertEqual(FLAGS.UnitTestMessage1, "") |
| 874 self.assertEqual(FLAGS['UnitTestMessage1'].default_as_str, "''") |
| 875 FLAGS([ 'dummyscript', '--UnitTestMessage1=fifty-six' ]) |
| 876 self.assertEqual(FLAGS.UnitTestMessage1, "fifty-six") |
| 877 |
| 878 # Test that setting the default to false works correctly. |
| 879 FLAGS['UnitTestBoolFlag'].SetDefault(False) |
| 880 self.assertEqual(FLAGS.UnitTestBoolFlag, False) |
| 881 self.assertEqual(FLAGS['UnitTestBoolFlag'].default_as_str, "'false'") |
| 882 FLAGS([ 'dummyscript', '--UnitTestBoolFlag=true' ]) |
| 883 self.assertEqual(FLAGS.UnitTestBoolFlag, True) |
| 884 |
| 885 # Test that setting a list default works correctly. |
| 886 FLAGS['UnitTestList'].SetDefault('4,5,6') |
| 887 self.assertEqual(FLAGS.UnitTestList, ['4', '5', '6']) |
| 888 self.assertEqual(FLAGS['UnitTestList'].default_as_str, "'4,5,6'") |
| 889 FLAGS([ 'dummyscript', '--UnitTestList=7,8,9' ]) |
| 890 self.assertEqual(FLAGS.UnitTestList, ['7', '8', '9']) |
| 891 |
| 892 # Test that setting invalid defaults raises exceptions |
| 893 self.assertRaises(flags.IllegalFlagValue, |
| 894 FLAGS['UnitTestNumber'].SetDefault, 'oops') |
| 895 self.assertRaises(flags.IllegalFlagValue, |
| 896 FLAGS['UnitTestNumber'].SetDefault, -1) |
| 897 self.assertRaises(flags.IllegalFlagValue, |
| 898 FLAGS['UnitTestBoolFlag'].SetDefault, 'oops') |
| 899 |
| 900 self._UndeclareSomeFlags() |
| 901 |
| 902 def testMethod_ShortestUniquePrefixes(self): |
| 903 """ |
| 904 Test FlagValues.ShortestUniquePrefixes |
| 905 """ |
| 906 flags.DEFINE_string('a', '', '') |
| 907 flags.DEFINE_string('abc', '', '') |
| 908 flags.DEFINE_string('common_a_string', '', '') |
| 909 flags.DEFINE_boolean('common_b_boolean', 0, '') |
| 910 flags.DEFINE_boolean('common_c_boolean', 0, '') |
| 911 flags.DEFINE_boolean('common', 0, '') |
| 912 flags.DEFINE_integer('commonly', 0, '') |
| 913 flags.DEFINE_boolean('zz', 0, '') |
| 914 flags.DEFINE_integer('nozz', 0, '') |
| 915 |
| 916 shorter_flags = FLAGS.ShortestUniquePrefixes(FLAGS.FlagDict()) |
| 917 |
| 918 expected_results = {'nocommon_b_boolean': 'nocommon_b', |
| 919 'common_c_boolean': 'common_c', |
| 920 'common_b_boolean': 'common_b', |
| 921 'a': 'a', |
| 922 'abc': 'ab', |
| 923 'zz': 'z', |
| 924 'nozz': 'nozz', |
| 925 'common_a_string': 'common_a', |
| 926 'commonly': 'commonl', |
| 927 'nocommon_c_boolean': 'nocommon_c', |
| 928 'nocommon': 'nocommon', |
| 929 'common': 'common'} |
| 930 |
| 931 for name, shorter in expected_results.iteritems(): |
| 932 self.assertEquals(shorter_flags[name], shorter) |
| 933 |
| 934 FLAGS.__delattr__('a') |
| 935 FLAGS.__delattr__('abc') |
| 936 FLAGS.__delattr__('common_a_string') |
| 937 FLAGS.__delattr__('common_b_boolean') |
| 938 FLAGS.__delattr__('common_c_boolean') |
| 939 FLAGS.__delattr__('common') |
| 940 FLAGS.__delattr__('commonly') |
| 941 FLAGS.__delattr__('zz') |
| 942 FLAGS.__delattr__('nozz') |
| 943 |
| 944 def test_twodasharg_first(self): |
| 945 flags.DEFINE_string("twodash_name", "Bob", "namehelp") |
| 946 flags.DEFINE_string("twodash_blame", "Rob", "blamehelp") |
| 947 argv = ('./program', |
| 948 '--', |
| 949 '--twodash_name=Harry') |
| 950 argv = FLAGS(argv) |
| 951 self.assertEqual('Bob', FLAGS.twodash_name) |
| 952 self.assertEqual(argv[1], '--twodash_name=Harry') |
| 953 |
| 954 def test_twodasharg_middle(self): |
| 955 flags.DEFINE_string("twodash2_name", "Bob", "namehelp") |
| 956 flags.DEFINE_string("twodash2_blame", "Rob", "blamehelp") |
| 957 argv = ('./program', |
| 958 '--twodash2_blame=Larry', |
| 959 '--', |
| 960 '--twodash2_name=Harry') |
| 961 argv = FLAGS(argv) |
| 962 self.assertEqual('Bob', FLAGS.twodash2_name) |
| 963 self.assertEqual('Larry', FLAGS.twodash2_blame) |
| 964 self.assertEqual(argv[1], '--twodash2_name=Harry') |
| 965 |
| 966 def test_onedasharg_first(self): |
| 967 flags.DEFINE_string("onedash_name", "Bob", "namehelp") |
| 968 flags.DEFINE_string("onedash_blame", "Rob", "blamehelp") |
| 969 argv = ('./program', |
| 970 '-', |
| 971 '--onedash_name=Harry') |
| 972 argv = FLAGS(argv) |
| 973 self.assertEqual(argv[1], '-') |
| 974 # TODO(csilvers): we should still parse --onedash_name=Harry as a |
| 975 # flag, but currently we don't (we stop flag processing as soon as |
| 976 # we see the first non-flag). |
| 977 |
| 978 def test_unrecognized_flags(self): |
| 979 # Unknown flag --nosuchflag |
| 980 try: |
| 981 argv = ('./program', '--nosuchflag', '--name=Bob', 'extra') |
| 982 FLAGS(argv) |
| 983 raise AssertionError("Unknown flag exception not raised") |
| 984 except flags.UnrecognizedFlag, e: |
| 985 assert e.flagname == 'nosuchflag' |
| 986 |
| 987 # Unknown flag -w (short option) |
| 988 try: |
| 989 argv = ('./program', '-w', '--name=Bob', 'extra') |
| 990 FLAGS(argv) |
| 991 raise AssertionError("Unknown flag exception not raised") |
| 992 except flags.UnrecognizedFlag, e: |
| 993 assert e.flagname == 'w' |
| 994 |
| 995 # Unknown flag --nosuchflagwithparam=foo |
| 996 try: |
| 997 argv = ('./program', '--nosuchflagwithparam=foo', '--name=Bob', 'extra') |
| 998 FLAGS(argv) |
| 999 raise AssertionError("Unknown flag exception not raised") |
| 1000 except flags.UnrecognizedFlag, e: |
| 1001 assert e.flagname == 'nosuchflagwithparam' |
| 1002 |
| 1003 # Allow unknown flag --nosuchflag if specified with undefok |
| 1004 argv = ('./program', '--nosuchflag', '--name=Bob', |
| 1005 '--undefok=nosuchflag', 'extra') |
| 1006 argv = FLAGS(argv) |
| 1007 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1008 assert argv[0]=='./program', "program name not preserved" |
| 1009 assert argv[1]=='extra', "extra argument not preserved" |
| 1010 |
| 1011 # But not if the flagname is misspelled: |
| 1012 try: |
| 1013 argv = ('./program', '--nosuchflag', '--name=Bob', |
| 1014 '--undefok=nosuchfla', 'extra') |
| 1015 FLAGS(argv) |
| 1016 raise AssertionError("Unknown flag exception not raised") |
| 1017 except flags.UnrecognizedFlag, e: |
| 1018 assert e.flagname == 'nosuchflag' |
| 1019 |
| 1020 try: |
| 1021 argv = ('./program', '--nosuchflag', '--name=Bob', |
| 1022 '--undefok=nosuchflagg', 'extra') |
| 1023 FLAGS(argv) |
| 1024 raise AssertionError("Unknown flag exception not raised") |
| 1025 except flags.UnrecognizedFlag: |
| 1026 assert e.flagname == 'nosuchflag' |
| 1027 |
| 1028 # Allow unknown short flag -w if specified with undefok |
| 1029 argv = ('./program', '-w', '--name=Bob', '--undefok=w', 'extra') |
| 1030 argv = FLAGS(argv) |
| 1031 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1032 assert argv[0]=='./program', "program name not preserved" |
| 1033 assert argv[1]=='extra', "extra argument not preserved" |
| 1034 |
| 1035 # Allow unknown flag --nosuchflagwithparam=foo if specified |
| 1036 # with undefok |
| 1037 argv = ('./program', '--nosuchflagwithparam=foo', '--name=Bob', |
| 1038 '--undefok=nosuchflagwithparam', 'extra') |
| 1039 argv = FLAGS(argv) |
| 1040 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1041 assert argv[0]=='./program', "program name not preserved" |
| 1042 assert argv[1]=='extra', "extra argument not preserved" |
| 1043 |
| 1044 # Even if undefok specifies multiple flags |
| 1045 argv = ('./program', '--nosuchflag', '-w', '--nosuchflagwithparam=foo', |
| 1046 '--name=Bob', |
| 1047 '--undefok=nosuchflag,w,nosuchflagwithparam', |
| 1048 'extra') |
| 1049 argv = FLAGS(argv) |
| 1050 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1051 assert argv[0]=='./program', "program name not preserved" |
| 1052 assert argv[1]=='extra', "extra argument not preserved" |
| 1053 |
| 1054 # However, not if undefok doesn't specify the flag |
| 1055 try: |
| 1056 argv = ('./program', '--nosuchflag', '--name=Bob', |
| 1057 '--undefok=another_such', 'extra') |
| 1058 FLAGS(argv) |
| 1059 raise AssertionError("Unknown flag exception not raised") |
| 1060 except flags.UnrecognizedFlag, e: |
| 1061 assert e.flagname == 'nosuchflag' |
| 1062 |
| 1063 # Make sure --undefok doesn't mask other option errors. |
| 1064 try: |
| 1065 # Provide an option requiring a parameter but not giving it one. |
| 1066 argv = ('./program', '--undefok=name', '--name') |
| 1067 FLAGS(argv) |
| 1068 raise AssertionError("Missing option parameter exception not raised") |
| 1069 except flags.UnrecognizedFlag: |
| 1070 raise AssertionError("Wrong kind of error exception raised") |
| 1071 except flags.FlagsError: |
| 1072 pass |
| 1073 |
| 1074 # Test --undefok <list> |
| 1075 argv = ('./program', '--nosuchflag', '-w', '--nosuchflagwithparam=foo', |
| 1076 '--name=Bob', |
| 1077 '--undefok', |
| 1078 'nosuchflag,w,nosuchflagwithparam', |
| 1079 'extra') |
| 1080 argv = FLAGS(argv) |
| 1081 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1082 assert argv[0]=='./program', "program name not preserved" |
| 1083 assert argv[1]=='extra', "extra argument not preserved" |
| 1084 |
| 1085 def test_nonglobal_flags(self): |
| 1086 """Test use of non-global FlagValues""" |
| 1087 nonglobal_flags = flags.FlagValues() |
| 1088 flags.DEFINE_string("nonglobal_flag", "Bob", "flaghelp", nonglobal_flags) |
| 1089 argv = ('./program', |
| 1090 '--nonglobal_flag=Mary', |
| 1091 'extra') |
| 1092 argv = nonglobal_flags(argv) |
| 1093 assert len(argv) == 2, "wrong number of arguments pulled" |
| 1094 assert argv[0]=='./program', "program name not preserved" |
| 1095 assert argv[1]=='extra', "extra argument not preserved" |
| 1096 assert nonglobal_flags['nonglobal_flag'].value == 'Mary' |
| 1097 |
| 1098 def test_unrecognized_nonglobal_flags(self): |
| 1099 """Test unrecognized non-global flags""" |
| 1100 nonglobal_flags = flags.FlagValues() |
| 1101 argv = ('./program', |
| 1102 '--nosuchflag') |
| 1103 try: |
| 1104 argv = nonglobal_flags(argv) |
| 1105 raise AssertionError("Unknown flag exception not raised") |
| 1106 except flags.UnrecognizedFlag, e: |
| 1107 assert e.flagname == 'nosuchflag' |
| 1108 pass |
| 1109 |
| 1110 argv = ('./program', |
| 1111 '--nosuchflag', |
| 1112 '--undefok=nosuchflag') |
| 1113 |
| 1114 argv = nonglobal_flags(argv) |
| 1115 assert len(argv) == 1, "wrong number of arguments pulled" |
| 1116 assert argv[0]=='./program', "program name not preserved" |
| 1117 |
| 1118 def test_main_module_help(self): |
| 1119 """Test MainModuleHelp()""" |
| 1120 help = FLAGS.MainModuleHelp() |
| 1121 |
| 1122 # When this test is invoked on behalf of flags_unittest_2_2, |
| 1123 # the main module has not defined any flags. Since there's |
| 1124 # no easy way to run this script in our test environment |
| 1125 # directly from python2.2, don't bother to test the output |
| 1126 # of MainModuleHelp() in that scenario. |
| 1127 if sys.version.startswith('2.2.'): |
| 1128 return |
| 1129 |
| 1130 expected_help = "\n" + sys.argv[0] + ':' + """ |
| 1131 --[no]debug: debughelp |
| 1132 (default: 'false') |
| 1133 -u,--[no]dup1: runhelp d12 |
| 1134 (default: 'true') |
| 1135 -u,--[no]dup2: runhelp d22 |
| 1136 (default: 'true') |
| 1137 -u,--[no]dup3: runhelp d32 |
| 1138 (default: 'true') |
| 1139 --[no]dup4: runhelp d41 |
| 1140 (default: 'false') |
| 1141 -?,--[no]help: show this help |
| 1142 --[no]helpshort: show usage only for this module |
| 1143 --kwery: <who|what|why|where|when>: ? |
| 1144 --l: how long to be |
| 1145 (default: '9223372032559808512') |
| 1146 (an integer) |
| 1147 --letters: a list of letters |
| 1148 (default: 'a,b,c') |
| 1149 (a comma separated list) |
| 1150 -m,--m_str: string option that can occur multiple times; |
| 1151 repeat this option to specify a list of values |
| 1152 (default: "['def1', 'def2']") |
| 1153 --name: namehelp |
| 1154 (default: 'Bob') |
| 1155 --[no]noexec: boolean flag with no as prefix |
| 1156 (default: 'true') |
| 1157 --[no]q: quiet mode |
| 1158 (default: 'true') |
| 1159 --[no]quack: superstring of 'q' |
| 1160 (default: 'false') |
| 1161 -r,--repeat: how many times to repeat (0-5) |
| 1162 (default: '4') |
| 1163 (a non-negative integer) |
| 1164 -s,--s_str: string option that can occur multiple times; |
| 1165 repeat this option to specify a list of values |
| 1166 (default: "['sing1']") |
| 1167 --[no]test0: test boolean parsing |
| 1168 --[no]test1: test boolean parsing |
| 1169 --[no]testget1: test parsing with defaults |
| 1170 --[no]testget2: test parsing with defaults |
| 1171 --[no]testget3: test parsing with defaults |
| 1172 --testget4: test parsing with defaults |
| 1173 (an integer) |
| 1174 --testlist: test lists parsing |
| 1175 (default: '') |
| 1176 (a comma separated list) |
| 1177 --[no]testnone: test boolean parsing |
| 1178 --testspacelist: tests space lists parsing |
| 1179 (default: '') |
| 1180 (a whitespace separated list) |
| 1181 --x: how eXtreme to be |
| 1182 (default: '3') |
| 1183 (an integer) |
| 1184 -z,--[no]zoom1: runhelp z1 |
| 1185 (default: 'false')""" |
| 1186 |
| 1187 if not MultiLineEqual(expected_help, help): |
| 1188 self.fail() |
| 1189 |
| 1190 def test_create_flag_errors(self): |
| 1191 # Since the exception classes are exposed, nothing stops users |
| 1192 # from creating their own instances. This test makes sure that |
| 1193 # people modifying the flags module understand that the external |
| 1194 # mechanisms for creating the exceptions should continue to work. |
| 1195 e = flags.FlagsError() |
| 1196 e = flags.FlagsError("message") |
| 1197 e = flags.DuplicateFlag() |
| 1198 e = flags.DuplicateFlag("message") |
| 1199 e = flags.IllegalFlagValue() |
| 1200 e = flags.IllegalFlagValue("message") |
| 1201 e = flags.UnrecognizedFlag() |
| 1202 e = flags.UnrecognizedFlag("message") |
| 1203 |
| 1204 def main(): |
| 1205 unittest.main() |
| 1206 |
| 1207 if __name__ == '__main__': |
| 1208 main() |
OLD | NEW |