~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/python-gflags/gflags_unittest.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 gflags.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
# For historic reasons, we use the name module_foo instead of
 
48
# test_module_foo, and module_bar instead of test_module_bar.
 
49
import test_module_foo as module_foo
 
50
import test_module_bar as module_bar
 
51
import test_module_baz as module_baz
 
52
 
 
53
def MultiLineEqual(expected_help, help):
 
54
  """Returns True if expected_help == help.  Otherwise returns False
 
55
  and logs the difference in a human-readable way.
 
56
  """
 
57
  if help == expected_help:
 
58
    return True
 
59
 
 
60
  print "Error: FLAGS.MainModuleHelp() didn't return the expected result."
 
61
  print "Got:"
 
62
  print help
 
63
  print "[End of got]"
 
64
 
 
65
  help_lines = help.split('\n')
 
66
  expected_help_lines = expected_help.split('\n')
 
67
 
 
68
  num_help_lines = len(help_lines)
 
69
  num_expected_help_lines = len(expected_help_lines)
 
70
 
 
71
  if num_help_lines != num_expected_help_lines:
 
72
    print "Number of help lines = %d, expected %d" % (
 
73
        num_help_lines, num_expected_help_lines)
 
74
 
 
75
  num_to_match = min(num_help_lines, num_expected_help_lines)
 
76
 
 
77
  for i in range(num_to_match):
 
78
    if help_lines[i] != expected_help_lines[i]:
 
79
      print "One discrepancy: Got:"
 
80
      print help_lines[i]
 
81
      print "Expected:"
 
82
      print expected_help_lines[i]
 
83
      break
 
84
  else:
 
85
    # If we got here, found no discrepancy, print first new line.
 
86
    if num_help_lines > num_expected_help_lines:
 
87
      print "New help line:"
 
88
      print help_lines[num_expected_help_lines]
 
89
    elif num_expected_help_lines > num_help_lines:
 
90
      print "Missing expected help line:"
 
91
      print expected_help_lines[num_help_lines]
 
92
    else:
 
93
      print "Bug in this test -- discrepancy detected but not found."
 
94
 
 
95
  return False
 
96
 
 
97
 
 
98
class FlagsUnitTest(unittest.TestCase):
 
99
  "Flags Unit Test"
 
100
 
 
101
  def setUp(self):
 
102
    # make sure we are using the old, stupid way of parsing flags.
 
103
    FLAGS.UseGnuGetOpt(False)
 
104
 
 
105
  def assertListEqual(self, list1, list2):
 
106
    """Asserts that, when sorted, list1 and list2 are identical."""
 
107
    sorted_list1 = list1[:]
 
108
    sorted_list2 = list2[:]
 
109
    sorted_list1.sort()
 
110
    sorted_list2.sort()
 
111
    self.assertEqual(sorted_list1, sorted_list2)
 
112
 
 
113
  def assertMultiLineEqual(self, expected, actual):
 
114
    self.assert_(MultiLineEqual(expected, actual))
 
115
 
 
116
 
 
117
  def test_flags(self):
 
118
 
 
119
    ##############################################
 
120
    # Test normal usage with no (expected) errors.
 
121
 
 
122
    # Define flags
 
123
    number_test_framework_flags = len(FLAGS.RegisteredFlags())
 
124
    repeatHelp = "how many times to repeat (0-5)"
 
125
    flags.DEFINE_integer("repeat", 4, repeatHelp,
 
126
                         lower_bound=0, short_name='r')
 
127
    flags.DEFINE_string("name", "Bob", "namehelp")
 
128
    flags.DEFINE_boolean("debug", 0, "debughelp")
 
129
    flags.DEFINE_boolean("q", 1, "quiet mode")
 
130
    flags.DEFINE_boolean("quack", 0, "superstring of 'q'")
 
131
    flags.DEFINE_boolean("noexec", 1, "boolean flag with no as prefix")
 
132
    flags.DEFINE_integer("x", 3, "how eXtreme to be")
 
133
    flags.DEFINE_integer("l", 0x7fffffff00000000L, "how long to be")
 
134
    flags.DEFINE_list('letters', 'a,b,c', "a list of letters")
 
135
    flags.DEFINE_list('numbers', [1, 2, 3], "a list of numbers")
 
136
    flags.DEFINE_enum("kwery", None, ['who', 'what', 'why', 'where', 'when'],
 
137
                      "?")
 
138
 
 
139
    # Specify number of flags defined above.  The short_name defined
 
140
    # for 'repeat' counts as an extra flag.
 
141
    number_defined_flags = 11 + 1
 
142
    self.assertEqual(len(FLAGS.RegisteredFlags()),
 
143
                         number_defined_flags + number_test_framework_flags)
 
144
 
 
145
    assert FLAGS.repeat == 4, "integer default values not set:" + FLAGS.repeat
 
146
    assert FLAGS.name == 'Bob', "default values not set:" + FLAGS.name
 
147
    assert FLAGS.debug == 0, "boolean default values not set:" + FLAGS.debug
 
148
    assert FLAGS.q == 1, "boolean default values not set:" + FLAGS.q
 
149
    assert FLAGS.x == 3, "integer default values not set:" + FLAGS.x
 
150
    assert FLAGS.l == 0x7fffffff00000000L, ("integer default values not set:"
 
151
                                            + FLAGS.l)
 
152
    assert FLAGS.letters == ['a', 'b', 'c'], ("list default values not set:"
 
153
                                              + FLAGS.letters)
 
154
    assert FLAGS.numbers == [1, 2, 3], ("list default values not set:"
 
155
                                        + FLAGS.numbers)
 
156
    assert FLAGS.kwery is None, ("enum default None value not set:"
 
157
                                  + FLAGS.kwery)
 
158
 
 
159
    flag_values = FLAGS.FlagValuesDict()
 
160
    assert flag_values['repeat'] == 4
 
161
    assert flag_values['name'] == 'Bob'
 
162
    assert flag_values['debug'] == 0
 
163
    assert flag_values['r'] == 4       # short for of repeat
 
164
    assert flag_values['q'] == 1
 
165
    assert flag_values['quack'] == 0
 
166
    assert flag_values['x'] == 3
 
167
    assert flag_values['l'] == 0x7fffffff00000000L
 
168
    assert flag_values['letters'] == ['a', 'b', 'c']
 
169
    assert flag_values['numbers'] == [1, 2, 3]
 
170
    assert flag_values['kwery'] is None
 
171
 
 
172
    # Verify string form of defaults
 
173
    assert FLAGS['repeat'].default_as_str == "'4'"
 
174
    assert FLAGS['name'].default_as_str == "'Bob'"
 
175
    assert FLAGS['debug'].default_as_str == "'false'"
 
176
    assert FLAGS['q'].default_as_str == "'true'"
 
177
    assert FLAGS['quack'].default_as_str == "'false'"
 
178
    assert FLAGS['noexec'].default_as_str == "'true'"
 
179
    assert FLAGS['x'].default_as_str == "'3'"
 
180
    assert FLAGS['l'].default_as_str == "'9223372032559808512'"
 
181
    assert FLAGS['letters'].default_as_str == "'a,b,c'"
 
182
    assert FLAGS['numbers'].default_as_str == "'1,2,3'"
 
183
 
 
184
    # Verify that the iterator for flags yields all the keys
 
185
    keys = list(FLAGS)
 
186
    keys.sort()
 
187
    reg_flags = FLAGS.RegisteredFlags()
 
188
    reg_flags.sort()
 
189
    self.assertEqual(keys, reg_flags)
 
190
 
 
191
    # Parse flags
 
192
    # .. empty command line
 
193
    argv = ('./program',)
 
194
    argv = FLAGS(argv)
 
195
    assert len(argv) == 1, "wrong number of arguments pulled"
 
196
    assert argv[0]=='./program', "program name not preserved"
 
197
 
 
198
    # .. non-empty command line
 
199
    argv = ('./program', '--debug', '--name=Bob', '-q', '--x=8')
 
200
    argv = FLAGS(argv)
 
201
    assert len(argv) == 1, "wrong number of arguments pulled"
 
202
    assert argv[0]=='./program', "program name not preserved"
 
203
    assert FLAGS['debug'].present == 1
 
204
    FLAGS['debug'].present = 0 # Reset
 
205
    assert FLAGS['name'].present == 1
 
206
    FLAGS['name'].present = 0 # Reset
 
207
    assert FLAGS['q'].present == 1
 
208
    FLAGS['q'].present = 0 # Reset
 
209
    assert FLAGS['x'].present == 1
 
210
    FLAGS['x'].present = 0 # Reset
 
211
 
 
212
    # Flags list
 
213
    self.assertEqual(len(FLAGS.RegisteredFlags()),
 
214
                     number_defined_flags + number_test_framework_flags)
 
215
    assert 'name' in FLAGS.RegisteredFlags()
 
216
    assert 'debug' in FLAGS.RegisteredFlags()
 
217
    assert 'repeat' in FLAGS.RegisteredFlags()
 
218
    assert 'r' in FLAGS.RegisteredFlags()
 
219
    assert 'q' in FLAGS.RegisteredFlags()
 
220
    assert 'quack' in FLAGS.RegisteredFlags()
 
221
    assert 'x' in FLAGS.RegisteredFlags()
 
222
    assert 'l' in FLAGS.RegisteredFlags()
 
223
    assert 'letters' in FLAGS.RegisteredFlags()
 
224
    assert 'numbers' in FLAGS.RegisteredFlags()
 
225
 
 
226
    # has_key
 
227
    assert FLAGS.has_key('name')
 
228
    assert not FLAGS.has_key('name2')
 
229
    assert 'name' in FLAGS
 
230
    assert 'name2' not in FLAGS
 
231
 
 
232
    # try deleting a flag
 
233
    del FLAGS.r
 
234
    self.assertEqual(len(FLAGS.RegisteredFlags()),
 
235
                     number_defined_flags - 1 + number_test_framework_flags)
 
236
    assert not 'r' in FLAGS.RegisteredFlags()
 
237
 
 
238
    # .. command line with extra stuff
 
239
    argv = ('./program', '--debug', '--name=Bob', 'extra')
 
240
    argv = FLAGS(argv)
 
241
    assert len(argv) == 2, "wrong number of arguments pulled"
 
242
    assert argv[0]=='./program', "program name not preserved"
 
243
    assert argv[1]=='extra', "extra argument not preserved"
 
244
    assert FLAGS['debug'].present == 1
 
245
    FLAGS['debug'].present = 0 # Reset
 
246
    assert FLAGS['name'].present == 1
 
247
    FLAGS['name'].present = 0 # Reset
 
248
 
 
249
    # Test reset
 
250
    argv = ('./program', '--debug')
 
251
    argv = FLAGS(argv)
 
