/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
16
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
17
import re
18
2221.4.1 by Aaron Bentley
Get registry options working
19
from bzrlib import (
20
    bzrdir,
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
21
    commands,
2221.4.1 by Aaron Bentley
Get registry options working
22
    errors,
23
    option,
24
    )
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
25
from bzrlib.builtins import cmd_commit
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
26
from bzrlib.commands import Command, parse_args
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
27
from bzrlib.tests import TestCase
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
28
from bzrlib.repofmt import knitrepo
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
29
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
30
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
31
def parse(options, args):
32
    parser = option.get_optparser(dict((o.name, o) for o in options))
33
    return parser.parse_args(args)
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
34
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
35
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
36
class OptionTests(TestCase):
37
    """Command-line option tests"""
38
39
    def test_parse_args(self):
40
        """Option parser"""
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
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
           ([], {'exclude': [], 'fixes': [], 'help': True}))
46
        self.assertEqual(parse_args(cmd_commit(), ['--message=biter']),
47
           ([], {'exclude': [], 'fixes': [], 'message': 'biter'}))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
48
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
49
    def test_no_more_opts(self):
50
        """Terminated options"""
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
51
        self.assertEqual(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
52
                          (['-file-with-dashes'], {'exclude': [], 'fixes': []}))
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
53
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
54
    def test_option_help(self):
55
        """Options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
56
        out, err = self.run_bzr('commit --help')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
57
        self.assertContainsRe(out,
58
                r'--file(.|\n)*Take commit message from this file\.')
1857.1.12 by Aaron Bentley
Fix a bunch of test cases that assumed --merge-type or log-format
59
        self.assertContainsRe(out, r'-h.*--help')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
60
61
    def test_option_help_global(self):
62
        """Global options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
63
        out, err = self.run_bzr('help status')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
64
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
65
66
    def test_option_arg_help(self):
