/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_options.py

  • Committer: John Arbash Meinel
  • Date: 2007-05-31 20:29:04 UTC
  • mto: This revision was merged to the branch mainline in revision 2499.
  • Revision ID: john@arbash-meinel.com-20070531202904-34h7ygudo7qq9ha1
Update the code so that symlinks aren't cached at incorrect times
and fix the tests so that they don't assume files and symlinks
get cached even when the timestamp doesn't declare them 'safe'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
import re
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
16
 
19
17
from bzrlib import (
 
18
    builtins,
20
19
    bzrdir,
21
 
    commands,
22
20
    errors,
23
21
    option,
 
22
    repository,
 
23
    symbol_versioning,
24
24
    )
25
 
from bzrlib.builtins import cmd_commit
 
25
from bzrlib.builtins import cmd_commit, cmd_log, cmd_status
26
26
from bzrlib.commands import Command, parse_args
27
27
from bzrlib.tests import TestCase
28
28
from bzrlib.repofmt import knitrepo
38
38
 
39
39
    def test_parse_args(self):
40
40
        """Option parser"""
41
 
        # XXX: Using cmd_commit makes these tests overly sensitive to changes
42
 
        # to cmd_commit, when they are meant to be about option parsing in
43
 
        # general.
44
 
        self.assertEqual(parse_args(cmd_commit(), ['--help']),
45
 
           ([], {'author': [], 'exclude': [], 'fixes': [], 'help': True}))
46
 
        self.assertEqual(parse_args(cmd_commit(), ['--message=biter']),
47
 
           ([], {'author': [], 'exclude': [], 'fixes': [], 'message': 'biter'}))
 
41
        eq = self.assertEquals
 
42
        eq(parse_args(cmd_commit(), ['--help']),
 
43
           ([], {'fixes': [], 'help': True}))
 
44
        eq(parse_args(cmd_commit(), ['--message=biter']),
 
45
           ([], {'fixes': [], 'message': 'biter'}))
48
46
 
49
47
    def test_no_more_opts(self):
50
48
        """Terminated options"""
51
 
        self.assertEqual(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
52
 
                          (['-file-with-dashes'], {'author': [], 'exclude': [], 'fixes': []}))
 
49
        self.assertEquals(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
 
50
                          (['-file-with-dashes'], {'fixes': []}))
53
51
 
54
52
    def test_option_help(self):
55
53
        """Options have help strings."""
56
 
        out, err = self.run_bzr('commit --help')
57
 
        self.assertContainsRe(out,
58
 
                r'--file(.|\n)*Take commit message from this file\.')
 
54
        out, err = self.run_bzr_captured(['commit', '--help'])
 
55
        self.assertContainsRe(out, r'--file(.|\n)*file containing commit'
 
56
                                   ' message')
59
57
        self.assertContainsRe(out, r'-h.*--help')
60
58
 
61
59
    def test_option_help_global(self):
62
60
        """Global options have help strings."""
63
 
        out, err = self.run_bzr('help status')
64
 
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
 
61
        out, err = self.run_bzr_captured(['help', 'status'])
 
62
        self.assertContainsRe(out, r'--show-ids.*show internal object')
65
63
 
66
64
    def test_option_arg_help(self):
67
65
        """Help message shows option arguments."""
68
 
        out, err = self.run_bzr('help commit')
69
 
        self.assertEqual(err, '')
 
66
        out, err = self.run_bzr_captured(['help', 'commit'])
 
67
        self.assertEquals(err, '')
70
68
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
71
69
 
72
70
    def test_unknown_short_opt(self):
73
 
        out, err = self.run_bzr('help -r', retcode=3)
 
71
        out, err = self.run_bzr_captured(['help', '-r'], retcode=3)
74
72
        self.assertContainsRe(err, r'no such option')
75
73
 
 
74
    def test_get_short_name(self):
 
75
        file_opt = option.Option.OPTIONS['file']
 
76
        self.assertEquals(file_opt.short_name(), 'F')
 
77
        force_opt = option.Option.OPTIONS['force']
 
78
        self.assertEquals(force_opt.short_name(), None)
 
79
 
76
80
    def test_set_short_name(self):
77
81
        o = option.Option('wiggle')
78
82
        o.set_short_name('w')
79
83
        self.assertEqual(o.short_name(), 'w')
80
84
 
 
85
    def test_old_short_names(self):
 
86
        # test the deprecated method for getting and setting short option
 
87
        # names
 
88
        expected_warning = (
 
89
            "access to SHORT_OPTIONS was deprecated in version 0.14."
 
90
            " Set the short option name when constructing the Option.",
 
91
            DeprecationWarning, 2)
 
