/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-03-20 00:49:11 UTC
  • mto: This revision was merged to the branch mainline in revision 2366.
  • Revision ID: john@arbash-meinel.com-20070320004911-0qajqnddr3rf9r2e
Simplify the test even further....
Basically, if you have a file deleted as removed, and then you unversion its directory
it deletes all records in the dirblock, not realizing that some of them might
already be marked as removed.

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
29
29
 
30
 
 
31
30
def parse(options, args):
32
31
    parser = option.get_optparser(dict((o.name, o) for o in options))
33
32
    return parser.parse_args(args)
34
33
 
35
 
 
36
34
class OptionTests(TestCase):
37
35
    """Command-line option tests"""
38
36
 
39
37
    def test_parse_args(self):
40
38
        """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'}))
 
39
        eq = self.assertEquals
 
40
        eq(parse_args(cmd_commit(), ['--help']),
 
41
           ([], {'help': True}))
 
42
        eq(parse_args(cmd_commit(), ['--message=biter']),
 
43
           ([], {'message': 'biter'}))
 
44
        ## eq(parse_args(cmd_log(),  '-r 500'.split()),
 
45
        ##   ([], {'revision': RevisionSpec_int(500)}))
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'], {}))
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((['-'], {}), parse_args(cmd_commit(), ['-']))
84
116
 
85
117
    def parse(self, options, args):
86
118
        parser = option.get_optparser(dict((o.name, o) for o in options))
91
123
        opts, args = self.parse(options, ['--no-hello', '--hello'])
92
124
        self.assertEqual(True, opts.hello)
93
125
        opts, args = self.parse(options, [])
94
 
        self.assertFalse(hasattr(opts, 'hello'))
 
126
        self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
95
127
        opts, args = self.parse(options, ['--hello', '--no-hello'])
96
128
        self.assertEqual(False, opts.hello)
97
129
        options = [option.Option('number', type=int)]
102
134
        self.assertRaises(errors.BzrCommandError, self.parse, options,
103
135
                          ['--no-number'])
104
136
 
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
137
    def test_registry_conversion(self):
110
138
        registry = bzrdir.BzrDirFormatRegistry()
111
139
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
136
164
        self.assertRaises(errors.BzrCommandError, self.parse, options,
137
165
                          ['--format', 'two'])
138
166
 
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
167
    def test_registry_converter(self):
152
168
        options = [option.RegistryOption('format', '',
153
169
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
155
171
        self.assertIsInstance(opts.format.repository_format,
156
172
                              knitrepo.RepositoryFormatKnit1)
157
173
 
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
174
    def test_from_kwargs(self):
168
175
        my_option = option.RegistryOption.from_kwargs('my-option',
169
176
            help='test option', short='be short', be_long='go long')
174
181
            be_long='go long', value_switches=True)
175
182
        self.assertEqual(['my-option', 'be-long', 'short'],
176
183
            [x[0] for x in my_option.iter_switches()])
177
 
        self.assertEqual('test option', my_option.help)
178
184
 
179
185
    def test_help(self):
180
186
        registry = bzrdir.BzrDirFormatRegistry()
225
231
                          ('two', None, None, 'two help'),
226
232
                          ])
227
233
 
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
 
 
260
 
class TestListOptions(TestCase):
261
 
    """Tests for ListOption, used to specify lists on the command-line."""
262
 
 
263
 
    def parse(self, options, args):
264
 
        parser = option.get_optparser(dict((o.name, o) for o in options))
265
 
        return parser.parse_args(args)
266
 
 
267
 
    def test_list_option(self):
268
 
        options = [option.ListOption('hello', type=str)]
269
 
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
270
 
        self.assertEqual(['world', 'sailor'], opts.hello)
271
 
 
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
 
    def test_list_option_no_arguments(self):
279
 
        options = [option.ListOption('hello', type=str)]
280
 
        opts, args = self.parse(options, [])
281
 
        self.assertEqual([], opts.hello)
282
 
 
283
 
    def test_list_option_with_int_type(self):
284
 
        options = [option.ListOption('hello', type=int)]
285
 
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
286
 
        self.assertEqual([2, 3], opts.hello)
287
 
 
288
 
    def test_list_option_with_int_type_can_be_reset(self):
289
 
        options = [option.ListOption('hello', type=int)]
290
 
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
291
 
                                          '--hello=-', '--hello=5'])
292
 
        self.assertEqual([5], opts.hello)
293
 
 
294
 
    def test_list_option_can_be_reset(self):
295
 
        """Passing an option of '-' to a list option should reset the list."""
296
 
        options = [option.ListOption('hello', type=str)]
297
 
        opts, args = self.parse(
298
 
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
299
 
        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'])
 
234
#     >>> parse_args('log -r 500'.split())
 
235
#     (['log'], {'revision': [<RevisionSpec_int 500>]})
 
236
#     >>> parse_args('log -r500..600'.split())
 
237
#     (['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
238
#     >>> parse_args('log -vr500..600'.split())
 
239
#     (['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
240
#     >>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
 
241
#     (['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})