67
        """Help message shows option arguments."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
68
        out, err = self.run_bzr('help commit')
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
69
        self.assertEqual(err, '')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
70
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
71
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
72
    def test_unknown_short_opt(self):
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
73
        out, err = self.run_bzr('help -r', retcode=3)
1857.1.1 by Aaron Bentley
Use optparse for parsing options
74
        self.assertContainsRe(err, r'no such option')
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
75
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
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
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
81
    def test_allow_dash(self):
82
        """Test that we can pass a plain '-' as an argument."""
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
83
        self.assertEqual((['-']), parse_args(cmd_commit(), ['-'])[0])
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
84
2221.4.1 by Aaron Bentley
Get registry options working
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)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
88
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
89
    def test_conversion(self):
90
        options = [option.Option('hello')]
2221.4.1 by Aaron Bentley
Get registry options working
91
        opts, args = self.parse(options, ['--no-hello', '--hello'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
92
        self.assertEqual(True, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
93
        opts, args = self.parse(options, [])
2768.1.6 by Ian Clatworthy
Fix existing option and help tests
94
        self.assertFalse(hasattr(opts, 'hello'))
2221.4.1 by Aaron Bentley
Get registry options working
95
        opts, args = self.parse(options, ['--hello', '--no-hello'])
1857.1.22 by Aaron Bentley
Negations set value to False, instead of Optparser.DEFAULT_VALUE
96
        self.assertEqual(False, opts.hello)
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
97
        options = [option.Option('number', type=int)]
2221.4.1 by Aaron Bentley
Get registry options working
98
        opts, args = self.parse(options, ['--number', '6'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
99
        self.assertEqual(6, opts.number)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
100
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
101
                          ['--number'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
102
        self.assertRaises(errors.BzrCommandError, self.parse, options,
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
103
                          ['--no-number'])
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
104
2221.4.1 by Aaron Bentley
Get registry options working
105
    def test_registry_conversion(self):
106
        registry = bzrdir.BzrDirFormatRegistry()
107
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
108
        registry.register_metadir('two', 'RepositoryFormatKnit1', 'two help')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
109
        registry.register_metadir('hidden', 'RepositoryFormatKnit1',
110
            'two help', hidden=True)
2221.4.1 by Aaron Bentley
Get registry options working
111
        registry.set_default('one')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
112
        options = [option.RegistryOption('format', '', registry, str)]
2221.4.1 by Aaron Bentley
Get registry options working
113
        opts, args = self.parse(options, ['--format', 'one'])
114
        self.assertEqual({'format':'one'}, opts)
115
        opts, args = self.parse(options, ['--format', 'two'])
116
        self.assertEqual({'format':'two'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
117
        self.assertRaises(errors.BadOptionValue, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
118
                          ['--format', 'three'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
119
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
120
                          ['--two'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
121
        options = [option.RegistryOption('format', '', registry, str,
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
122
                   value_switches=True)]
2221.4.1 by Aaron Bentley
Get registry options working
123
        opts, args = self.parse(options, ['--two'])
124
        self.assertEqual({'format':'two'}, opts)
125
        opts, args = self.parse(options, ['--two', '--one'])
126
        self.assertEqual({'format':'one'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
127
        opts, args = self.parse(options, ['--two', '--one',
2221.4.1 by Aaron Bentley
Get registry options working
128
                                          '--format', 'two'])
129
        self.assertEqual({'format':'two'}, opts)
1551.12.18 by Aaron Bentley
Allow RegistryOption to omit the value-taking option
130
        options = [option.RegistryOption('format', '', registry, str,
131
                   enum_switch=False)]
132
        self.assertRaises(errors.BzrCommandError, self.parse, options,
133
                          ['--format', 'two'])
2221.4.1 by Aaron Bentley
Get registry options working
134
2745.4.2 by Lukáš Lalinsky
Allow options to be stored in attributes that differ from their 'name' and use this to let '--change' and '--revision' to override each other.
135
    def test_override(self):
136
        options = [option.Option('hello', type=str),
137
                   option.Option('hi', type=str, param_name='hello')]
138
        opts, args = self.parse(options, ['--hello', 'a', '--hello', 'b'])
139
        self.assertEqual('b', opts.hello)
140
        opts, args = self.parse(options, ['--hello', 'b', '--hello', 'a'])
141
        self.assertEqual('a', opts.hello)
142
        opts, args = self.parse(options, ['--hello', 'a', '--hi', 'b'])
143
        self.assertEqual('b', opts.hello)
144
        opts, args = self.parse(options, ['--hi', 'b', '--hello', 'a'])
145
        self.assertEqual('a', opts.hello)
146
2221.4.1 by Aaron Bentley
Get registry options working
147
    def test_registry_converter(self):
2221.4.9 by Aaron Bentley
Zap trailing whitespace
148
        options = [option.RegistryOption('format', '',
2204.5.5 by Aaron Bentley
Remove RepositoryFormat.set_default_format, deprecate get_format_type
149
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
2221.4.1 by Aaron Bentley
Get registry options working
150
        opts, args = self.parse(options, ['--format', 'knit'])
151
        self.assertIsInstance(opts.format.repository_format,
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
152
                              knitrepo.RepositoryFormatKnit1)
2221.4.1 by Aaron Bentley
Get registry options working
153
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
154
    def test_from_kwargs(self):
155
        my_option = option.RegistryOption.from_kwargs('my-option',
156
            help='test option', short='be short', be_long='go long')
157
        self.assertEqual(['my-option'],
158
            [x[0] for x in my_option.iter_switches()])
159
        my_option = option.RegistryOption.from_kwargs('my-option',
160
            help='test option', title="My option", short='be short',
161
            be_long='go long', value_switches=True)
162
        self.assertEqual(['my-option', 'be-long', 'short'],
163
            [x[0] for x in my_option.iter_switches()])
2681.1.5 by Aaron Bentley
Display correct help message in from_kwargs
164
        self.assertEqual('test option', my_option.help)
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
165
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
166
    def test_help(self):
167
        registry = bzrdir.BzrDirFormatRegistry()
168
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
169
        registry.register_metadir('two',
170
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
171
            'two help',
172
            )
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
173
        registry.register_metadir('hidden', 'RepositoryFormat7', 'hidden help',
174
            hidden=True)
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
175
        registry.set_default('one')
176
        options = [option.RegistryOption('format', 'format help', registry,
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
177
                   str, value_switches=True, title='Formats')]
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
178
        parser = option.get_optparser(dict((o.name, o) for o in options))
179
        value = parser.format_option_help()
180
        self.assertContainsRe(value, 'format.*format help')
181
        self.assertContainsRe(value, 'one.*one help')
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
182
        self.assertContainsRe(value, 'Formats:\n *--format')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
183
        self.assertNotContainsRe(value, 'hidden help')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
184
1857.1.16 by Aaron Bentley
Add tests for iter_switches
185
    def test_iter_switches(self):
186
        opt = option.Option('hello', help='fg')
187
        self.assertEqual(list(opt.iter_switches()),
188
                         [('hello', None, None, 'fg')])
189
        opt = option.Option('hello', help='fg', type=int)
190
        self.assertEqual(list(opt.iter_switches()),
191
                         [('hello', None, 'ARG', 'fg')])
192
        opt = option.Option('hello', help='fg', type=int, argname='gar')
193
        self.assertEqual(list(opt.iter_switches()),
194
                         [('hello', None, 'GAR', 'fg')])
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
195
        registry = bzrdir.BzrDirFormatRegistry()
196
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
197
        registry.register_metadir('two',
198
                'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
199
                'two help',
200
                )
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
201
        registry.set_default('one')
202
        opt = option.RegistryOption('format', 'format help', registry,
203
                                    value_switches=False)
204
        self.assertEqual(list(opt.iter_switches()),
205
                         [('format', None, 'ARG', 'format help')])
206
        opt = option.RegistryOption('format', 'format help', registry,
207
                                    value_switches=True)
208
        self.assertEqual(list(opt.iter_switches()),
209
                         [('format', None, 'ARG', 'format help'),
2221.4.9 by Aaron Bentley
Zap trailing whitespace
210
                          ('default', None, None, 'one help'),
211
                          ('one', None, None, 'one help'),
212
                          ('two', None, None, 'two help'),
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
213
                          ])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
214
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
215
    def test_option_callback_bool(self):
216
        "Test booleans get True and False passed correctly to a callback."""