92
        _warnings = []
 
93
        def capture_warning(message, category, stacklevel=None):
 
94
            _warnings.append((message, category, stacklevel))
 
95
        old_warning_method = symbol_versioning.warn
 
96
        try:
 
97
            # an example of the kind of thing plugins might want to do through
 
98
            # the old interface - make a new option and then give it a short
 
99
            # name.
 
100
            symbol_versioning.set_warning_method(capture_warning)
 
101
            example_opt = option.Option('example', help='example option')
 
102
            option.Option.SHORT_OPTIONS['w'] = example_opt
 
103
            self.assertEqual(example_opt.short_name(), 'w')
 
104
            self.assertEqual([expected_warning], _warnings)
 
105
            # now check that it can actually be parsed with the registered
 
106
            # value
 
107
            opts, args = parse([example_opt], ['-w', 'foo'])
 
108
            self.assertEqual(opts.example, True)
 
109
            self.assertEqual(args, ['foo'])
 
110
        finally:
 
111
            symbol_versioning.set_warning_method(old_warning_method)
 
112
 
81
113
    def test_allow_dash(self):
82
114
        """Test that we can pass a plain '-' as an argument."""
83
 
        self.assertEqual((['-']), parse_args(cmd_commit(), ['-'])[0])
 
115
        self.assertEqual(
 
116
            (['-'], {'fixes': []}), parse_args(cmd_commit(), ['-']))
84
117
 
85
118
    def parse(self, options, args):
86
119
        parser = option.get_optparser(dict((o.name, o) for o in options))
91
124
        opts, args = self.parse(options, ['--no-hello', '--hello'])
92
125
        self.assertEqual(True, opts.hello)
93
126
        opts, args = self.parse(options, [])
94
 
        self.assertFalse(hasattr(opts, 'hello'))
 
127
        self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
95
128
        opts, args = self.parse(options, ['--hello', '--no-hello'])
96
129
        self.assertEqual(False, opts.hello)
97
130
        options = [option.Option('number', type=int)]
102
135
        self.assertRaises(errors.BzrCommandError, self.parse, options,
103
136
                          ['--no-number'])
104
137
 
105
 
    def test_is_hidden(self):
106
 
        self.assertTrue(option.Option('foo', hidden=True).is_hidden('foo'))
107
 
        self.assertFalse(option.Option('foo', hidden=False).is_hidden('foo'))
108
 
 
109
138
    def test_registry_conversion(self):
110
139
        registry = bzrdir.BzrDirFormatRegistry()
111
140
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
136
165
        self.assertRaises(errors.BzrCommandError, self.parse, options,
137
166
                          ['--format', 'two'])
138
167
 
139
 
    def test_override(self):
140
 
        options = [option.Option('hello', type=str),
141
 
                   option.Option('hi', type=str, param_name='hello')]
142
 
        opts, args = self.parse(options, ['--hello', 'a', '--hello', 'b'])
143
 
        self.assertEqual('b', opts.hello)
144
 
        opts, args = self.parse(options, ['--hello', 'b', '--hello', 'a'])
145
 
        self.assertEqual('a', opts.hello)
146
 
        opts, args = self.parse(options, ['--hello', 'a', '--hi', 'b'])
147
 
        self.assertEqual('b', opts.hello)
148
 
        opts, args = self.parse(options, ['--hi', 'b', '--hello', 'a'])
149
 
        self.assertEqual('a', opts.hello)
150
 
 
151
168
    def test_registry_converter(self):
152
169
        options = [option.RegistryOption('format', '',
153
170
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
155
172
        self.assertIsInstance(opts.format.repository_format,
156
173
                              knitrepo.RepositoryFormatKnit1)
157
174
 
158
 
    def test_lazy_registry(self):
159
 
        options = [option.RegistryOption('format', '',
160
 
                   lazy_registry=('bzrlib.bzrdir','format_registry'),
161
 
                   converter=str)]
162
 
        opts, args = self.parse(options, ['--format', 'knit'])
163
 
        self.assertEqual({'format': 'knit'}, opts)
164
 
        self.assertRaises(
165
 
            errors.BadOptionValue, self.parse, options, ['--format', 'BAD'])
166
 
 
167
175
    def test_from_kwargs(self):
168
176
        my_option = option.RegistryOption.from_kwargs('my-option',
169
177
            help='test option', short='be short', be_long='go long')
174
182
            be_long='go long', value_switches=True)
175
183
        self.assertEqual(['my-option', 'be-long', 'short'],
176
184
            [x[0] for x in my_option.iter_switches()])
177
 
        self.assertEqual('test option', my_option.help)
178
185
 
179
186
    def test_help(self):
180
187
        registry = bzrdir.BzrDirFormatRegistry()
225
232
                          ('two', None, None, 'two help'),
226
233
                          ])