252
    assert len(argv) == 1, "wrong number of arguments pulled"
 
253
    assert argv[0] == './program', "program name not preserved"
 
254
    assert FLAGS['debug'].present == 1
 
255
    assert FLAGS['debug'].value
 
256
    FLAGS.Reset()
 
257
    assert FLAGS['debug'].present == 0
 
258
    assert not FLAGS['debug'].value
 
259
 
 
260
    # Test that reset restores default value when default value is None.
 
261
    argv = ('./program', '--kwery=who')
 
262
    argv = FLAGS(argv)
 
263
    assert len(argv) == 1, "wrong number of arguments pulled"
 
264
    assert argv[0] == './program', "program name not preserved"
 
265
    assert FLAGS['kwery'].present == 1
 
266
    assert FLAGS['kwery'].value == 'who'
 
267
    FLAGS.Reset()
 
268
    assert FLAGS['kwery'].present == 0
 
269
    assert FLAGS['kwery'].value == None
 
270
 
 
271
    # Test integer argument passing
 
272
    argv = ('./program', '--x', '0x12345')
 
273
    argv = FLAGS(argv)
 
274
    self.assertEquals(FLAGS.x, 0x12345)
 
275
    self.assertEquals(type(FLAGS.x), int)
 
276
 
 
277
    argv = ('./program', '--x', '0x1234567890ABCDEF1234567890ABCDEF')
 
278
    argv = FLAGS(argv)
 
279
    self.assertEquals(FLAGS.x, 0x1234567890ABCDEF1234567890ABCDEF)
 
280
    self.assertEquals(type(FLAGS.x), long)
 
281
 
 
282
    # Treat 0-prefixed parameters as base-10, not base-8
 
283
    argv = ('./program', '--x', '012345')
 
284
    argv = FLAGS(argv)
 
285
    self.assertEquals(FLAGS.x, 12345)
 
286
    self.assertEquals(type(FLAGS.x), int)
 
287
 
 
288
    argv = ('./program', '--x', '0123459')
 
289
    argv = FLAGS(argv)
 
290
    self.assertEquals(FLAGS.x, 123459)
 
291
    self.assertEquals(type(FLAGS.x), int)
 
292
 
 
293
    argv = ('./program', '--x', '0x123efg')
 
294
    try:
 
295
      argv = FLAGS(argv)
 
296
      raise AssertionError("failed to detect invalid hex argument")
 
297
    except flags.IllegalFlagValue:
 
298
      pass
 
299
 
 
300
    argv = ('./program', '--x', '0X123efg')
 
301
    try:
 
302
      argv = FLAGS(argv)
 
303
      raise AssertionError("failed to detect invalid hex argument")
 
304
    except flags.IllegalFlagValue:
 
305
      pass
 
306
 
 
307
    # Test boolean argument parsing
 
308
    flags.DEFINE_boolean("test0", None, "test boolean parsing")
 
309
    argv = ('./program', '--notest0')
 
310
    argv = FLAGS(argv)
 
311
    assert FLAGS.test0 == 0
 
312
 
 
313
    flags.DEFINE_boolean("test1", None, "test boolean parsing")
 
314
    argv = ('./program', '--test1')
 
315
    argv = FLAGS(argv)
 
316
    assert FLAGS.test1 == 1
 
317
 
 
318
    FLAGS.test0 = None
 
319
    argv = ('./program', '--test0=false')
 
320
    argv = FLAGS(argv)
 
321
    assert FLAGS.test0 == 0
 
322
 
 
323
    FLAGS.test1 = None
 
324
    argv = ('./program', '--test1=true')
 
325
    argv = FLAGS(argv)
 
326
    assert FLAGS.test1 == 1
 
327
 
 
328
    FLAGS.test0 = None
 
329
    argv = ('./program', '--test0=0')
 
330
    argv = FLAGS(argv)
 
331
    assert FLAGS.test0 == 0
 
332
 
 
333
    FLAGS.test1 = None
 
334
    argv = ('./program', '--test1=1')
 
335
    argv = FLAGS(argv)
 
336
    assert FLAGS.test1 == 1
 
337
 
 
338
    # Test booleans that already have 'no' as a prefix
 
339
    FLAGS.noexec = None
 
340
    argv = ('./program', '--nonoexec', '--name', 'Bob')
 
341
    argv = FLAGS(argv)
 
342
    assert FLAGS.noexec == 0
 
343
 
 
344
    FLAGS.noexec = None
 
345
    argv = ('./program', '--name', 'Bob', '--noexec')
 
346
    argv = FLAGS(argv)
 
347
    assert FLAGS.noexec == 1
 
348
 
 
349
    # Test unassigned booleans
 
350
    flags.DEFINE_boolean("testnone", None, "test boolean parsing")
 
351
    argv = ('./program',)
 
352
    argv = FLAGS(argv)
 
353
    assert FLAGS.testnone == None
 
354
 
 
355
    # Test get with default
 
356
    flags.DEFINE_boolean("testget1", None, "test parsing with defaults")
 
357
    flags.DEFINE_boolean("testget2", None, "test parsing with defaults")
 
358
    flags.DEFINE_boolean("testget3", None, "test parsing with defaults")
 
359
    flags.DEFINE_integer("testget4", None, "test parsing with defaults")
 
360
    argv = ('./program','--testget1','--notestget2')
 
361
    argv = FLAGS(argv)
 
362
    assert FLAGS.get('testget1', 'foo') == 1
 
363
    assert FLAGS.get('testget2', 'foo') == 0
 
364
    assert FLAGS.get('testget3', 'foo') == 'foo'
 
365
    assert FLAGS.get('testget4', 'foo') == 'foo'
 
366
 
 
367
    # test list code
 
368
    lists = [['hello','moo','boo','1'],
 
369
             [],]
 
370
 
 
371
    flags.DEFINE_list('testlist', '', 'test lists parsing')
 
372
    flags.DEFINE_spaceseplist('testspacelist', '', 'tests space lists parsing')
 
373
 
 
374
    for name, sep in (('testlist', ','), ('testspacelist', ' '),
 
375
                      ('testspacelist', '\n')):
 
376
      for lst in lists:
 
377
        argv = ('./program', '--%s=%s' % (name, sep.join(lst)))
 
378
        argv = FLAGS(argv)
 
379
        self.assertEquals(getattr(FLAGS, name), lst)
 
380
 
 
381
    # Test help text
 
382
    flagsHelp = str(FLAGS)
 
383
    assert flagsHelp.find("repeat") != -1, "cannot find flag in help"
 
384
    assert flagsHelp.find(repeatHelp) != -1, "cannot find help string in help"
 
385
 
 
386
    # Test flag specified twice
 
387
    argv = ('./program', '--repeat=4', '--repeat=2', '--debug', '--nodebug')
 
388
    argv = FLAGS(argv)
 
389
    self.assertEqual(FLAGS.get('repeat', None), 2)
 
390
    self.assertEqual(FLAGS.get('debug', None), 0)
 
391
 
 
392
    # Test MultiFlag with single default value
 
393
    flags.DEFINE_multistring('s_str', 'sing1',
 
394
                             'string option that can occur multiple times',
 
395
                             short_name='s')
 
396
    self.assertEqual(FLAGS.get('s_str', None), [ 'sing1', ])
 
397
 
 
398
    # Test MultiFlag with list of default values
 
399
    multi_string_defs = [ 'def1', 'def2', ]
 
400
    flags.DEFINE_multistring('m_str', multi_string_defs,
 
401
                             'string option that can occur multiple times',
 
402
                             short_name='m')
 
403
    self.assertEqual(FLAGS.get('m_str', None), multi_string_defs)
 
404
 
 
405
    # Test flag specified multiple times with a MultiFlag
 
406
    argv = ('./program', '--m_str=str1', '-m', 'str2')
 
407
    argv = FLAGS(argv)
 
408
    self.assertEqual(FLAGS.get('m_str', None), [ 'str1', 'str2', ])
 
409
 
 
410
    # Test single-letter flags; should support both single and double dash
 
411
    argv = ('./program', '-q', '-x8')
 
412
    argv = FLAGS(argv)
 
413
    self.assertEqual(FLAGS.get('q', None), 1)
 
414
    self.assertEqual(FLAGS.get('x', None), 8)
 
415
 
 
416
    argv = ('./program', '--q', '--x', '9', '--noqu')
 
417
    argv = FLAGS(argv)
 
418
    self.assertEqual(FLAGS.get('q', None), 1)
 
419
    self.assertEqual(FLAGS.get('x', None), 9)
 
420
    # --noqu should match '--noquack since it's a unique prefix
 
421
    self.assertEqual(FLAGS.get('quack', None), 0)
 
422
 
 
423
    argv = ('./program', '--noq', '--x=10', '--qu')
 
424
    argv = FLAGS(argv)
 
425
    self.assertEqual(FLAGS.get('q', None), 0)
 
426
    self.assertEqual(FLAGS.get('x', None), 10)
 
427
    self.assertEqual(FLAGS.get('quack', None), 1)
 
428
 
 
429
    ####################################
 
430
    # Test flag serialization code:
 
431
 
 
432
    oldtestlist = FLAGS.testlist
 
433
    oldtestspacelist = FLAGS.testspacelist
 
434
 
 
435
    argv = ('./program',
 
436
            FLAGS['test0'].Serialize(),
 
437
            FLAGS['test1'].Serialize(),
 
438
            FLAGS['testnone'].Serialize(),
 
439
            FLAGS['s_str'].Serialize())
 
440
    argv = FLAGS(argv)
 
441
    self.assertEqual(FLAGS['test0'].Serialize(), '--notest0')
 
442
    self.assertEqual(FLAGS['test1'].Serialize(), '--test1')
 
443
    self.assertEqual(FLAGS['testnone'].Serialize(), '')
 
444
    self.assertEqual(FLAGS['s_str'].Serialize(), '--s_str=sing1')
 
445
 
 
446
    testlist1 = ['aa', 'bb']
 
447
    testspacelist1 = ['aa', 'bb', 'cc']
 
448
    FLAGS.testlist = list(testlist1)
 
449
    FLAGS.testspacelist = list(testspacelist1)
 
450
    argv = ('./program',
 
451
            FLAGS['testlist'].Serialize(),
 
452
            FLAGS['testspacelist'].Serialize())
 
453
    argv = FLAGS(argv)
 
454
    self.assertEqual(FLAGS.testlist, testlist1)
 
455
    self.assertEqual(FLAGS.testspacelist, testspacelist1)
 
456
 
 
457
    testlist1 = ['aa some spaces', 'bb']
 
458
    testspacelist1 = ['aa', 'bb,some,commas,', 'cc']
 
459
    FLAGS.testlist = list(testlist1)
 
460
    FLAGS.testspacelist = list(testspacelist1)
 