217
        cb_calls = []
218
        def cb(option, name, value, parser):
219
            cb_calls.append((option,name,value,parser))
220
        options = [option.Option('hello', custom_callback=cb)]
221
        opts, args = self.parse(options, ['--hello', '--no-hello'])
222
        self.assertEqual(2, len(cb_calls))
223
        opt,name,value,parser = cb_calls[0]
224
        self.assertEqual('hello', name)
225
        self.assertTrue(value)
226
        opt,name,value,parser = cb_calls[1]
227
        self.assertEqual('hello', name)
228
        self.assertFalse(value)
229
230
    def test_option_callback_str(self):
231
        """Test callbacks work for string options both long and short."""
232
        cb_calls = []
233
        def cb(option, name, value, parser):
234
            cb_calls.append((option,name,value,parser))
235
        options = [option.Option('hello', type=str, custom_callback=cb,
236
            short_name='h')]
237
        opts, args = self.parse(options, ['--hello', 'world', '-h', 'mars'])
238
        self.assertEqual(2, len(cb_calls))
239
        opt,name,value,parser = cb_calls[0]
240
        self.assertEqual('hello', name)
241
        self.assertEqual('world', value)
242
        opt,name,value,parser = cb_calls[1]
243
        self.assertEqual('hello', name)
244
        self.assertEqual('mars', value)
245
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
246
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
247
class TestListOptions(TestCase):
248
    """Tests for ListOption, used to specify lists on the command-line."""
249
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
250
    def parse(self, options, args):
251
        parser = option.get_optparser(dict((o.name, o) for o in options))
252
        return parser.parse_args(args)
