/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: 2009-06-18 18:18:36 UTC
  • mto: This revision was merged to the branch mainline in revision 4461.
  • Revision ID: john@arbash-meinel.com-20090618181836-biodfkat9a8eyzjz
The new add_inventory_by_delta is returning a CHKInventory when mapping from NULL
Which is completely valid, but 'broke' one of the tests.
So to fix it, changed the test to use CHKInventories on both sides, and add an __eq__
member. The nice thing is that CHKInventory.__eq__ is fairly cheap, since it only
has to check the root keys.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
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
 
18
 
 
19
from bzrlib import (
 
20
    bzrdir,
 
21
    commands,
 
22
    errors,
 
23
    option,
 
24
    )
 
25
from bzrlib.builtins import cmd_commit
 
26
from bzrlib.commands import Command, parse_args
 
27
from bzrlib.tests import TestCase
 
28
from bzrlib.repofmt import knitrepo
 
29
 
 
30
 
 
31
def parse(options, args):
 
32
    parser = option.get_optparser(dict((o.name, o) for o in options))
 
33
    return parser.parse_args(args)
 
34
 
 
35
 
 
36
class OptionTests(TestCase):
 
37
    """Command-line option tests"""
 
38
 
 
39
    def test_parse_args(self):
 
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'}))
 
48
 
 
49
    def test_no_more_opts(self):
 
50
        """Terminated options"""
 
51
        self.assertEqual(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
 
52
                          (['-file-with-dashes'], {'author': [], 'exclude': [], 'fixes': []}))
 
53
 
 
54
    def test_option_help(self):
 