461
    argv = ('./program',
 
462
            FLAGS['testlist'].Serialize(),
 
463
            FLAGS['testspacelist'].Serialize())
 
464
    argv = FLAGS(argv)
 
465
    self.assertEqual(FLAGS.testlist, testlist1)
 
466
    self.assertEqual(FLAGS.testspacelist, testspacelist1)
 
467
 
 
468
    FLAGS.testlist = oldtestlist
 
469
    FLAGS.testspacelist = oldtestspacelist
 
470
 
 
471
    ####################################
 
472
    # Test flag-update:
 
473
 
 
474
    def ArgsString():
 
475
      flagnames = FLAGS.RegisteredFlags()
 
476
 
 
477
      flagnames.sort()
 
478
      nonbool_flags = ['--%s %s' % (name, FLAGS.get(name, None))
 
479
                       for name in flagnames
 
480
                       if not isinstance(FLAGS[name], flags.BooleanFlag)]
 
481
 
 
482
      truebool_flags = ['--%s' % (name)
 
483
                        for name in flagnames
 
484
                        if isinstance(FLAGS[name], flags.BooleanFlag) and
 
485
                          FLAGS.get(name, None)]
 
486
      falsebool_flags = ['--no%s' % (name)
 
487
                         for name in flagnames
 
488
                         if isinstance(FLAGS[name], flags.BooleanFlag) and
 
489
                           not FLAGS.get(name, None)]
 
490
      return ' '.join(nonbool_flags + truebool_flags + falsebool_flags)
 
491
 
 
492
    argv = ('./program', '--repeat=3', '--name=giants', '--nodebug')
 
493
 
 
494
    FLAGS(argv)
 
495
    self.assertEqual(FLAGS.get('repeat', None), 3)
 
496
    self.assertEqual(FLAGS.get('name', None), 'giants')
 
497
    self.assertEqual(FLAGS.get('debug', None), 0)
 
498
    self.assertEqual(ArgsString(),
 
499
      "--kwery None "
 
500
      "--l 9223372032559808512 "
 
501
      "--letters ['a', 'b', 'c'] "
 
502
      "--m ['str1', 'str2'] --m_str ['str1', 'str2'] "
 
503
      "--name giants "
 
504
      "--numbers [1, 2, 3] "
 
505
      "--repeat 3 "
 
506
      "--s ['sing1'] --s_str ['sing1'] "
 
507
      "--testget4 None --testlist [] "
 
508
      "--testspacelist [] --x 10 "
 
509
      "--noexec --quack "
 
510
      "--test1 "
 
511
      "--testget1 --tmod_baz_x --no? --nodebug --nohelp --nohelpshort --nohelpxml "
 
512
      "--noq --notest0 --notestget2 "
 
513
      "--notestget3 --notestnone")
 
514
 
 
515
    argv = ('./program', '--debug', '--m_str=upd1', '-s', 'upd2')
 
516
    FLAGS(argv)
 
517
    self.assertEqual(FLAGS.get('repeat', None), 3)
 
518
    self.assertEqual(FLAGS.get('name', None), 'giants')
 
519
    self.assertEqual(FLAGS.get('debug', None), 1)
 
520
 
 
521
    # items appended to existing non-default value lists for --m/--m_str
 
522
    # new value overwrites default value (not appended to it) for --s/--s_str
 
523
    self.assertEqual(ArgsString(),
 
524
      "--kwery None "
 
525
      "--l 9223372032559808512 "
 
526
      "--letters ['a', 'b', 'c'] "
 
527
      "--m ['str1', 'str2', 'upd1'] "
 
528
      "--m_str ['str1', 'str2', 'upd1'] "
 
529
      "--name giants "
 
530
      "--numbers [1, 2, 3] "
 
531
      "--repeat 3 "
 
532
      "--s ['upd2'] --s_str ['upd2'] "
 
533
      "--testget4 None --testlist [] "
 
534
      "--testspacelist [] --x 10 "
 
535
      "--debug --noexec --quack "
 
536
      "--test1 "
 
537
      "--testget1 --tmod_baz_x --no? --nohelp --nohelpshort --nohelpxml "
 
538
      "--noq --notest0 --notestget2 "
 
539
      "--notestget3 --notestnone")
 
540
 
 
541
 
 
542
    ####################################
 
543
    # Test all kind of error conditions.
 
544
 
 
545
    # Duplicate flag detection
 
546
    try:
 
547
      flags.DEFINE_boolean("run", 0, "runhelp", short_name='q')
 
548
      raise AssertionError("duplicate flag detection failed")
 
549
    except flags.DuplicateFlag, e:
 
550
      pass
 
551
 
 
552
    # Duplicate short flag detection
 
553
    try:
 
554
      flags.DEFINE_boolean("zoom1", 0, "runhelp z1", short_name='z')
 
555
      flags.DEFINE_boolean("zoom2", 0, "runhelp z2", short_name='z')
 
556
      raise AssertionError("duplicate short flag detection failed")
 
557
    except flags.DuplicateFlag, e:
 
558
      self.assertTrue("The flag 'z' is defined twice. " in e.args[0])
 
559
      self.assertTrue("First from" in e.args[0])
 
560
      self.assertTrue(", Second from" in e.args[0])
 
561
 
 
562
    # Duplicate mixed flag detection
 
563
    try:
 
564
      flags.DEFINE_boolean("short1", 0, "runhelp s1", short_name='s')
 
565
      flags.DEFINE_boolean("s", 0, "runhelp s2")
 
566
      raise AssertionError("duplicate mixed flag detection failed")
 
567
    except flags.DuplicateFlag, e:
 
568
      self.assertTrue("The flag 's' is defined twice. " in e.args[0])
 
569
      self.assertTrue("First from" in e.args[0])
 
570
      self.assertTrue(", Second from" in e.args[0])
 
571
 
 
572
    # Make sure allow_override works
 
573
    try:
 
574
      flags.DEFINE_boolean("dup1", 0, "runhelp d11", short_name='u',
 
575
                           allow_override=0)
 
576
      flag = FLAGS.FlagDict()['dup1']
 
577
      self.assertEqual(flag.default, 0)
 
578
 
 
579
      flags.DEFINE_boolean("dup1", 1, "runhelp d12", short_name='u',
 
580
                           allow_override=1)
 
581
      flag = FLAGS.FlagDict()['dup1']
 
582
      self.assertEqual(flag.default, 1)
 
583
    except flags.DuplicateFlag, e:
 
584
      raise AssertionError("allow_override did not permit a flag duplication")
 
585
 
 
586
    # Make sure allow_override works
 
587
    try:
 
588
      flags.DEFINE_boolean("dup2", 0, "runhelp d21", short_name='u',
 
589
                           allow_override=1)
 
590
      flag = FLAGS.FlagDict()['dup2']
 
591
      self.assertEqual(flag.default, 0)
 
592
 
 
593
      flags.DEFINE_boolean("dup2", 1, "runhelp d22", short_name='u',
 
594
                           allow_override=0)
 
595
      flag = FLAGS.FlagDict()['dup2']
 
596
      self.assertEqual(flag.default, 1)
 
597
    except flags.DuplicateFlag, e:
 
598
      raise AssertionError("allow_override did not permit a flag duplication")
 
599
 
 
600
    # Make sure allow_override doesn't work with None default
 
601
    try:
 
602
      flags.DEFINE_boolean("dup3", 0, "runhelp d31", short_name='u',
 
603
                           allow_override=0)
 
604
      flag = FLAGS.FlagDict()['dup3']
 
605
      self.assertEqual(flag.default, 0)
 
606
 
 
607
      flags.DEFINE_boolean("dup3", None, "runhelp d32", short_name='u',
 
608
                           allow_override=1)
 
609
      raise AssertionError('Cannot override a flag with a default of None')
 
610
    except flags.DuplicateFlag, e:
 
611
      pass
 
612
 
 
613
    # Make sure that when we override, the help string gets updated correctly
 
614
    flags.DEFINE_boolean("dup3", 0, "runhelp d31", short_name='u',
 
615
                         allow_override=1)
 
616
    flags.DEFINE_boolean("dup3", 1, "runhelp d32", short_name='u',
 
617
                         allow_override=1)
 
618
    self.assert_(str(FLAGS).find('runhelp d31') == -1)
 
619
    self.assert_(str(FLAGS).find('runhelp d32') != -1)
 
620
 
 
621
    # Make sure AppendFlagValues works
 
622
    new_flags = flags.FlagValues()
 
623
    flags.DEFINE_boolean("new1", 0, "runhelp n1", flag_values=new_flags)
 
624
    flags.DEFINE_boolean("new2", 0, "runhelp n2", flag_values=new_flags)
 
625
    self.assertEqual(len(new_flags.FlagDict()), 2)
 
626
    old_len = len(FLAGS.FlagDict())
 
627
    FLAGS.AppendFlagValues(new_flags)
 
628
    self.assertEqual(len(FLAGS.FlagDict())-old_len, 2)
 
629
    self.assertEqual("new1" in FLAGS.FlagDict(), True)
 
630
    self.assertEqual("new2" in FLAGS.FlagDict(), True)
 
631
 
 
632
    # Make sure AppendFlagValues works with flags with shortnames.
 
633
    new_flags = flags.FlagValues()
 
634
    flags.DEFINE_boolean("new3", 0, "runhelp n3", flag_values=new_flags)
 
635
    flags.DEFINE_boolean("new4", 0, "runhelp n4", flag_values=new_flags,
 
636
                         short_name="n4")
 
637
    self.assertEqual(len(new_flags.FlagDict()), 3)
 
638
    old_len = len(FLAGS.FlagDict())
 
639
    FLAGS.AppendFlagValues(new_flags)
 
640
    self.assertEqual(len(FLAGS.FlagDict())-old_len, 3)
 
641
    self.assertTrue("new3" in FLAGS.FlagDict())
 
642
    self.assertTrue("new4" in FLAGS.FlagDict())
 
643
    self.assertTrue("n4" in FLAGS.FlagDict())
 
644
    self.assertEqual(FLAGS.FlagDict()['n4'], FLAGS.FlagDict()['new4'])
 
645
 
 
646
    # Make sure AppendFlagValues fails on duplicates
 
647
    flags.DEFINE_boolean("dup4", 0, "runhelp d41")
 
648
    new_flags = flags.FlagValues()
 
649
    flags.DEFINE_boolean("dup4", 0, "runhelp d42", flag_values=new_flags)
 
650
    try:
 
651
      FLAGS.AppendFlagValues(new_flags)
 
652
      raise AssertionError("ignore_copy was not set but caused no exception")
 
653
    except flags.DuplicateFlag, e:
 
654
      pass
 
655
 
 
656
    # Integer out of bounds
 
657
    try:
 