253
254
    def test_list_option(self):
255
        options = [option.ListOption('hello', type=str)]
256
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
257
        self.assertEqual(['world', 'sailor'], opts.hello)
258
3668.2.1 by Vincent Ladeuil
Fix bug #263249 by setting valid default _param_name.
259
    def test_list_option_with_dash(self):
260
        options = [option.ListOption('with-dash', type=str)]
261
        opts, args = self.parse(options, ['--with-dash=world',
262
                                          '--with-dash=sailor'])
263
        self.assertEqual(['world', 'sailor'], opts.with_dash)
264
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
265
    def test_list_option_no_arguments(self):
266
        options = [option.ListOption('hello', type=str)]
267
        opts, args = self.parse(options, [])
268
        self.assertEqual([], opts.hello)
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
269
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
270
    def test_list_option_with_int_type(self):
271
        options = [option.ListOption('hello', type=int)]
272
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
273
        self.assertEqual([2, 3], opts.hello)
274
275
    def test_list_option_with_int_type_can_be_reset(self):
276
        options = [option.ListOption('hello', type=int)]
277
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
278
                                          '--hello=-', '--hello=5'])
279
        self.assertEqual([5], opts.hello)
280
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
281
    def test_list_option_can_be_reset(self):
282
        """Passing an option of '-' to a list option should reset the list."""
283
        options = [option.ListOption('hello', type=str)]