227
234
 
228
 
    def test_option_callback_bool(self):
229
 
        "Test booleans get True and False passed correctly to a callback."""
230
 
        cb_calls = []
231
 
        def cb(option, name, value, parser):
232
 
            cb_calls.append((option,name,value,parser))
233
 
        options = [option.Option('hello', custom_callback=cb)]
234
 
        opts, args = self.parse(options, ['--hello', '--no-hello'])
235
 
        self.assertEqual(2, len(cb_calls))
236
 
        opt,name,value,parser = cb_calls[0]
237
 
        self.assertEqual('hello', name)
238
 
        self.assertTrue(value)
239
 
        opt,name,value,parser = cb_calls[1]
240
 
        self.assertEqual('hello', name)
241
 
        self.assertFalse(value)
242
 
 
243
 
    def test_option_callback_str(self):
244
 
        """Test callbacks work for string options both long and short."""
245
 
        cb_calls = []
246
 
        def cb(option, name, value, parser):
247
 
            cb_calls.append((option,name,value,parser))
248
 
        options = [option.Option('hello', type=str, custom_callback=cb,
249
 
            short_name='h')]
250
 
        opts, args = self.parse(options, ['--hello', 'world', '-h', 'mars'])
251
 
        self.assertEqual(2, len(cb_calls))
252
 
        opt,name,value,parser = cb_calls[0]
253
 
        self.assertEqual('hello', name)
254
 
        self.assertEqual('world', value)
255
 
        opt,name,value,parser = cb_calls[1]
256
 
        self.assertEqual('hello', name)
257
 
        self.assertEqual('mars', value)
258
 
 
259
235
 
260
236
class TestListOptions(TestCase):
261
237
    """Tests for ListOption, used to specify lists on the command-line."""
269
245
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
270
246
        self.assertEqual(['world', 'sailor'], opts.hello)
271
247
 
272
 
    def test_list_option_with_dash(self):
273
 
        options = [option.ListOption('with-dash', type=str)]
274
 
        opts, args = self.parse(options, ['--with-dash=world',
275
 
                                          '--with-dash=sailor'])
276
 
        self.assertEqual(['world', 'sailor'], opts.with_dash)
277
 
 
278
248
    def test_list_option_no_arguments(self):
279
249
        options = [option.ListOption('hello', type=str)]
280
250
        opts, args = self.parse(options, [])