55
        """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\.')
 
59
        self.assertContainsRe(out, r'-h.*--help')
 
60
 
 
61
    def test_option_help_global(self):
 
62
        """Global options have help strings."""
 
63
        out, err = self.run_bzr('help status')
 
64
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
 
65
 
 
66
    def test_option_arg_help(self):
 
67
        """Help message shows option arguments."""
 
68
        out, err = self.run_bzr('help commit')
 
69
        self.assertEqual(err, '')
 
70
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
 
71
 
 
72
    def test_unknown_short_opt(self):
 
73
        out, err = self.run_bzr('help -r', retcode=3)
 
74
        self.assertContainsRe(err, r'no such option')
 
75
 
 
76
    def test_set_short_name(self):
 
77
        o = option.Option('wiggle')
 
78
        o.set_short_name('w')
 
79
        self.assertEqual(o.short_name(), 'w')
 
80
 
 
81
    def test_allow_dash(self):
 
82
        """Test that we can pass a plain '-' as an argument."""
 
83
        self.assertEqual((['-']), parse_args(cmd_commit(), ['-'])[0])
 
84
 
 
85
    def parse(self, options, args):
 
86
        parser = option.get_optparser(dict((o.name, o) for o in options))
 
87
        return parser.parse_args(args)
 
88
 
 
89
    def test_conversion(self):
 
90
        options = [option.Option('hello')]
 
91
        opts, args = self.parse(options, ['--no-hello', '--hello'])
 
92
        self.assertEqual(True, opts.hello)
 
93
        opts, args = self.parse(options, [])
 
94
        self.assertFalse(hasattr(opts, 'hello'))
 
95
        opts, args = self.parse(options, ['--hello', '--no-hello'])
 
96
        self.assertEqual(False, opts.hello)
 
97
        options = [option.Option('number', type=int)]
 
98
        opts, args = self.parse(options, ['--number', '6'])
 
99
        self.assertEqual(6, opts.number)
 
100
        self.assertRaises(errors.BzrCommandError, self.parse, options,
 
101
                          ['--number'])
 
102
        self.assertRaises(errors.BzrCommandError, self.parse, options,
 
103
                          ['--no-number'])
 
104
 
 
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
    def test_registry_conversion(self):
 
110
        registry = bzrdir.BzrDirFormatRegistry()
 
111
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
 
112
        registry.register_metadir('two', 'RepositoryFormatKnit1', 'two help')
 
113
        registry.register_metadir('hidden', 'RepositoryFormatKnit1',
 
114
            'two help', hidden=True)
 
115
        registry.set_default('one')
 
116
        options = [option.RegistryOption('format', '', registry, str)]
 
117
        opts, args = self.parse(options, ['--format', 'one'])
 
118
        self.assertEqual({'format':'one'}, opts)
 
119
        opts, args = self.parse(options, ['--format', 'two'])
 
120
        self.assertEqual({'format':'two'}, opts)
 
121
        self.assertRaises(errors.BadOptionValue, self.parse, options,
 
122
                          ['--format', 'three'])
 
123
        self.assertRaises(errors.BzrCommandError, self.parse, options,
 
124
                          ['--two'])
 
125
        options = [option.RegistryOption('format', '', registry, str,
 
126
                   value_switches=True)]
 
127
        opts, args = self.parse(options, ['--two'])
 
128
        self.assertEqual({'format':'two'}, opts)
 
129
        opts, args = self.parse(options, ['--two', '--one'])
 
130
        self.assertEqual({'format':'one'}, opts)
 
131
        opts, args = self.parse(options, ['--two', '--one',
 
132
                                          '--format', 'two'])
 
133
        self.assertEqual({'format':'two'}, opts)
 
134
        options = [option.RegistryOption('format', '', registry, str,
 
135
                   enum_switch=False)]
 
136
        self.assertRaises(errors.BzrCommandError, self.parse, options,
 
137
                          ['--format', 'two'])
 
138
 
 
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
    def test_registry_converter(self):
 
152
        options = [option.RegistryOption('format', '',
 
153
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
 
154
        opts, args = self.parse(options, ['--format', 'knit'])
 
155
        self.assertIsInstance(opts.format.repository_format,
 
156
                              knitrepo.RepositoryFormatKnit1)
 
157
 
 
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
    def test_from_kwargs(self):
 
168
        my_option = option.RegistryOption.from_kwargs('my-option',
 
169
            help='test option', short='be short', be_long='go long')
 
170
        self.assertEqual(['my-option'],
 
171
            [x[0] for x in my_option.iter_switches()])
 
172
        my_option = option.RegistryOption.from_kwargs('my-option',
 
173
            help='test option', title="My option", short='be short',
 
174
            be_long='go long', value_switches=True)
 
175
        self.assertEqual(['my-option', 'be-long', 'short'],
 
176
            [x[0] for x in my_option.iter_switches()])
 
177
        self.assertEqual('test option', my_option.help)
 
178
 
 
179
    def test_help(self):
 
180
        registry = bzrdir.BzrDirFormatRegistry()
 
181
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
 
182
        registry.register_metadir('two',
 
183
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
184
            'two help',
 
185
            )
 
186
        registry.register_metadir('hidden', 'RepositoryFormat7', 'hidden help',
 
187
            hidden=True)
 
188
        registry.set_default('one')
 
189
        options = [option.RegistryOption('format', 'format help', registry,
 
190
                   str, value_switches=True, title='Formats')]
 
191
        parser = option.get_optparser(dict((o.name, o) for o in options))
 
192
        value = parser.format_option_help()
 
193
        self.assertContainsRe(value, 'format.*format help')
 
194
        self.assertContainsRe(value, 'one.*one help')
 
195
        self.assertContainsRe(value, 'Formats:\n *--format')
 
196
        self.assertNotContainsRe(value, 'hidden help')
 
197
 
 
198
    def test_iter_switches(self):
 
199
        opt = option.Option('hello', help='fg')
 
200
        self.assertEqual(list(opt.iter_switches()),
 
201
                         [('hello', None, None, 'fg')])
 
202
        opt = option.Option('hello', help='fg', type=int)
 
203
        self.assertEqual(list(opt.iter_switches()),
 
204
                         [('hello', None, 'ARG', 'fg')])
 
205
        opt = option.Option('hello', help='fg', type=int, argname='gar')
 
206
        self.assertEqual(list(opt.iter_switches()),
 
207
                         [('hello', None, 'GAR', 'fg')])
 
208
        registry = bzrdir.BzrDirFormatRegistry()
 
209
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
 
210
        registry.register_metadir('two',
 
211
                'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
212
                'two help',
 
213
                )
 
214
        registry.set_default('one')
 
215
        opt = option.RegistryOption('format', 'format help', registry,
 
216
                                    value_switches=False)
 
217
        self.assertEqual(list(opt.iter_switches()),
 
218
                         [('format', None, 'ARG', 'format help')])
 
219
        opt = option.RegistryOption('format', 'format help', registry,
 
220
                                    value_switches=True)
 
221
        self.assertEqual(list(opt.iter_switches()),
 
222
                         [('format', None, 'ARG', 'format help'),
 
223
                          ('default', None, None, 'one help'),
 
224
                          ('one', None, None, 'one help'),
 
225
                          ('two', None, None, 'two help'),
 
226
                          ])
 
227
 
 
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
 
 
322
class TestOptionDefinitions(TestCase):
 
323
    """Tests for options in the Bazaar codebase."""
 
324
 
 
325
    def get_builtin_command_options(self):
 
326
        g = []
 
327
        for cmd_name in sorted(commands.all_command_names()):
 
328
            cmd = commands.get_cmd_object(cmd_name)
 
329
            for opt_name, opt in sorted(cmd.options().items()):
 
330
                g.append((cmd_name, opt))
 
331
        return g
 
332
 
 
333
    def test_global_options_used(self):
 
334
        # In the distant memory, options could only be declared globally.  Now
 
335
        # we prefer to declare them in the command, unless like -r they really
 
336
        # are used very widely with the exact same meaning.  So this checks
 
337
        # for any that should be garbage collected.
 
338
        g = dict(option.Option.OPTIONS.items())
 
339
        used_globals = {}
 
340
        msgs = []
 
341
        for cmd_name in sorted(commands.all_command_names()):
 
342
            cmd = commands.get_cmd_object(cmd_name)
 
343
            for option_or_name in sorted(cmd.takes_options):
 
344
                if not isinstance(option_or_name, basestring):
 
345
                    self.assertIsInstance(option_or_name, option.Option)
 
346
                elif not option_or_name in g:
 
347
                    msgs.append("apparent reference to undefined "
 
348
                        "global option %r from %r"
 
349
                        % (option_or_name, cmd))
 
350
                else:
 
351
                    used_globals.setdefault(option_or_name, []).append(cmd_name)
 
352
        unused_globals = set(g.keys()) - set(used_globals.keys())
 
353
        # not enforced because there might be plugins that use these globals
 
354
        ## for option_name in sorted(unused_globals):
 
355
        ##    msgs.append("unused global option %r" % option_name)
 
356
        ## for option_name, cmds in sorted(used_globals.items()):
 
357
        ##     if len(cmds) <= 1:
 
358
        ##         msgs.append("global option %r is only used by %r"
 
359
        ##                 % (option_name, cmds))
 
360
        if msgs:
 
361
            self.fail("problems with global option definitions:\n"
 
362
                    + '\n'.join(msgs))
 
363
 
 
364
    def test_option_grammar(self):
 
365
        msgs = []
 
366
        # Option help should be written in sentence form, and have a final
 
367
        # period and be all on a single line, because the display code will
 
368
        # wrap it.
 
369
        option_re = re.compile(r'^[A-Z][^\n]+\.$')
 
370
        for scope, opt in self.get_builtin_command_options():
 
371
            if not opt.help:
 
372
                msgs.append('%-16s %-16s %s' %
 
373
                       ((scope or 'GLOBAL'), opt.name, 'NO HELP'))
 
374
            elif not option_re.match(opt.help):
 
375
                msgs.append('%-16s %-16s %s' %
 
376
                        ((scope or 'GLOBAL'), opt.name, opt.help))
 
377
        if msgs:
 
378
            self.fail("The following options don't match the style guide:\n"
 
379
                    + '\n'.join(msgs))
 
380
 
 
381
    def test_is_hidden(self):
 
382
        registry = bzrdir.BzrDirFormatRegistry()
 
383
        registry.register_metadir('hidden', 'HiddenFormat',
 
384
            'hidden help text', hidden=True)
 
385
        registry.register_metadir('visible', 'VisibleFormat',
 
386
            'visible help text', hidden=False)
 
387
        format = option.RegistryOption('format', '', registry, str)
 
388
        self.assertTrue(format.is_hidden('hidden'))
 
389
        self.assertFalse(format.is_hidden('visible'))
 
390
 
 
391
    def test_option_custom_help(self):
 
392
        the_opt = option.Option.OPTIONS['help']
 
393
        orig_help = the_opt.help[:]
 
394
        my_opt = option.custom_help('help', 'suggest lottery numbers')
 
395
        # Confirm that my_opt has my help and the original is unchanged
 
396
        self.assertEqual('suggest lottery numbers', my_opt.help)
 
397
        self.assertEqual(orig_help, the_opt.help)
 
398
 
 
399
 
 
400
class TestVerboseQuietLinkage(TestCase):
 
401
 
 
402
    def check(self, parser, level, args):
 
403
        option._verbosity_level = 0
 
404
        opts, args = parser.parse_args(args)
 
405
        self.assertEqual(level, option._verbosity_level)
 
406
 
 
407
    def test_verbose_quiet_linkage(self):
 
408
        parser = option.get_optparser(option.Option.STD_OPTIONS)
 
409
        self.check(parser, 0, [])
 
410
        self.check(parser, 1, ['-v'])
 
411
        self.check(parser, 2, ['-v', '-v'])
 
412
        self.check(parser, -1, ['-q'])
 
413
        self.check(parser, -2, ['-qq'])
 
414
        self.check(parser, -1, ['-v', '-v', '-q'])
 
415
        self.check(parser, 2, ['-q', '-v', '-v'])
 
416
        self.check(parser, 0, ['--no-verbose'])
 
417
        self.check(parser, 0, ['-v', '-q', '--no-quiet'])