658
      argv = ('./program', '--repeat=-4')
 
659
      FLAGS(argv)
 
660
      raise AssertionError('integer bounds exception not raised:'
 
661
                           + str(FLAGS.repeat))
 
662
    except flags.IllegalFlagValue:
 
663
      pass
 
664
 
 
665
    # Non-integer
 
666
    try:
 
667
      argv = ('./program', '--repeat=2.5')
 
668
      FLAGS(argv)
 
669
      raise AssertionError("malformed integer value exception not raised")
 
670
    except flags.IllegalFlagValue:
 
671
      pass
 
672
 
 
673
    # Missing required arugment
 
674
    try:
 
675
      argv = ('./program', '--name')
 
676
      FLAGS(argv)
 
677
      raise AssertionError("Flag argument required exception not raised")
 
678
    except flags.FlagsError:
 
679
      pass
 
680
 
 
681
    # Non-boolean arguments for boolean
 
682
    try:
 
683
      argv = ('./program', '--debug=goofup')
 
684
      FLAGS(argv)
 
685
      raise AssertionError("Illegal flag value exception not raised")
 
686
    except flags.IllegalFlagValue:
 
687
      pass
 
688
 
 
689
    try:
 
690
      argv = ('./program', '--debug=42')
 
691
      FLAGS(argv)
 
692
      raise AssertionError("Illegal flag value exception not raised")
 
693
    except flags.IllegalFlagValue:
 
694
      pass
 
695
 
 
696
 
 
697
    # Non-numeric argument for integer flag --repeat
 
698
    try:
 
699
      argv = ('./program', '--repeat', 'Bob', 'extra')
 
700
      FLAGS(argv)
 
701
      raise AssertionError("Illegal flag value exception not raised")
 
702
    except flags.IllegalFlagValue:
 
703
      pass
 
704
 
 
705
  ################################################
 
706
  # Code to test the flagfile=<> loading behavior
 
707
  ################################################
 
708
  def _SetupTestFiles(self):
 
709
    """ Creates and sets up some dummy flagfile files with bogus flags"""
 
710
 
 
711
    # Figure out where to create temporary files
 
712
    tmp_path = '/tmp/flags_unittest'
 
713
    if os.path.exists(tmp_path):
 
714
      shutil.rmtree(tmp_path)
 
715
    os.makedirs(tmp_path)
 
716
 
 
717
    try:
 
718
      tmp_flag_file_1 = open((tmp_path + '/UnitTestFile1.tst'), 'w')
 
719
      tmp_flag_file_2 = open((tmp_path + '/UnitTestFile2.tst'), 'w')
 
720
      tmp_flag_file_3 = open((tmp_path + '/UnitTestFile3.tst'), 'w')
 
721
    except IOError, e_msg:
 
722
      print e_msg
 
723
      print 'FAIL\n File Creation problem in Unit Test'
 
724
      sys.exit(1)
 
725
 
 
726
    # put some dummy flags in our test files
 
727
    tmp_flag_file_1.write('#A Fake Comment\n')
 
728
    tmp_flag_file_1.write('--UnitTestMessage1=tempFile1!\n')
 
729
    tmp_flag_file_1.write('\n')
 
730
    tmp_flag_file_1.write('--UnitTestNumber=54321\n')
 
731
    tmp_flag_file_1.write('--noUnitTestBoolFlag\n')
 
732
    file_list = [tmp_flag_file_1.name]
 
733
    # this one includes test file 1
 
734
    tmp_flag_file_2.write('//A Different Fake Comment\n')
 
735
    tmp_flag_file_2.write('--flagfile=%s\n' % tmp_flag_file_1.name)
 
736
    tmp_flag_file_2.write('--UnitTestMessage2=setFromTempFile2\n')
 
737
    tmp_flag_file_2.write('\t\t\n')
 
738
    tmp_flag_file_2.write('--UnitTestNumber=6789a\n')
 
739
    file_list.append(tmp_flag_file_2.name)
 
740
    # this file points to itself
 
741
    tmp_flag_file_3.write('--flagfile=%s\n' % tmp_flag_file_3.name)
 
742
    tmp_flag_file_3.write('--UnitTestMessage1=setFromTempFile3\n')
 
743
    tmp_flag_file_3.write('#YAFC\n')
 
744
    tmp_flag_file_3.write('--UnitTestBoolFlag\n')
 
745
    file_list.append(tmp_flag_file_3.name)
 
746
 
 
747
    tmp_flag_file_1.close()
 
748
    tmp_flag_file_2.close()
 
749
    tmp_flag_file_3.close()
 
750
 
 
751
    return file_list # these are just the file names
 
752
  # end SetupFiles def
 
753
 
 
754
  def _RemoveTestFiles(self, tmp_file_list):
 
755
    """Closes the files we just created.  tempfile deletes them for us """
 
756
    for file_name in tmp_file_list:
 
757
      try:
 
758
        os.remove(file_name)
 
759
      except OSError, e_msg:
 
760
        print '%s\n, Problem deleting test file' % e_msg
 
761
  #end RemoveTestFiles def
 
762
 
 
763
  def __DeclareSomeFlags(self):
 
764
    flags.DEFINE_string('UnitTestMessage1', 'Foo!', 'You Add Here.')
 
765
    flags.DEFINE_string('UnitTestMessage2', 'Bar!', 'Hello, Sailor!')
 
766
    flags.DEFINE_boolean('UnitTestBoolFlag', 0, 'Some Boolean thing')
 
767
    flags.DEFINE_integer('UnitTestNumber', 12345, 'Some integer',
 
768
                         lower_bound=0)
 
769
    flags.DEFINE_list('UnitTestList', "1,2,3", 'Some list')
 
770
 
 
771
  def _UndeclareSomeFlags(self):
 
772
    FLAGS.__delattr__('UnitTestMessage1')
 
773
    FLAGS.__delattr__('UnitTestMessage2')
 
774
    FLAGS.__delattr__('UnitTestBoolFlag')
 
775
    FLAGS.__delattr__('UnitTestNumber')
 
776
    FLAGS.__delattr__('UnitTestList')
 
777
 
 
778
  def _ReadFlagsFromFiles(self, argv, force_gnu):
 
779
    return argv[:1] + FLAGS.ReadFlagsFromFiles(argv[1:], force_gnu=force_gnu)
 
780
 
 
781
  #### Flagfile Unit Tests ####
 
782
  def testMethod_flagfiles_1(self):
 
783
    """ Test trivial case with no flagfile based options. """
 
784
    self.__DeclareSomeFlags()
 
785
    try:
 
786
      fake_cmd_line = 'fooScript --UnitTestBoolFlag'
 
787
      fake_argv = fake_cmd_line.split(' ')
 
788
      FLAGS(fake_argv)
 
789
      self.assertEqual( FLAGS.UnitTestBoolFlag, 1)
 
790
      self.assertEqual( fake_argv, self._ReadFlagsFromFiles(fake_argv, False))
 
791
    finally:
 
792
      self._UndeclareSomeFlags()
 
793
  # end testMethodOne
 
794
 
 
795
  def testMethod_flagfiles_2(self):
 
796
    """Tests parsing one file + arguments off simulated argv"""
 
797
    self.__DeclareSomeFlags()
 
798
    try:
 
799
      tmp_files = self._SetupTestFiles()
 
800
      # specify our temp file on the fake cmd line
 
801
      fake_cmd_line = 'fooScript --q --flagfile=%s' % tmp_files[0]
 
802
      fake_argv = fake_cmd_line.split(' ')
 
803
 
 
804
      # We should see the original cmd line with the file's contents spliced in.
 
805
      # Note that these will be in REVERSE order from order encountered in file
 
806
      # This is done so arguements we encounter sooner will have priority.
 
807
      expected_results = ['fooScript',
 
808
                            '--UnitTestMessage1=tempFile1!',
 
809
                            '--UnitTestNumber=54321',
 
810
                            '--noUnitTestBoolFlag',
 
811
                            '--q']
 
812
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
813
      self.assertEqual(expected_results, test_results)
 
814
    finally:
 
815
      self._RemoveTestFiles(tmp_files)
 
816
      self._UndeclareSomeFlags()
 
817
  # end testTwo def
 
818
 
 
819
  def testMethod_flagfiles_3(self):
 
820
    """Tests parsing nested files + arguments of simulated argv"""
 
821
    self.__DeclareSomeFlags()
 
822
    try:
 
823
      tmp_files = self._SetupTestFiles()
 
824
      # specify our temp file on the fake cmd line
 
825
      fake_cmd_line = ('fooScript --UnitTestNumber=77 --flagfile=%s'
 
826
                       % tmp_files[1])
 
827
      fake_argv = fake_cmd_line.split(' ')
 
828
 
 
829
      expected_results = ['fooScript',
 
830
                            '--UnitTestMessage1=tempFile1!',
 
831
                            '--UnitTestNumber=54321',
 
832
                            '--noUnitTestBoolFlag',
 
833
                            '--UnitTestMessage2=setFromTempFile2',
 
834
                            '--UnitTestNumber=6789a',
 
835
                            '--UnitTestNumber=77']
 
836
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
837
      self.assertEqual(expected_results, test_results)
 
838
    finally:
 
839
      self._RemoveTestFiles(tmp_files)
 
840
      self._UndeclareSomeFlags()
 
841
  # end testThree def
 
842
 
 
843
  def testMethod_flagfiles_4(self):
 
844
    """Tests parsing self-referential files + arguments of simulated argv.
 
845
      This test should print a warning to stderr of some sort.
 
846
    """
 
847
    self.__DeclareSomeFlags()
 
848
    try:
 
849
      tmp_files = self._SetupTestFiles()
 
850
      # specify our temp file on the fake cmd line
 
851
      fake_cmd_line = ('fooScript --flagfile=%s --noUnitTestBoolFlag'
 
852
                       % tmp_files[2])
 
853
      fake_argv = fake_cmd_line.split(' ')
 
854
      expected_results = ['fooScript',
 
855
                            '--UnitTestMessage1=setFromTempFile3',
 
856
                            '--UnitTestBoolFlag',
 
857
                            '--noUnitTestBoolFlag' ]
 
858
 
 
859
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
860
      self.assertEqual(expected_results, test_results)
 
861
    finally:
 
862
      self._RemoveTestFiles(tmp_files)
 
863
      self._UndeclareSomeFlags()
 
864
 
 
865
  def testMethod_flagfiles_5(self):
 
866
    """Test that --flagfile parsing respects the '--' end-of-options marker."""
 
867
    self.__DeclareSomeFlags()
 
868
    try:
 
869
      tmp_files = self._SetupTestFiles()
 
870
      # specify our temp file on the fake cmd line
 
871
      fake_cmd_line = 'fooScript --SomeFlag -- --flagfile=%s' % tmp_files[0]
 