297
267
        opts, args = self.parse(
298
268
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
299
269
        self.assertEqual(['c'], opts.hello)
300
 
 
301
 
    def test_option_callback_list(self):
302
 
        """Test callbacks work for list options."""
303
 
        cb_calls = []
304
 
        def cb(option, name, value, parser):
305
 
            # Note that the value is a reference so copy to keep it
306
 
            cb_calls.append((option,name,value[:],parser))
307
 
        options = [option.ListOption('hello', type=str, custom_callback=cb)]
308
 
        opts, args = self.parse(options, ['--hello=world', '--hello=mars',
309
 
            '--hello=-'])
310
 
        self.assertEqual(3, len(cb_calls))
311
 
        opt,name,value,parser = cb_calls[0]
312
 
        self.assertEqual('hello', name)
313
 
        self.assertEqual(['world'], value)
314
 
        opt,name,value,parser = cb_calls[1]
315
 
        self.assertEqual('hello', name)
316
 
        self.assertEqual(['world', 'mars'], value)
317
 
        opt,name,value,parser = cb_calls[2]
318
 
        self.assertEqual('hello', name)
319
 
        self.assertEqual([], value)
320
 
 
321
 
    def test_list_option_param_name(self):
322
 
        """Test list options can have their param_name set."""
323
 
        options = [option.ListOption('hello', type=str, param_name='greeting')]
324
 
        opts, args = self.parse(
325
 
            options, ['--hello=world', '--hello=sailor'])
326
 
        self.assertEqual(['world', 'sailor'], opts.greeting)
327
 
 
328
 
 
329
 
class TestOptionDefinitions(TestCase):
330
 
    """Tests for options in the Bazaar codebase."""
331
 
 
332
 
    def get_builtin_command_options(self):
333
 
        g = []
334
 
        for cmd_name in sorted(commands.all_command_names()):
335
 
            cmd = commands.get_cmd_object(cmd_name)
336
 
            for opt_name, opt in sorted(cmd.options().items()):
337
 
                g.append((cmd_name, opt))
338
 
        return g
339
 
 
340
 
    def test_global_options_used(self):
341
 
        # In the distant memory, options could only be declared globally.  Now
342
 
        # we prefer to declare them in the command, unless like -r they really
343
 
        # are used very widely with the exact same meaning.  So this checks
344
 
        # for any that should be garbage collected.
345
 
        g = dict(option.Option.OPTIONS.items())
346
 
        used_globals = {}
347
 
        msgs = []
348
 
        for cmd_name in sorted(commands.all_command_names()):
349
 
            cmd = commands.get_cmd_object(cmd_name)
350
 
            for option_or_name in sorted(cmd.takes_options):
351
 
                if not isinstance(option_or_name, basestring):
352
 
                    self.assertIsInstance(option_or_name, option.Option)
353
 
                elif not option_or_name in g:
354
 
                    msgs.append("apparent reference to undefined "
355
 
                        "global option %r from %r"
356
 
                        % (option_or_name, cmd))
357
 
                else:
358
 
                    used_globals.setdefault(option_or_name, []).append(cmd_name)
359
 
        unused_globals = set(g.keys()) - set(used_globals.keys())
360
 
        # not enforced because there might be plugins that use these globals
361
 
        ## for option_name in sorted(unused_globals):
362
 
        ##    msgs.append("unused global option %r" % option_name)
363
 
        ## for option_name, cmds in sorted(used_globals.items()):
364
 
        ##     if len(cmds) <= 1:
365
 
        ##         msgs.append("global option %r is only used by %r"
366
 
        ##                 % (option_name, cmds))
367
 
        if msgs:
368
 
            self.fail("problems with global option definitions:\n"
369
 
                    + '\n'.join(msgs))
370
 
 
371
 
    def test_option_grammar(self):
372
 
        msgs = []
373
 
        # Option help should be written in sentence form, and have a final
374
 
        # period and be all on a single line, because the display code will
375
 
        # wrap it.
376
 
        option_re = re.compile(r'^[A-Z][^\n]+\.$')
377
 
        for scope, opt in self.get_builtin_command_options():
378
 
            if not opt.help:
379
 
                msgs.append('%-16s %-16s %s' %
380
 
                       ((scope or 'GLOBAL'), opt.name, 'NO HELP'))
381
 
            elif not option_re.match(opt.help):
382
 
                msgs.append('%-16s %-16s %s' %
383
 
                        ((scope or 'GLOBAL'), opt.name, opt.help))
384
 
        if msgs:
385
 
            self.fail("The following options don't match the style guide:\n"
386
 
                    + '\n'.join(msgs))
387
 
 
388
 
    def test_is_hidden(self):
389
 
        registry = bzrdir.BzrDirFormatRegistry()
390
 
        registry.register_metadir('hidden', 'HiddenFormat',
391
 
            'hidden help text', hidden=True)
392
 
        registry.register_metadir('visible', 'VisibleFormat',
393
 
            'visible help text', hidden=False)
394
 
        format = option.RegistryOption('format', '', registry, str)
395
 
        self.assertTrue(format.is_hidden('hidden'))
396
 
        self.assertFalse(format.is_hidden('visible'))
397
 
 
398
 
    def test_option_custom_help(self):
399
 
        the_opt = option.Option.OPTIONS['help']
400
 
        orig_help = the_opt.help[:]
401
 
        my_opt = option.custom_help('help', 'suggest lottery numbers')
402
 
        # Confirm that my_opt has my help and the original is unchanged
403
 
        self.assertEqual('suggest lottery numbers', my_opt.help)
404
 
        self.assertEqual(orig_help, the_opt.help)
405
 
 
406
 
 
407
 
class TestVerboseQuietLinkage(TestCase):
408
 
 
409
 
    def check(self, parser, level, args):
410
 
        option._verbosity_level = 0
411
 
        opts, args = parser.parse_args(args)
412
 
        self.assertEqual(level, option._verbosity_level)
413
 
 
414
 
    def test_verbose_quiet_linkage(self):
415
 
        parser = option.get_optparser(option.Option.STD_OPTIONS)
416
 
        self.check(parser, 0, [])
417
 
        self.check(parser, 1, ['-v'])
418
 
        self.check(parser, 2, ['-v', '-v'])
419
 
        self.check(parser, -1, ['-q'])
420
 
        self.check(parser, -2, ['-qq'])
421
 
        self.check(parser, -1, ['-v', '-v', '-q'])
422
 
        self.check(parser, 2, ['-q', '-v', '-v'])
423
 
        self.check(parser, 0, ['--no-verbose'])
424
 
        self.check(parser, 0, ['-v', '-q', '--no-quiet'])