284
        opts, args = self.parse(
285
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
286
        self.assertEqual(['c'], opts.hello)
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
287
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
288
    def test_option_callback_list(self):
289
        """Test callbacks work for list options."""
290
        cb_calls = []
291
        def cb(option, name, value, parser):
292
            # Note that the value is a reference so copy to keep it
293
            cb_calls.append((option,name,value[:],parser))
294
        options = [option.ListOption('hello', type=str, custom_callback=cb)]
295
        opts, args = self.parse(options, ['--hello=world', '--hello=mars',
296
            '--hello=-'])
297
        self.assertEqual(3, len(cb_calls))
298
        opt,name,value,parser = cb_calls[0]
299
        self.assertEqual('hello', name)
300
        self.assertEqual(['world'], value)
301
        opt,name,value,parser = cb_calls[1]
302
        self.assertEqual('hello', name)
303
        self.assertEqual(['world', 'mars'], value)
304
        opt,name,value,parser = cb_calls[2]
305
        self.assertEqual('hello', name)
306
        self.assertEqual([], value)
307
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
308
309
class TestOptionDefinitions(TestCase):
310
    """Tests for options in the Bazaar codebase."""
311
2598.1.14 by Martin Pool
Revert tightening of options api - breaks too many plugins
312
    def get_builtin_command_options(self):
313
        g = []
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
314
        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
315
            cmd = cmd_class()
316
            for opt_name, opt in sorted(cmd.options().items()):
317
                g.append((cmd_name, opt))
318
        return g
319
2598.1.7 by Martin Pool
Add failing test that global options are all used.
320
    def test_global_options_used(self):
321
        # In the distant memory, options could only be declared globally.  Now
322
        # we prefer to declare them in the command, unless like -r they really
323
        # are used very widely with the exact same meaning.  So this checks
324
        # for any that should be garbage collected.
325
        g = dict(option.Option.OPTIONS.items())
2598.1.9 by Martin Pool
Add failing test that global options are used at least twice
326
        used_globals = {}
2598.1.7 by Martin Pool
Add failing test that global options are all used.
327
        msgs = []
328
        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
329
            for option_or_name in sorted(cmd_class.takes_options):
330
                if not isinstance(option_or_name, basestring):
331
                    self.assertIsInstance(option_or_name, option.Option)
332
                elif not option_or_name in g:
333
                    msgs.append("apparent reference to undefined "
334
                        "global option %r from %r"
335
                        % (option_or_name, cmd_class))
336
                else:
2598.1.9 by Martin Pool
Add failing test that global options are used at least twice
337
                    used_globals.setdefault(option_or_name, []).append(cmd_name)
338
        unused_globals = set(g.keys()) - set(used_globals.keys())
2598.1.14 by Martin Pool
Revert tightening of options api - breaks too many plugins
339
        # not enforced because there might be plugins that use these globals
340
        ## for option_name in sorted(unused_globals):
341
        ##    msgs.append("unused global option %r" % option_name)
342
        ## for option_name, cmds in sorted(used_globals.items()):
343
        ##     if len(cmds) <= 1:
344
        ##         msgs.append("global option %r is only used by %r"
345
        ##                 % (option_name, cmds))
2598.1.7 by Martin Pool
Add failing test that global options are all used.
346
        if msgs:
347
            self.fail("problems with global option definitions:\n"
348
                    + '\n'.join(msgs))
349
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
350
    def test_option_grammar(self):
351
        msgs = []
2598.1.2 by Martin Pool
Also check that option help ends in a period, and fix those that don't
352
        # Option help should be written in sentence form, and have a final
353
        # period and be all on a single line, because the display code will
354
        # wrap it.
355
        option_re = re.compile(r'^[A-Z][^\n]+\.$')
2598.1.14 by Martin Pool
Revert tightening of options api - breaks too many plugins
356
        for scope, option in self.get_builtin_command_options():
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
357
            if not option.help:
2598.1.11 by Martin Pool
Insist that all options have a help string and fix those that don't.
358
                msgs.append('%-16s %-16s %s' %
359
                       ((scope or 'GLOBAL'), option.name, 'NO HELP'))
2598.1.7 by Martin Pool
Add failing test that global options are all used.
360
            elif not option_re.match(option.help):
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
361
                msgs.append('%-16s %-16s %s' %
362
                        ((scope or 'GLOBAL'), option.name, option.help))
363
        if msgs:
364
            self.fail("The following options don't match the style guide:\n"
365
                    + '\n'.join(msgs))
1551.18.12 by Aaron Bentley
Man page doesn't list hidden options (#131667)
366
367
    def test_is_hidden(self):
368
        registry = bzrdir.BzrDirFormatRegistry()
1551.18.13 by Aaron Bentley
Update test from review suggestions
369
        registry.register_metadir('hidden', 'HiddenFormat',
370
            'hidden help text', hidden=True)
371
        registry.register_metadir('visible', 'VisibleFormat',
372
            'visible help text', hidden=False)
1551.18.12 by Aaron Bentley
Man page doesn't list hidden options (#131667)
373
        format = option.RegistryOption('format', '', registry, str)
374
        self.assertTrue(format.is_hidden('hidden'))
375
        self.assertFalse(format.is_hidden('visible'))
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
376
377
    def test_option_custom_help(self):
378
        the_opt = option.Option.OPTIONS['help']
379
        orig_help = the_opt.help[:]
380
        my_opt = option.custom_help('help', 'suggest lottery numbers')
381
        # Confirm that my_opt has my help and the original is unchanged
382
        self.assertEqual('suggest lottery numbers', my_opt.help)
383
        self.assertEqual(orig_help, the_opt.help)
384
385
386
class TestVerboseQuietLinkage(TestCase):
387
388
    def check(self, parser, level, args):
389
        option._verbosity_level = 0
390
        opts, args = parser.parse_args(args)
391
        self.assertEqual(level, option._verbosity_level)
392
393
    def test_verbose_quiet_linkage(self):
394
        parser = option.get_optparser(option.Option.STD_OPTIONS)
395
        self.check(parser, 0, [])
396
        self.check(parser, 1, ['-v'])
397
        self.check(parser, 2, ['-v', '-v'])
398
        self.check(parser, -1, ['-q'])
399
        self.check(parser, -2, ['-qq'])
400
        self.check(parser, -1, ['-v', '-v', '-q'])
401
        self.check(parser, 2, ['-q', '-v', '-v'])
402
        self.check(parser, 0, ['--no-verbose'])
403
        self.check(parser, 0, ['-v', '-q', '--no-quiet'])