872
      fake_argv = fake_cmd_line.split(' ')
 
873
      expected_results = ['fooScript',
 
874
                          '--SomeFlag',
 
875
                          '--',
 
876
                          '--flagfile=%s' % tmp_files[0]]
 
877
 
 
878
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
879
      self.assertEqual(expected_results, test_results)
 
880
    finally:
 
881
      self._RemoveTestFiles(tmp_files)
 
882
      self._UndeclareSomeFlags()
 
883
 
 
884
  def testMethod_flagfiles_6(self):
 
885
    """Test that --flagfile parsing stops at non-options (non-GNU behavior)."""
 
886
    self.__DeclareSomeFlags()
 
887
    try:
 
888
      tmp_files = self._SetupTestFiles()
 
889
      # specify our temp file on the fake cmd line
 
890
      fake_cmd_line = ('fooScript --SomeFlag some_arg --flagfile=%s'
 
891
                       % tmp_files[0])
 
892
      fake_argv = fake_cmd_line.split(' ')
 
893
      expected_results = ['fooScript',
 
894
                          '--SomeFlag',
 
895
                          'some_arg',
 
896
                          '--flagfile=%s' % tmp_files[0]]
 
897
 
 
898
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
899
      self.assertEqual(expected_results, test_results)
 
900
    finally:
 
901
      self._RemoveTestFiles(tmp_files)
 
902
      self._UndeclareSomeFlags()
 
903
 
 
904
  def testMethod_flagfiles_7(self):
 
905
    """Test that --flagfile parsing skips over a non-option (GNU behavior)."""
 
906
    self.__DeclareSomeFlags()
 
907
    try:
 
908
      FLAGS.UseGnuGetOpt()
 
909
      tmp_files = self._SetupTestFiles()
 
910
      # specify our temp file on the fake cmd line
 
911
      fake_cmd_line = ('fooScript --SomeFlag some_arg --flagfile=%s'
 
912
                       % tmp_files[0])
 
913
      fake_argv = fake_cmd_line.split(' ')
 
914
      expected_results = ['fooScript',
 
915
                          '--UnitTestMessage1=tempFile1!',
 
916
                          '--UnitTestNumber=54321',
 
917
                          '--noUnitTestBoolFlag',
 
918
                          '--SomeFlag',
 
919
                          'some_arg']
 
920
 
 
921
      test_results = self._ReadFlagsFromFiles(fake_argv, False)
 
922
      self.assertEqual(expected_results, test_results)
 
923
    finally:
 
924
      self._RemoveTestFiles(tmp_files)
 
925
      self._UndeclareSomeFlags()
 
926
 
 
927
  def testMethod_flagfiles_8(self):
 
928
    """Test that --flagfile parsing respects force_gnu=True."""
 
929
    self.__DeclareSomeFlags()
 
930
    try:
 
931
      tmp_files = self._SetupTestFiles()
 
932
      # specify our temp file on the fake cmd line
 
933
      fake_cmd_line = ('fooScript --SomeFlag some_arg --flagfile=%s'
 
934
                       % tmp_files[0])
 
935
      fake_argv = fake_cmd_line.split(' ')
 
936
      expected_results = ['fooScript',
 
937
                          '--UnitTestMessage1=tempFile1!',
 
938
                          '--UnitTestNumber=54321',
 
939
                          '--noUnitTestBoolFlag',
 
940
                          '--SomeFlag',
 
941
                          'some_arg']
 
942
 
 
943
      test_results = self._ReadFlagsFromFiles(fake_argv, True)
 
944
      self.assertEqual(expected_results, test_results)
 
945
    finally:
 
946
      self._RemoveTestFiles(tmp_files)
 
947
      self._UndeclareSomeFlags()
 
948
 
 
949
  def test_flagfiles_user_path_expansion(self):
 
950
    """Test that user directory referenced paths (ie. ~/foo) are correctly
 
951
      expanded.  This test depends on whatever account's running the unit test
 
952
      to have read/write access to their own home directory, otherwise it'll
 
953
      FAIL.
 
954
    """
 
955
    self.__DeclareSomeFlags()
 
956
    fake_flagfile_item_style_1 = '--flagfile=~/foo.file'
 
957
    fake_flagfile_item_style_2 = '-flagfile=~/foo.file'
 
958
 
 
959
    expected_results = os.path.expanduser('~/foo.file')
 
960
 
 
961
    test_results = FLAGS.ExtractFilename(fake_flagfile_item_style_1)
 
962
    self.assertEqual(expected_results, test_results)
 
963
 
 
964
    test_results = FLAGS.ExtractFilename(fake_flagfile_item_style_2)
 
965
    self.assertEqual(expected_results, test_results)
 
966
 
 
967
    self._UndeclareSomeFlags()
 
968
 
 
969
  # end testFour def
 
970
 
 
971
  def test_no_touchy_non_flags(self):
 
972
    """
 
973
    Test that the flags parser does not mutilate arguments which are
 
974
    not supposed to be flags
 
975
    """
 
976
    self.__DeclareSomeFlags()
 
977
    fake_argv = ['fooScript', '--UnitTestBoolFlag',
 
978
                 'command', '--command_arg1', '--UnitTestBoom', '--UnitTestB']
 
979
    argv = FLAGS(fake_argv)
 
980
    self.assertEqual(argv, fake_argv[:1] + fake_argv[2:])
 
981
    self._UndeclareSomeFlags()
 
982
 
 
983
  def test_parse_flags_after_args_if_using_gnu_getopt(self):
 
984
    """
 
985
    Test that flags given after arguments are parsed if using gnu_getopt.
 
986
    """
 
987
    self.__DeclareSomeFlags()
 
988
    FLAGS.UseGnuGetOpt()
 
989
    fake_argv = ['fooScript', '--UnitTestBoolFlag',
 
990
                 'command', '--UnitTestB']
 
991
    argv = FLAGS(fake_argv)
 
992
    self.assertEqual(argv, ['fooScript', 'command'])
 
993
    self._UndeclareSomeFlags()
 
994
 
 
995
  def test_SetDefault(self):
 
996
    """
 
997
    Test changing flag defaults.
 
998
    """
 
999
    self.__DeclareSomeFlags()
 
1000
    # Test that SetDefault changes both the default and the value,
 
1001
    # and that the value is changed when one is given as an option.
 
1002
    FLAGS['UnitTestMessage1'].SetDefault('New value')
 
1003
    self.assertEqual(FLAGS.UnitTestMessage1, 'New value')
 
1004
    self.assertEqual(FLAGS['UnitTestMessage1'].default_as_str,"'New value'")
 
1005
    FLAGS([ 'dummyscript', '--UnitTestMessage1=Newer value' ])
 
1006
    self.assertEqual(FLAGS.UnitTestMessage1, 'Newer value')
 
1007
 
 
1008
    # Test that setting the default to None works correctly.
 
1009
    FLAGS['UnitTestNumber'].SetDefault(None)
 
1010
    self.assertEqual(FLAGS.UnitTestNumber, None)
 
1011
    self.assertEqual(FLAGS['UnitTestNumber'].default_as_str, None)
 
1012
    FLAGS([ 'dummyscript', '--UnitTestNumber=56' ])
 
1013
    self.assertEqual(FLAGS.UnitTestNumber, 56)
 
1014
 
 
1015
    # Test that setting the default to zero works correctly.
 
1016
    FLAGS['UnitTestNumber'].SetDefault(0)
 
1017
    self.assertEqual(FLAGS.UnitTestNumber, 0)
 
1018
    self.assertEqual(FLAGS['UnitTestNumber'].default_as_str, "'0'")
 
1019
    FLAGS([ 'dummyscript', '--UnitTestNumber=56' ])
 
1020
    self.assertEqual(FLAGS.UnitTestNumber, 56)
 
1021
 
 
1022
    # Test that setting the default to "" works correctly.
 
1023
    FLAGS['UnitTestMessage1'].SetDefault("")
 
1024
    self.assertEqual(FLAGS.UnitTestMessage1, "")
 
1025
    self.assertEqual(FLAGS['UnitTestMessage1'].default_as_str, "''")
 
1026
    FLAGS([ 'dummyscript', '--UnitTestMessage1=fifty-six' ])
 
1027
    self.assertEqual(FLAGS.UnitTestMessage1, "fifty-six")
 
1028
 
 
1029
    # Test that setting the default to false works correctly.
 
1030
    FLAGS['UnitTestBoolFlag'].SetDefault(False)
 
1031
    self.assertEqual(FLAGS.UnitTestBoolFlag, False)
 
1032
    self.assertEqual(FLAGS['UnitTestBoolFlag'].default_as_str, "'false'")
 
1033
    FLAGS([ 'dummyscript', '--UnitTestBoolFlag=true' ])
 
1034
    self.assertEqual(FLAGS.UnitTestBoolFlag, True)
 
1035
 
 
1036
    # Test that setting a list default works correctly.
 
1037
    FLAGS['UnitTestList'].SetDefault('4,5,6')
 
1038
    self.assertEqual(FLAGS.UnitTestList, ['4', '5', '6'])
 
1039
    self.assertEqual(FLAGS['UnitTestList'].default_as_str, "'4,5,6'")
 
1040
    FLAGS([ 'dummyscript', '--UnitTestList=7,8,9' ])
 
1041
    self.assertEqual(FLAGS.UnitTestList, ['7', '8', '9'])
 
1042
 
 
1043
    # Test that setting invalid defaults raises exceptions
 
1044
    self.assertRaises(flags.IllegalFlagValue,
 
1045
                      FLAGS['UnitTestNumber'].SetDefault, 'oops')
 
1046
    self.assertRaises(flags.IllegalFlagValue,
 
1047
                      FLAGS['UnitTestNumber'].SetDefault, -1)
 
1048
    self.assertRaises(flags.IllegalFlagValue,
 
1049
                      FLAGS['UnitTestBoolFlag'].SetDefault, 'oops')
 
1050
 
 
1051
    self._UndeclareSomeFlags()
 
1052
 
 
1053
  def testMethod_ShortestUniquePrefixes(self):
 
1054
    """
 
1055
    Test FlagValues.ShortestUniquePrefixes
 
1056
    """
 
1057
    flags.DEFINE_string('a', '', '')
 
1058
    flags.DEFINE_string('abc', '', '')
 
1059
    flags.DEFINE_string('common_a_string', '', '')
 
1060
    flags.DEFINE_boolean('common_b_boolean', 0, '')
 
1061
    flags.DEFINE_boolean('common_c_boolean', 0, '')
 
1062
    flags.DEFINE_boolean('common', 0, '')
 
1063
    flags.DEFINE_integer('commonly', 0, '')
 
1064
    flags.DEFINE_boolean('zz', 0, '')
 
1065
    flags.DEFINE_integer('nozz', 0, '')
 
1066
 
 
1067
    shorter_flags = FLAGS.ShortestUniquePrefixes(FLAGS.FlagDict())
 
1068
 
 
1069
    expected_results = {'nocommon_b_boolean': 'nocommon_b',
 
1070
                        'common_c_boolean': 'common_c',
 
1071
                        'common_b_boolean': 'common_b',
 
1072
                        'a': 'a',
 
1073
                        'abc': 'ab',
 
1074
                        'zz': 'z',
 
1075
                        'nozz': 'nozz',
 
1076
                        'common_a_string': 'common_a',
 
1077
                        'commonly': 'commonl',
 
1078
                        'nocommon_c_boolean': 'nocommon_c',
 
1079
                        'nocommon': 'nocommon',
 
1080
                        'common': 'common'}
 
1081
 
 
1082
    for name, shorter in expected_results.iteritems():
 
1083
      self.assertEquals(shorter_flags[name], shorter)
 
1084
 
 
1085
    FLAGS.__delattr__('a')
 
1086
    FLAGS.__delattr__('abc')
 
1087
    FLAGS.__delattr__('common_a_string')
 
1088
    FLAGS.__delattr__('common_b_boolean')
 
1089
    FLAGS.__delattr__('common_c_boolean')
 
1090
    FLAGS.__delattr__('common')
 
1091
    FLAGS.__delattr__('commonly')
 
1092
    FLAGS.__delattr__('zz')
 
1093
    FLAGS.__delattr__('nozz')
 
1094
 
 
1095
  def test_twodasharg_first(self):
 
1096
    flags.DEFINE_string("twodash_name", "Bob", "namehelp")
 
1097
    flags.DEFINE_string("twodash_blame", "Rob", "blamehelp")
 
1098
    argv = ('./program',
 
1099
            '--',
 
1100
            '--twodash_name=Harry')
 
1101
    argv = FLAGS(argv)
 
1102
    self.assertEqual('Bob', FLAGS.twodash_name)
 
1103
    self.assertEqual(argv[1], '--twodash_name=Harry')
 
1104
 
 
1105
  def test_twodasharg_middle(self):
 
1106
    flags.DEFINE_string("twodash2_name", "Bob", "namehelp")
 
1107
    flags.DEFINE_string("twodash2_blame", "Rob", "blamehelp")
 
1108
    argv = ('./program',
 
1109
            '--twodash2_blame=Larry',
 
1110
            '--',
 
1111
            '--twodash2_name=Harry')
 
1112
    argv = FLAGS(argv)
 
1113
    self.assertEqual('Bob', FLAGS.twodash2_name)
 
1114
    self.assertEqual('Larry', FLAGS.twodash2_blame)
 
1115
    self.assertEqual(argv[1], '--twodash2_name=Harry')
 
1116
 
 
1117
  def test_onedasharg_first(self):
 
1118
    flags.DEFINE_string("onedash_name", "Bob", "namehelp")
 
1119
    flags.DEFINE_string("onedash_blame", "Rob", "blamehelp")
 
1120
    argv = ('./program',
 
1121
            '-',
 
1122
            '--onedash_name=Harry')
 
1123
    argv = FLAGS(argv)
 
1124
    self.assertEqual(argv[1], '-')
 
1125
    # TODO(csilvers): we should still parse --onedash_name=Harry as a
 
1126
    # flag, but currently we don't (we stop flag processing as soon as
 
1127
    # we see the first non-flag).
 
1128
    # - This requires gnu_getopt from Python 2.3+ see FLAGS.UseGnuGetOpt()
 
1129
 
 
1130
  def test_unrecognized_flags(self):
 
1131
    # Unknown flag --nosuchflag
 
1132
    try:
 
1133
      argv = ('./program', '--nosuchflag', '--name=Bob', 'extra')
 
1134
      FLAGS(argv)
 
1135
      raise AssertionError("Unknown flag exception not raised")
 
1136
    except flags.UnrecognizedFlag, e:
 
1137
      assert e.flagname == 'nosuchflag'
 
1138
 
 
1139
    # Unknown flag -w (short option)
 
1140
    try:
 
1141
      argv = ('./program', '-w', '--name=Bob', 'extra')
 
1142
      FLAGS(argv)
 
1143
      raise AssertionError("Unknown flag exception not raised")
 
1144
    except flags.UnrecognizedFlag, e:
 
1145
      assert e.flagname == 'w'
 
1146
 
 
1147
    # Unknown flag --nosuchflagwithparam=foo
 
1148
    try:
 
1149
      argv = ('./program', '--nosuchflagwithparam=foo', '--name=Bob', 'extra')
 
1150
      FLAGS(argv)
 
1151
      raise AssertionError("Unknown flag exception not raised")
 
1152
    except flags.UnrecognizedFlag, e:
 
1153
      assert e.flagname == 'nosuchflagwithparam'
 
1154
 
 
1155
    # Allow unknown flag --nosuchflag if specified with undefok
 
1156
    argv = ('./program', '--nosuchflag', '--name=Bob',
 
1157
            '--undefok=nosuchflag', 'extra')
 
1158
    argv = FLAGS(argv)
 
1159
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1160
    assert argv[0]=='./program', "program name not preserved"
 
1161
    assert argv[1]=='extra', "extra argument not preserved"
 
1162
 
 
1163
    # Allow unknown flag --noboolflag if undefok=boolflag is specified
 
1164
    argv = ('./program', '--noboolflag', '--name=Bob',
 
1165
            '--undefok=boolflag', 'extra')
 
1166
    argv = FLAGS(argv)
 
1167
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1168
    assert argv[0]=='./program', "program name not preserved"
 
1169
    assert argv[1]=='extra', "extra argument not preserved"
 
1170
 
 
1171
    # But not if the flagname is misspelled:
 
1172
    try:
 
1173
      argv = ('./program', '--nosuchflag', '--name=Bob',
 
1174
              '--undefok=nosuchfla', 'extra')
 
1175
      FLAGS(argv)
 
1176
      raise AssertionError("Unknown flag exception not raised")
 
1177
    except flags.UnrecognizedFlag, e:
 
1178
      assert e.flagname == 'nosuchflag'
 
1179
 
 
1180
    try:
 
1181
      argv = ('./program', '--nosuchflag', '--name=Bob',
 
1182
              '--undefok=nosuchflagg', 'extra')
 
1183
      FLAGS(argv)
 
1184
      raise AssertionError("Unknown flag exception not raised")
 
1185
    except flags.UnrecognizedFlag:
 
1186
      assert e.flagname == 'nosuchflag'
 
1187
 
 
1188
    # Allow unknown short flag -w if specified with undefok
 
1189
    argv = ('./program', '-w', '--name=Bob', '--undefok=w', 'extra')
 
1190
    argv = FLAGS(argv)
 
1191
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1192
    assert argv[0]=='./program', "program name not preserved"
 
1193
    assert argv[1]=='extra', "extra argument not preserved"
 
1194
 
 
1195
    # Allow unknown flag --nosuchflagwithparam=foo if specified
 
1196
    # with undefok
 
1197
    argv = ('./program', '--nosuchflagwithparam=foo', '--name=Bob',
 
1198
            '--undefok=nosuchflagwithparam', 'extra')
 
1199
    argv = FLAGS(argv)
 
1200
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1201
    assert argv[0]=='./program', "program name not preserved"
 
1202
    assert argv[1]=='extra', "extra argument not preserved"
 
1203
 
 
1204
    # Even if undefok specifies multiple flags
 
1205
    argv = ('./program', '--nosuchflag', '-w', '--nosuchflagwithparam=foo',
 
1206
            '--name=Bob',
 
1207
            '--undefok=nosuchflag,w,nosuchflagwithparam',
 
1208
            'extra')
 
1209
    argv = FLAGS(argv)
 
1210
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1211
    assert argv[0]=='./program', "program name not preserved"
 
1212
    assert argv[1]=='extra', "extra argument not preserved"
 
1213
 
 
1214
    # However, not if undefok doesn't specify the flag
 
1215
    try:
 
1216
      argv = ('./program', '--nosuchflag', '--name=Bob',
 
1217
              '--undefok=another_such', 'extra')
 
1218
      FLAGS(argv)
 
1219
      raise AssertionError("Unknown flag exception not raised")
 
1220
    except flags.UnrecognizedFlag, e:
 
1221
      assert e.flagname == 'nosuchflag'
 
1222
 
 
1223
    # Make sure --undefok doesn't mask other option errors.
 
1224
    try:
 
1225
      # Provide an option requiring a parameter but not giving it one.
 
1226
      argv = ('./program', '--undefok=name', '--name')
 
1227
      FLAGS(argv)
 
1228
      raise AssertionError("Missing option parameter exception not raised")
 
1229
    except flags.UnrecognizedFlag:
 
1230
      raise AssertionError("Wrong kind of error exception raised")
 
1231
    except flags.FlagsError:
 
1232
      pass
 
1233
 
 
1234
    # Test --undefok <list>
 
1235
    argv = ('./program', '--nosuchflag', '-w', '--nosuchflagwithparam=foo',
 
1236
            '--name=Bob',
 
1237
            '--undefok',
 
1238
            'nosuchflag,w,nosuchflagwithparam',
 
1239
            'extra')
 
1240
    argv = FLAGS(argv)
 
1241
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1242
    assert argv[0]=='./program', "program name not preserved"
 
1243
    assert argv[1]=='extra', "extra argument not preserved"
 
1244
 
 
1245
  def test_nonglobal_flags(self):
 
1246
    """Test use of non-global FlagValues"""
 
1247
    nonglobal_flags = flags.FlagValues()
 
1248
    flags.DEFINE_string("nonglobal_flag", "Bob", "flaghelp", nonglobal_flags)
 
1249
    argv = ('./program',
 
1250
            '--nonglobal_flag=Mary',
 
1251
            'extra')
 
1252
    argv = nonglobal_flags(argv)
 
1253
    assert len(argv) == 2, "wrong number of arguments pulled"
 
1254
    assert argv[0]=='./program', "program name not preserved"
 
1255
    assert argv[1]=='extra', "extra argument not preserved"
 
1256
    assert nonglobal_flags['nonglobal_flag'].value == 'Mary'
 
1257
 
 
1258
  def test_unrecognized_nonglobal_flags(self):
 
1259
    """Test unrecognized non-global flags"""
 
1260
    nonglobal_flags = flags.FlagValues()
 
1261
    argv = ('./program',
 
1262
            '--nosuchflag')
 
1263
    try:
 
1264
      argv = nonglobal_flags(argv)
 
1265
      raise AssertionError("Unknown flag exception not raised")
 
1266
    except flags.UnrecognizedFlag, e:
 
1267
      assert e.flagname == 'nosuchflag'
 
1268
      pass
 
1269
 
 
1270
    argv = ('./program',
 
1271
            '--nosuchflag',
 
1272
            '--undefok=nosuchflag')
 
1273
 
 
1274
    argv = nonglobal_flags(argv)
 
1275
    assert len(argv) == 1, "wrong number of arguments pulled"
 
1276
    assert argv[0]=='./program', "program name not preserved"
 
1277
 
 
1278
  def test_module_help(self):
 
1279
    """Test ModuleHelp()."""
 
1280
    helpstr = FLAGS.ModuleHelp(module_baz)
 
1281
 
 
1282
    expected_help = "\n" + module_baz.__name__ + ":" + """
 
1283
  --[no]tmod_baz_x: Boolean flag.
 
1284
    (default: 'true')"""
 
1285
 
 
1286
    self.assertMultiLineEqual(expected_help, helpstr)
 
1287
 
 
1288
  def test_main_module_help(self):
 
1289
    """Test MainModuleHelp()."""
 
1290
    helpstr = FLAGS.MainModuleHelp()
 
1291
 
 
1292
    # When this test is invoked on behalf of flags_unittest_2_2,
 
1293
    # the main module has not defined any flags. Since there's
 
1294
    # no easy way to run this script in our test environment
 
1295
    # directly from python2.2, don't bother to test the output
 
1296
    # of MainModuleHelp() in that scenario.
 
1297
    if sys.version.startswith('2.2.'):
 
1298
      return
 
1299
 
 
1300
    expected_help = "\n" + sys.argv[0] + ':' + """
 
1301
  --[no]debug: debughelp
 
1302
    (default: 'false')
 
1303
  -u,--[no]dup1: runhelp d12
 
1304
    (default: 'true')
 
1305
  -u,--[no]dup2: runhelp d22
 
1306
    (default: 'true')
 
1307
  -u,--[no]dup3: runhelp d32
 
1308
    (default: 'true')
 
1309
  --[no]dup4: runhelp d41
 
1310
    (default: 'false')
 
1311
  -?,--[no]help: show this help
 
1312
  --[no]helpshort: show usage only for this module
 
1313
  --[no]helpxml: like --help, but generates XML output
 
1314
  --kwery: <who|what|why|where|when>: ?
 
1315
  --l: how long to be
 
1316
    (default: '9223372032559808512')
 
1317
    (an integer)
 
1318
  --letters: a list of letters
 
1319
    (default: 'a,b,c')
 
1320
    (a comma separated list)
 
1321
  -m,--m_str: string option that can occur multiple times;
 
1322
    repeat this option to specify a list of values
 
1323
    (default: "['def1', 'def2']")
 
1324
  --name: namehelp
 
1325
    (default: 'Bob')
 
1326
  --[no]noexec: boolean flag with no as prefix
 
1327
    (default: 'true')
 
1328
  --numbers: a list of numbers
 
1329
    (default: '1,2,3')
 
1330
    (a comma separated list)
 
1331
  --[no]q: quiet mode
 
1332
    (default: 'true')
 
1333
  --[no]quack: superstring of 'q'
 
1334
    (default: 'false')
 
1335
  -r,--repeat: how many times to repeat (0-5)
 
1336
    (default: '4')
 
1337
    (a non-negative integer)
 
1338
  -s,--s_str: string option that can occur multiple times;
 
1339
    repeat this option to specify a list of values
 
1340
    (default: "['sing1']")
 
1341
  --[no]test0: test boolean parsing
 
1342
  --[no]test1: test boolean parsing
 
1343
  --[no]testget1: test parsing with defaults
 
1344
  --[no]testget2: test parsing with defaults
 
1345
  --[no]testget3: test parsing with defaults
 
1346
  --testget4: test parsing with defaults
 
1347
    (an integer)
 
1348
  --testlist: test lists parsing
 
1349
    (default: '')
 
1350
    (a comma separated list)
 
1351
  --[no]testnone: test boolean parsing
 
1352
  --testspacelist: tests space lists parsing
 
1353
    (default: '')
 
1354
    (a whitespace separated list)
 
1355
  --x: how eXtreme to be
 
1356
    (default: '3')
 
1357
    (an integer)
 
1358
  -z,--[no]zoom1: runhelp z1
 
1359
    (default: 'false')"""
 
1360
 
 
1361
    if not MultiLineEqual(expected_help, helpstr):
 
1362
      self.fail()
 
1363
 
 
1364
  def test_create_flag_errors(self):
 
1365
    # Since the exception classes are exposed, nothing stops users
 
1366
    # from creating their own instances. This test makes sure that
 
1367
    # people modifying the flags module understand that the external
 
1368
    # mechanisms for creating the exceptions should continue to work.
 
1369
    e = flags.FlagsError()
 
1370
    e = flags.FlagsError("message")
 
1371
    e = flags.DuplicateFlag()
 
1372
    e = flags.DuplicateFlag("message")
 
1373
    e = flags.IllegalFlagValue()
 
1374
    e = flags.IllegalFlagValue("message")
 
1375
    e = flags.UnrecognizedFlag()
 
1376
    e = flags.UnrecognizedFlag("message")
 
1377
 
 
1378
  def testFlagValuesDelAttr(self):
 
1379
    """Checks that del FLAGS.flag_id works."""
 
1380
    default_value = 'default value for testFlagValuesDelAttr'
 
1381
    # 1. Declare and delete a flag with no short name.
 
1382
    flags.DEFINE_string('delattr_foo', default_value, 'A simple flag.')
 
1383
    self.assertEquals(FLAGS.delattr_foo, default_value)
 
1384
    flag_obj = FLAGS['delattr_foo']
 
1385
    # We also check that _FlagIsRegistered works as expected :)
 
1386
    self.assertTrue(FLAGS._FlagIsRegistered(flag_obj))
 
1387
    del FLAGS.delattr_foo
 
1388
    self.assertFalse('delattr_foo' in FLAGS.FlagDict())
 
1389
    self.assertFalse(FLAGS._FlagIsRegistered(flag_obj))
 
1390
    # If the previous del FLAGS.delattr_foo did not work properly, the
 
1391
    # next definition will trigger a redefinition error.
 
1392
    flags.DEFINE_integer('delattr_foo', 3, 'A simple flag.')
 
1393
    del FLAGS.delattr_foo
 
1394
 
 
1395
    self.assertFalse('delattr_foo' in FLAGS.RegisteredFlags())
 
1396
 
 
1397
    # 2. Declare and delete a flag with a short name.
 
1398
    flags.DEFINE_string('delattr_bar', default_value, 'flag with short name',
 
1399
                        short_name='x5')
 
1400
    flag_obj = FLAGS['delattr_bar']
 
1401
    self.assertTrue(FLAGS._FlagIsRegistered(flag_obj))
 
1402
    del FLAGS.x5
 
1403
    self.assertTrue(FLAGS._FlagIsRegistered(flag_obj))
 
1404
    del FLAGS.delattr_bar
 
1405
    self.assertFalse(FLAGS._FlagIsRegistered(flag_obj))
 
1406
 
 
1407
    # 3. Just like 2, but del FLAGS.name last
 
1408
    flags.DEFINE_string('delattr_bar', default_value, 'flag with short name',
 
1409
                        short_name='x5')
 
1410
    flag_obj = FLAGS['delattr_bar']
 
1411
    self.assertTrue(FLAGS._FlagIsRegistered(flag_obj))
 
1412
    del FLAGS.delattr_bar
 
1413
    self.assertTrue(FLAGS._FlagIsRegistered(flag_obj))
 
1414
    del FLAGS.x5
 
1415
    self.assertFalse(FLAGS._FlagIsRegistered(flag_obj))
 
1416
 
 
1417
    self.assertFalse('delattr_bar' in FLAGS.RegisteredFlags())
 
1418
    self.assertFalse('x5' in FLAGS.RegisteredFlags())
 
1419
 
 
1420
  def _GetNamesOfDefinedFlags(self, module, flag_values=FLAGS):
 
1421
    """Returns the list of names of flags defined by a module.
 
1422
 
 
1423
    Auxiliary for the testKeyFlags* methods.
 
1424
 
 
1425
    Args:
 
1426
      module: A module object or a string module name.
 
1427
      flag_values: A FlagValues object.
 
1428
 
 
1429
    Returns:
 
1430
      A list of strings.
 
1431
    """
 
1432
    return [f.name for f in flag_values._GetFlagsDefinedByModule(module)]
 
1433
 
 
1434
  def _GetNamesOfKeyFlags(self, module, flag_values=FLAGS):
 
1435
    """Returns the list of names of key flags for a module.
 
1436
 
 
1437
    Auxiliary for the testKeyFlags* methods.
 
1438
 
 
1439
    Args:
 
1440
      module: A module object or a string module name.
 
1441
      flag_values: A FlagValues object.
 
1442
 
 
1443
    Returns:
 
1444
      A list of strings.
 
1445
    """
 
1446
    return [f.name for f in flag_values._GetKeyFlagsForModule(module)]
 
1447
 
 
1448
  def testKeyFlags(self):
 
1449
    # Before starting any testing, make sure no flags are already
 
1450
    # defined for module_foo and module_bar.
 
1451
    self.assertListEqual(self._GetNamesOfKeyFlags(module_foo), [])
 
1452
    self.assertListEqual(self._GetNamesOfKeyFlags(module_bar), [])
 
1453
    self.assertListEqual(self._GetNamesOfDefinedFlags(module_foo), [])
 
1454
    self.assertListEqual(self._GetNamesOfDefinedFlags(module_bar), [])
 
1455
 
 
1456
    try:
 
1457
      # Defines a few flags in module_foo and module_bar.
 
1458
      module_foo.DefineFlags()
 
1459
 
 
1460
      # Part 1. Check that all flags defined by module_foo are key for
 
1461
      # that module, and similarly for module_bar.
 
1462
      for module in [module_foo, module_bar]:
 
1463
        self.assertListEqual(FLAGS._GetFlagsDefinedByModule(module),
 
1464
                             FLAGS._GetKeyFlagsForModule(module))
 
1465
        # Also check that each module defined the expected flags.
 
1466
        self.assertListEqual(self._GetNamesOfDefinedFlags(module),
 
1467
                             module.NamesOfDefinedFlags())
 
1468
 
 
1469
      # Part 2. Check that flags.DECLARE_key_flag works fine.
 
1470
      # Declare that some flags from module_bar are key for
 
1471
      # module_foo.
 
1472
      module_foo.DeclareKeyFlags()
 
1473
 
 
1474
      # Check that module_foo has the expected list of defined flags.
 
1475
      self.assertListEqual(self._GetNamesOfDefinedFlags(module_foo),
 
1476
                           module_foo.NamesOfDefinedFlags())
 
1477
 
 
1478
      # Check that module_foo has the expected list of key flags.
 
1479
      self.assertListEqual(self._GetNamesOfKeyFlags(module_foo),
 
1480
                           module_foo.NamesOfDeclaredKeyFlags())
 
1481
 
 
1482
      # Part 3. Check that flags.ADOPT_module_key_flags works fine.
 
1483
      # Trigger a call to flags.ADOPT_module_key_flags(module_bar)
 
1484
      # inside module_foo.  This should declare a few more key
 
1485
      # flags in module_foo.
 
1486
      module_foo.DeclareExtraKeyFlags()
 
1487
 
 
1488
      # Check that module_foo has the expected list of key flags.
 
1489
      self.assertListEqual(self._GetNamesOfKeyFlags(module_foo),
 
1490
                           module_foo.NamesOfDeclaredKeyFlags() +
 
1491
                           module_foo.NamesOfDeclaredExtraKeyFlags())
 
1492
    finally:
 
1493
      module_foo.RemoveFlags()
 
1494
 
 
1495
  def testKeyFlagsWithNonDefaultFlagValuesObject(self):
 
1496
    # Check that key flags work even when we use a FlagValues object
 
1497
    # that is not the default flags.FLAGS object.  Otherwise, this
 
1498
    # test is similar to testKeyFlags, but it uses only module_bar.
 
1499
    # The other test module (module_foo) uses only the default values
 
1500
    # for the flag_values keyword arguments.  This way, testKeyFlags
 
1501
    # and this method test both the default FlagValues, the explicitly
 
1502
    # specified one, and a mixed usage of the two.
 
1503
 
 
1504
    # A brand-new FlagValues object, to use instead of flags.FLAGS.
 
1505
    fv = flags.FlagValues()
 
1506
 
 
1507
    # Before starting any testing, make sure no flags are already
 
1508
    # defined for module_foo and module_bar.
 
1509
    self.assertListEqual(
 
1510
        self._GetNamesOfKeyFlags(module_bar, flag_values=fv),
 
1511
        [])
 
1512
    self.assertListEqual(
 
1513
        self._GetNamesOfDefinedFlags(module_bar, flag_values=fv),
 
1514
        [])
 
1515
 
 
1516
    module_bar.DefineFlags(flag_values=fv)
 
1517
 
 
1518
    # Check that all flags defined by module_bar are key for that
 
1519
    # module, and that module_bar defined the expected flags.
 
1520
    self.assertListEqual(fv._GetFlagsDefinedByModule(module_bar),
 
1521
                         fv._GetKeyFlagsForModule(module_bar))
 
1522
    self.assertListEqual(
 
1523
        self._GetNamesOfDefinedFlags(module_bar, flag_values=fv),
 
1524
        module_bar.NamesOfDefinedFlags())
 
1525
 
 
1526
    # Pick two flags from module_bar, declare them as key for the
 
1527
    # current (i.e., main) module (via flags.DECLARE_key_flag), and
 
1528
    # check that we get the expected effect.  The important thing is
 
1529
    # that we always use flags_values=fv (instead of the default
 
1530
    # FLAGS).
 
1531
    main_module = flags._GetMainModule()
 
1532
    names_of_flags_defined_by_bar = module_bar.NamesOfDefinedFlags()
 
1533
    flag_name_0 = names_of_flags_defined_by_bar[0]
 
1534
    flag_name_2 = names_of_flags_defined_by_bar[2]
 
1535
 
 
1536
    flags.DECLARE_key_flag(flag_name_0, flag_values=fv)
 
1537
    self.assertListEqual(
 
1538
        self._GetNamesOfKeyFlags(main_module, flag_values=fv),
 
1539
        [flag_name_0])
 
1540
 
 
1541
    flags.DECLARE_key_flag(flag_name_2, flag_values=fv)
 
1542
    self.assertListEqual(
 
1543
        self._GetNamesOfKeyFlags(main_module, flag_values=fv),
 
1544
        [flag_name_0, flag_name_2])
 
1545
 
 
1546
    flags.ADOPT_module_key_flags(module_bar, flag_values=fv)
 
1547
    key_flags = self._GetNamesOfKeyFlags(main_module, flag_values=fv)
 
1548
    # Order is irrelevant; hence, we sort both lists before comparison.
 
1549
    key_flags.sort()
 
1550
    names_of_flags_defined_by_bar.sort()
 
1551
    self.assertListEqual(key_flags, names_of_flags_defined_by_bar)
 
1552
 
 
1553
  def testMainModuleHelpWithKeyFlags(self):
 
1554
    # Similar to test_main_module_help, but this time we make sure to
 
1555
    # declare some key flags.
 
1556
    try:
 
1557
      help_flag_help = (
 
1558
          "  -?,--[no]help: show this help\n"
 
1559
          "  --[no]helpshort: show usage only for this module\n"
 
1560
          "  --[no]helpxml: like --help, but generates XML output"
 
1561
          )
 
1562
 
 
1563
      expected_help = "\n%s:\n%s" % (sys.argv[0], help_flag_help)
 
1564
 
 
1565
      # Safety check that the main module does not declare any flags
 
1566
      # at the beginning of this test.
 
1567
      self.assertMultiLineEqual(expected_help, FLAGS.MainModuleHelp())
 
1568
 
 
1569
      # Define one flag in this main module and some flags in modules
 
1570
      # a and b.  Also declare one flag from module a and one flag
 
1571
      # from module b as key flags for the main module.
 
1572
      flags.DEFINE_integer('main_module_int_fg', 1,
 
1573
                           'Integer flag in the main module.')
 
1574
 
 
1575
      main_module_int_fg_help = (
 
1576
          "  --main_module_int_fg: Integer flag in the main module.\n"
 
1577
          "    (default: '1')\n"
 
1578
          "    (an integer)")
 
1579
 
 
1580
      expected_help += "\n" + main_module_int_fg_help
 
1581
      self.assertMultiLineEqual(expected_help, FLAGS.MainModuleHelp())
 
1582
 
 
1583
      # The following call should be a no-op: any flag declared by a
 
1584
      # module is automatically key for that module.
 
1585
      flags.DECLARE_key_flag('main_module_int_fg')
 
1586
      self.assertMultiLineEqual(expected_help, FLAGS.MainModuleHelp())
 
1587
 
 
1588
      # The definition of a few flags in an imported module should not
 
1589
      # change the main module help.
 
1590
      module_foo.DefineFlags()
 
1591
      self.assertMultiLineEqual(expected_help, FLAGS.MainModuleHelp())
 
1592
 
 
1593
      flags.DECLARE_key_flag('tmod_foo_bool')
 
1594
      tmod_foo_bool_help = (
 
1595
          "  --[no]tmod_foo_bool: Boolean flag from module foo.\n"
 
1596
          "    (default: 'true')")
 
1597
      expected_help += "\n" + tmod_foo_bool_help
 
1598
      self.assertMultiLineEqual(expected_help, FLAGS.MainModuleHelp())
 
1599
 
 
1600
      flags.DECLARE_key_flag('tmod_bar_z')
 
1601
      tmod_bar_z_help = (
 
1602
          "  --[no]tmod_bar_z: Another boolean flag from module bar.\n"
 
1603
          "    (default: 'false')")
 
1604
      # Unfortunately, there is some flag sorting inside
 
1605
      # MainModuleHelp, so we can't keep incrementally extending
 
1606
      # the expected_help string ...
 
1607
      expected_help = ("\n%s:\n%s\n%s\n%s\n%s" %
 
1608
                       (sys.argv[0],
 
1609
                        help_flag_help,
 
1610
                        main_module_int_fg_help,
 
1611
                        tmod_bar_z_help,
 
1612
                        tmod_foo_bool_help))
 
1613
      self.assertMultiLineEqual(FLAGS.MainModuleHelp(), expected_help)
 
1614
 
 
1615
    finally:
 
1616
      # At the end, delete all the flag information we created.
 
1617
      FLAGS.__delattr__('main_module_int_fg')
 
1618
      module_foo.RemoveFlags()
 
1619
 
 
1620
  def test_ADOPT_module_key_flags(self):
 
1621
    # Check that ADOPT_module_key_flags raises an exception when
 
1622
    # called with a module name (as opposed to a module object).
 
1623
    self.assertRaises(flags.FlagsError,
 
1624
                      flags.ADOPT_module_key_flags,
 
1625
                      'google3.pyglib.app')
 
1626
 
 
1627
  def test_GetCallingModule(self):
 
1628
    self.assertEqual(flags._GetCallingModule(), sys.argv[0])
 
1629
    self.assertEqual(
 
1630
        module_foo.GetModuleName(),
 
1631
        'test_module_foo')
 
1632
    self.assertEqual(
 
1633
        module_bar.GetModuleName(),
 
1634
        'test_module_bar')
 
1635
 
 
1636
    # We execute the following exec statements for their side-effect
 
1637
    # (i.e., not raising an error).  They emphasize the case that not
 
1638
    # all code resides in one of the imported modules: Python is a
 
1639
    # really dynamic language, where we can dynamically construct some
 
1640
    # code and execute it.
 
1641
    code = ("import gflags\n"
 
1642
            "module_name = gflags._GetCallingModule()")
 
1643
    exec code
 
1644
 
 
1645
    # Next two exec statements executes code with a global environment
 
1646
    # that is different from the global environment of any imported
 
1647
    # module.
 
1648
    exec code in {}
 
1649
    # vars(self) returns a dictionary corresponding to the symbol
 
1650
    # table of the self object.  dict(...) makes a distinct copy of
 
1651
    # this dictionary, such that any new symbol definition by the
 
1652
    # exec-ed code (e.g., import flags, module_name = ...) does not
 
1653
    # affect the symbol table of self.
 
1654
    exec code in dict(vars(self))
 
1655
 
 
1656
    # Next test is actually more involved: it checks not only that
 
1657
    # _GetCallingModule does not crash inside exec code, it also checks
 
1658
    # that it returns the expected value: the code executed via exec
 
1659
    # code is treated as being executed by the current module.  We
 
1660
    # check it twice: first time by executing exec from the main
 
1661
    # module, second time by executing it from module_bar.
 
1662
    global_dict = {}
 
1663
    exec code in global_dict
 
1664
    self.assertEqual(global_dict['module_name'],
 
1665
                     sys.argv[0])
 
1666
 
 
1667
    global_dict = {}
 
1668
    module_bar.ExecuteCode(code, global_dict)
 
1669
    self.assertEqual(
 
1670
        global_dict['module_name'],
 
1671
        'test_module_bar')
 
1672
 
 
1673
 
 
1674
def main():
 
1675
  unittest.main()
 
1676
 
 
1677
 
 
1678
if __name__ == '__main__':
 
1679
  main()