~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2005-2011 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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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,
5363.2.9 by Jelmer Vernooij
Fix some tests.
22
    controldir,
2221.4.1 by Aaron Bentley
Get registry options working
23
    errors,
24
    option,
5945.1.1 by Martin von Gagern
Allow -s as shorthand for --log-format=short.
25
    registry,
2221.4.1 by Aaron Bentley
Get registry options working
26
    )
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
27
from bzrlib.builtins import cmd_commit
5579.3.1 by Jelmer Vernooij
Remove unused imports.
28
from bzrlib.commands import parse_args
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
29
from bzrlib.tests import TestCase
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
30
from bzrlib.repofmt import knitrepo
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
31
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
32
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
33
def parse(options, args):
34
    parser = option.get_optparser(dict((o.name, o) for o in options))
35
    return parser.parse_args(args)
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
36
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
37
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
38
class OptionTests(TestCase):
39
    """Command-line option tests"""
40
41
    def test_parse_args(self):
42
        """Option parser"""
3602.1.5 by Robert Collins
Fixups for test_options due to the changes to cmd_commit - insta-review by spiv.
43
        # XXX: Using cmd_commit makes these tests overly sensitive to changes
44
        # to cmd_commit, when they are meant to be about option parsing in
45
        # general.
6161.1.1 by Vincent Ladeuil
Allow config options to be overridden from the command line
46
        self.assertEqual(
6161.1.4 by Vincent Ladeuil
Follow the lead of other 'global' options which are not declared in option.py but handled in bzrlib.commands.run_bzr instead.
47
           ([], {'author': [], 'exclude': [], 'fixes': [], 'help': True}),
6161.1.1 by Vincent Ladeuil
Allow config options to be overridden from the command line
48
           parse_args(cmd_commit(), ['--help']))
49
        self.assertEqual(
6161.1.4 by Vincent Ladeuil
Follow the lead of other 'global' options which are not declared in option.py but handled in bzrlib.commands.run_bzr instead.
50
           ([], {'author': [], 'exclude': [], 'fixes': [], 'message': 'biter'}),
6161.1.1 by Vincent Ladeuil
Allow config options to be overridden from the command line
51
           parse_args(cmd_commit(), ['--message=biter']))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
52
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
53
    def test_no_more_opts(self):
54
        """Terminated options"""
6161.1.1 by Vincent Ladeuil
Allow config options to be overridden from the command line
55
        self.assertEqual(
6161.1.4 by Vincent Ladeuil
Follow the lead of other 'global' options which are not declared in option.py but handled in bzrlib.commands.run_bzr instead.
56
            (['-file-with-dashes'], {'author': [], 'exclude': [], 'fixes': []}),
6161.1.1 by Vincent Ladeuil
Allow config options to be overridden from the command line
57
            parse_args(cmd_commit(), ['--', '-file-with-dashes']))
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
58
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
59
    def test_option_help(self):
60
        """Options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
61
        out, err = self.run_bzr('commit --help')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
62
        self.assertContainsRe(out,
63
                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
64
        self.assertContainsRe(out, r'-h.*--help')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
65
66
    def test_option_help_global(self):
67
        """Global options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
68
        out, err = self.run_bzr('help status')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
69
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
70
6171.2.1 by Vincent Ladeuil
Global options respect their hidden attribute
71
    def test_option_help_global_hidden(self):
72
        """Hidden global options have no help strings."""
73
        out, err = self.run_bzr('help log')
74
        self.assertNotContainsRe(out, r'--message')
75
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
76
    def test_option_arg_help(self):
77
        """Help message shows option arguments."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
78
        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.
79
        self.assertEqual(err, '')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
80
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
81
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
82
    def test_unknown_short_opt(self):
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
83
        out, err = self.run_bzr('help -r', retcode=3)
1857.1.1 by Aaron Bentley
Use optparse for parsing options
84
        self.assertContainsRe(err, r'no such option')
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
85
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
86
    def test_set_short_name(self):
87
        o = option.Option('wiggle')
88
        o.set_short_name('w')
89
        self.assertEqual(o.short_name(), 'w')
90
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
91
    def test_allow_dash(self):
92
        """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.
93
        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
94
2221.4.1 by Aaron Bentley
Get registry options working
95
    def parse(self, options, args):
96
        parser = option.get_optparser(dict((o.name, o) for o in options))
97
        return parser.parse_args(args)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
98
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
99
    def test_conversion(self):
100
        options = [option.Option('hello')]
2221.4.1 by Aaron Bentley
Get registry options working
101
        opts, args = self.parse(options, ['--no-hello', '--hello'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
102
        self.assertEqual(True, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
103
        opts, args = self.parse(options, [])
2768.1.6 by Ian Clatworthy
Fix existing option and help tests
104
        self.assertFalse(hasattr(opts, 'hello'))
2221.4.1 by Aaron Bentley
Get registry options working
105
        opts, args = self.parse(options, ['--hello', '--no-hello'])
1857.1.22 by Aaron Bentley
Negations set value to False, instead of Optparser.DEFAULT_VALUE
106
        self.assertEqual(False, opts.hello)
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
107
        options = [option.Option('number', type=int)]
2221.4.1 by Aaron Bentley
Get registry options working
108
        opts, args = self.parse(options, ['--number', '6'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
109
        self.assertEqual(6, opts.number)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
110
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
111
                          ['--number'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
112
        self.assertRaises(errors.BzrCommandError, self.parse, options,
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
113
                          ['--no-number'])
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
114
4251.1.1 by Aaron Bentley
Support hidden options.
115
    def test_is_hidden(self):
116
        self.assertTrue(option.Option('foo', hidden=True).is_hidden('foo'))
117
        self.assertFalse(option.Option('foo', hidden=False).is_hidden('foo'))
118
2221.4.1 by Aaron Bentley
Get registry options working
119
    def test_registry_conversion(self):
5363.2.9 by Jelmer Vernooij
Fix some tests.
120
        registry = controldir.ControlDirFormatRegistry()
121
        bzrdir.register_metadir(registry, 'one', 'RepositoryFormat7', 'one help')
122
        bzrdir.register_metadir(registry, 'two', 'RepositoryFormatKnit1', 'two help')
123
        bzrdir.register_metadir(registry, 'hidden', 'RepositoryFormatKnit1',
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
124
            'two help', hidden=True)
2221.4.1 by Aaron Bentley
Get registry options working
125
        registry.set_default('one')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
126
        options = [option.RegistryOption('format', '', registry, str)]
2221.4.1 by Aaron Bentley
Get registry options working
127
        opts, args = self.parse(options, ['--format', 'one'])
128
        self.assertEqual({'format':'one'}, opts)
129
        opts, args = self.parse(options, ['--format', 'two'])
130
        self.assertEqual({'format':'two'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
131
        self.assertRaises(errors.BadOptionValue, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
132
                          ['--format', 'three'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
133
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
134
                          ['--two'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
135
        options = [option.RegistryOption('format', '', registry, str,
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
136
                   value_switches=True)]
2221.4.1 by Aaron Bentley
Get registry options working
137
        opts, args = self.parse(options, ['--two'])
138
        self.assertEqual({'format':'two'}, opts)
139
        opts, args = self.parse(options, ['--two', '--one'])
140
        self.assertEqual({'format':'one'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
141
        opts, args = self.parse(options, ['--two', '--one',
2221.4.1 by Aaron Bentley
Get registry options working
142
                                          '--format', 'two'])
143
        self.assertEqual({'format':'two'}, opts)
1551.12.18 by Aaron Bentley
Allow RegistryOption to omit the value-taking option
144
        options = [option.RegistryOption('format', '', registry, str,
145
                   enum_switch=False)]
146
        self.assertRaises(errors.BzrCommandError, self.parse, options,
147
                          ['--format', 'two'])
2221.4.1 by Aaron Bentley
Get registry options working
148
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.
149
    def test_override(self):
150
        options = [option.Option('hello', type=str),
151
                   option.Option('hi', type=str, param_name='hello')]
152
        opts, args = self.parse(options, ['--hello', 'a', '--hello', 'b'])
153
        self.assertEqual('b', opts.hello)
154
        opts, args = self.parse(options, ['--hello', 'b', '--hello', 'a'])
155
        self.assertEqual('a', opts.hello)
156
        opts, args = self.parse(options, ['--hello', 'a', '--hi', 'b'])
157
        self.assertEqual('b', opts.hello)
158
        opts, args = self.parse(options, ['--hi', 'b', '--hello', 'a'])
159
        self.assertEqual('a', opts.hello)
160
2221.4.1 by Aaron Bentley
Get registry options working
161
    def test_registry_converter(self):
2221.4.9 by Aaron Bentley
Zap trailing whitespace
162
        options = [option.RegistryOption('format', '',
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
163
                   controldir.format_registry, controldir.format_registry.make_bzrdir)]
2221.4.1 by Aaron Bentley
Get registry options working
164
        opts, args = self.parse(options, ['--format', 'knit'])
165
        self.assertIsInstance(opts.format.repository_format,
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
166
                              knitrepo.RepositoryFormatKnit1)
2221.4.1 by Aaron Bentley
Get registry options working
167
3224.5.34 by Andrew Bennetts
Polish lazy_registry feature a little.
168
    def test_lazy_registry(self):
169
        options = [option.RegistryOption('format', '',
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
170
                   lazy_registry=('bzrlib.controldir','format_registry'),
3224.5.34 by Andrew Bennetts
Polish lazy_registry feature a little.
171
                   converter=str)]
172
        opts, args = self.parse(options, ['--format', 'knit'])
173
        self.assertEqual({'format': 'knit'}, opts)
174
        self.assertRaises(
175
            errors.BadOptionValue, self.parse, options, ['--format', 'BAD'])
176
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
177
    def test_from_kwargs(self):
178
        my_option = option.RegistryOption.from_kwargs('my-option',
179
            help='test option', short='be short', be_long='go long')
180
        self.assertEqual(['my-option'],
181
            [x[0] for x in my_option.iter_switches()])
182
        my_option = option.RegistryOption.from_kwargs('my-option',
183
            help='test option', title="My option", short='be short',
184
            be_long='go long', value_switches=True)
185
        self.assertEqual(['my-option', 'be-long', 'short'],
186
            [x[0] for x in my_option.iter_switches()])
2681.1.5 by Aaron Bentley
Display correct help message in from_kwargs
187
        self.assertEqual('test option', my_option.help)
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
188
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
189
    def test_help(self):
5363.2.9 by Jelmer Vernooij
Fix some tests.
190
        registry = controldir.ControlDirFormatRegistry()
191
        bzrdir.register_metadir(registry, 'one', 'RepositoryFormat7', 'one help')
192
        bzrdir.register_metadir(registry, 'two',
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
193
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
194
            'two help',
195
            )
5363.2.9 by Jelmer Vernooij
Fix some tests.
196
        bzrdir.register_metadir(registry, 'hidden', 'RepositoryFormat7', 'hidden help',
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
197
            hidden=True)
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
198
        registry.set_default('one')
199
        options = [option.RegistryOption('format', 'format help', registry,
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
200
                   str, value_switches=True, title='Formats')]
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
201
        parser = option.get_optparser(dict((o.name, o) for o in options))
202
        value = parser.format_option_help()
203
        self.assertContainsRe(value, 'format.*format help')
204
        self.assertContainsRe(value, 'one.*one help')
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
205
        self.assertContainsRe(value, 'Formats:\n *--format')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
206
        self.assertNotContainsRe(value, 'hidden help')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
207
1857.1.16 by Aaron Bentley
Add tests for iter_switches
208
    def test_iter_switches(self):
209
        opt = option.Option('hello', help='fg')
210
        self.assertEqual(list(opt.iter_switches()),
211
                         [('hello', None, None, 'fg')])
212
        opt = option.Option('hello', help='fg', type=int)
213
        self.assertEqual(list(opt.iter_switches()),
214
                         [('hello', None, 'ARG', 'fg')])
215
        opt = option.Option('hello', help='fg', type=int, argname='gar')
216
        self.assertEqual(list(opt.iter_switches()),
217
                         [('hello', None, 'GAR', 'fg')])
5363.2.9 by Jelmer Vernooij
Fix some tests.
218
        registry = controldir.ControlDirFormatRegistry()
219
        bzrdir.register_metadir(registry, 'one', 'RepositoryFormat7', 'one help')
220
        bzrdir.register_metadir(registry, 'two',
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
221
                'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
222
                'two help',
223
                )
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
224
        registry.set_default('one')
225
        opt = option.RegistryOption('format', 'format help', registry,
226
                                    value_switches=False)
227
        self.assertEqual(list(opt.iter_switches()),
228
                         [('format', None, 'ARG', 'format help')])
229
        opt = option.RegistryOption('format', 'format help', registry,
230
                                    value_switches=True)
231
        self.assertEqual(list(opt.iter_switches()),
232
                         [('format', None, 'ARG', 'format help'),
2221.4.9 by Aaron Bentley
Zap trailing whitespace
233
                          ('default', None, None, 'one help'),
234
                          ('one', None, None, 'one help'),
235
                          ('two', None, None, 'two help'),
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
236
                          ])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
237
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
238
    def test_option_callback_bool(self):
239
        "Test booleans get True and False passed correctly to a callback."""
240
        cb_calls = []
241
        def cb(option, name, value, parser):
242
            cb_calls.append((option,name,value,parser))
243
        options = [option.Option('hello', custom_callback=cb)]
244
        opts, args = self.parse(options, ['--hello', '--no-hello'])
245
        self.assertEqual(2, len(cb_calls))
246
        opt,name,value,parser = cb_calls[0]
247
        self.assertEqual('hello', name)
248
        self.assertTrue(value)
249
        opt,name,value,parser = cb_calls[1]
250
        self.assertEqual('hello', name)
251
        self.assertFalse(value)
252
253
    def test_option_callback_str(self):
254
        """Test callbacks work for string options both long and short."""
255
        cb_calls = []
256
        def cb(option, name, value, parser):
257
            cb_calls.append((option,name,value,parser))
258
        options = [option.Option('hello', type=str, custom_callback=cb,
259
            short_name='h')]
260
        opts, args = self.parse(options, ['--hello', 'world', '-h', 'mars'])
261
        self.assertEqual(2, len(cb_calls))
262
        opt,name,value,parser = cb_calls[0]
263
        self.assertEqual('hello', name)
264
        self.assertEqual('world', value)
265
        opt,name,value,parser = cb_calls[1]
266
        self.assertEqual('hello', name)
267
        self.assertEqual('mars', value)
268
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
269
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
270
class TestListOptions(TestCase):
271
    """Tests for ListOption, used to specify lists on the command-line."""
272
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
273
    def parse(self, options, args):
274
        parser = option.get_optparser(dict((o.name, o) for o in options))
275
        return parser.parse_args(args)
276
277
    def test_list_option(self):
278
        options = [option.ListOption('hello', type=str)]
279
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
280
        self.assertEqual(['world', 'sailor'], opts.hello)
281
3668.2.1 by Vincent Ladeuil
Fix bug #263249 by setting valid default _param_name.
282
    def test_list_option_with_dash(self):
283
        options = [option.ListOption('with-dash', type=str)]
284
        opts, args = self.parse(options, ['--with-dash=world',
285
                                          '--with-dash=sailor'])
286
        self.assertEqual(['world', 'sailor'], opts.with_dash)
287
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
288
    def test_list_option_no_arguments(self):
289
        options = [option.ListOption('hello', type=str)]
290
        opts, args = self.parse(options, [])
291
        self.assertEqual([], opts.hello)
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
292
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
293
    def test_list_option_with_int_type(self):
294
        options = [option.ListOption('hello', type=int)]
295
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
296
        self.assertEqual([2, 3], opts.hello)
297
298
    def test_list_option_with_int_type_can_be_reset(self):
299
        options = [option.ListOption('hello', type=int)]
300
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
301
                                          '--hello=-', '--hello=5'])
302
        self.assertEqual([5], opts.hello)
303
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
304
    def test_list_option_can_be_reset(self):
305
        """Passing an option of '-' to a list option should reset the list."""
306
        options = [option.ListOption('hello', type=str)]
307
        opts, args = self.parse(
308
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
309
        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
310
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
311
    def test_option_callback_list(self):
312
        """Test callbacks work for list options."""
313
        cb_calls = []
314
        def cb(option, name, value, parser):
315
            # Note that the value is a reference so copy to keep it
316
            cb_calls.append((option,name,value[:],parser))
317
        options = [option.ListOption('hello', type=str, custom_callback=cb)]
318
        opts, args = self.parse(options, ['--hello=world', '--hello=mars',
319
            '--hello=-'])
320
        self.assertEqual(3, len(cb_calls))
321
        opt,name,value,parser = cb_calls[0]
322
        self.assertEqual('hello', name)
323
        self.assertEqual(['world'], value)
324
        opt,name,value,parser = cb_calls[1]
325
        self.assertEqual('hello', name)
326
        self.assertEqual(['world', 'mars'], value)
327
        opt,name,value,parser = cb_calls[2]
328
        self.assertEqual('hello', name)
329
        self.assertEqual([], value)
330
3751.1.1 by Martin von Gagern
Handle param_name for ListOption.
331
    def test_list_option_param_name(self):
332
        """Test list options can have their param_name set."""
333
        options = [option.ListOption('hello', type=str, param_name='greeting')]
334
        opts, args = self.parse(
335
            options, ['--hello=world', '--hello=sailor'])
336
        self.assertEqual(['world', 'sailor'], opts.greeting)
337
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
338
339
class TestOptionDefinitions(TestCase):
340
    """Tests for options in the Bazaar codebase."""
341
2598.1.14 by Martin Pool
Revert tightening of options api - breaks too many plugins
342
    def get_builtin_command_options(self):
343
        g = []
6259.2.1 by Martin Packman
Make TestOptionDefinitions actually do something again by reinstalling hooks in test context
344
        commands.install_bzr_command_hooks()
345
        for cmd_name in sorted(commands.builtin_command_names()):
4119.3.8 by Robert Collins
Get missing command support sorted out.
346
            cmd = commands.get_cmd_object(cmd_name)
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
347
            for opt_name, opt in sorted(cmd.options().items()):
348
                g.append((cmd_name, opt))
6259.2.1 by Martin Packman
Make TestOptionDefinitions actually do something again by reinstalling hooks in test context
349
        self.assert_(g)
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
350
        return g
351
352
    def test_option_grammar(self):
353
        msgs = []
2598.1.2 by Martin Pool
Also check that option help ends in a period, and fix those that don't
354
        # Option help should be written in sentence form, and have a final
6259.2.10 by Martin Packman
Allow a bracketed suffix in option help test
355
        # period with an optional bracketed suffix. All the text should be on
356
        # one line, because the display code will wrap it.
357
        option_re = re.compile(r'^[A-Z][^\n]+\.(?: \([^\n]+\))?$')
3755.1.1 by Vincent Ladeuil
Fix --verbose leaking into blackbox tests.
358
        for scope, opt in self.get_builtin_command_options():
6259.2.6 by Martin Packman
Test help strings of registry option value switches as well
359
            for name, _, _, helptxt in opt.iter_switches():
360
                if name != opt.name:
361
                    name = "/".join([opt.name, name])
362
                if not helptxt:
363
                    msgs.append('%-16s %-16s %s' %
364
                           ((scope or 'GLOBAL'), name, 'NO HELP'))
365
                elif not option_re.match(helptxt):
6259.2.7 by Martin Packman
Let format registry help break the rules for now
366
                    if name.startswith("format/"):
367
                        # Don't complain about the odd format registry help
368
                        continue
6259.2.6 by Martin Packman
Test help strings of registry option value switches as well
369
                    msgs.append('%-16s %-16s %s' %
370
                            ((scope or 'GLOBAL'), name, helptxt))
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
371
        if msgs:
372
            self.fail("The following options don't match the style guide:\n"
373
                    + '\n'.join(msgs))
1551.18.12 by Aaron Bentley
Man page doesn't list hidden options (#131667)
374
6259.2.3 by Martin Packman
Split tests methods unrelated to command options to a seperate class
375
376
class TestOptionMisc(TestCase):
377
1551.18.12 by Aaron Bentley
Man page doesn't list hidden options (#131667)
378
    def test_is_hidden(self):
5363.2.9 by Jelmer Vernooij
Fix some tests.
379
        registry = controldir.ControlDirFormatRegistry()
380
        bzrdir.register_metadir(registry, 'hidden', 'HiddenFormat',
1551.18.13 by Aaron Bentley
Update test from review suggestions
381
            'hidden help text', hidden=True)
5363.2.9 by Jelmer Vernooij
Fix some tests.
382
        bzrdir.register_metadir(registry, 'visible', 'VisibleFormat',
1551.18.13 by Aaron Bentley
Update test from review suggestions
383
            'visible help text', hidden=False)
1551.18.12 by Aaron Bentley
Man page doesn't list hidden options (#131667)
384
        format = option.RegistryOption('format', '', registry, str)
385
        self.assertTrue(format.is_hidden('hidden'))
386
        self.assertFalse(format.is_hidden('visible'))
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
387
5574.9.3 by Jelmer Vernooij
Add -F as alias for 'bzr diff -F format'
388
    def test_short_name(self):
389
        registry = controldir.ControlDirFormatRegistry()
390
        opt = option.RegistryOption('format', help='', registry=registry)
391
        self.assertEquals(None, opt.short_name())
392
        opt = option.RegistryOption('format', short_name='F', help='',
393
            registry=registry)
394
        self.assertEquals('F', opt.short_name())
395
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
396
    def test_option_custom_help(self):
397
        the_opt = option.Option.OPTIONS['help']
398
        orig_help = the_opt.help[:]
399
        my_opt = option.custom_help('help', 'suggest lottery numbers')
400
        # Confirm that my_opt has my help and the original is unchanged
401
        self.assertEqual('suggest lottery numbers', my_opt.help)
402
        self.assertEqual(orig_help, the_opt.help)
403
5945.1.1 by Martin von Gagern
Allow -s as shorthand for --log-format=short.
404
    def test_short_value_switches(self):
405
        reg = registry.Registry()
406
        reg.register('short', 'ShortChoice')
407
        reg.register('long', 'LongChoice')
408
        ropt = option.RegistryOption('choice', '', reg, value_switches=True,
409
            short_value_switches={'short': 's'})
410
        opts, args = parse([ropt], ['--short'])
411
        self.assertEqual('ShortChoice', opts.choice)
412
        opts, args = parse([ropt], ['-s'])
413
        self.assertEqual('ShortChoice', opts.choice)
414
2768.1.11 by Ian Clatworthy
Add new option tests for custom help, callbacks and verbose/quiet linkage
415
416
class TestVerboseQuietLinkage(TestCase):
417
418
    def check(self, parser, level, args):
419
        option._verbosity_level = 0
420
        opts, args = parser.parse_args(args)
421
        self.assertEqual(level, option._verbosity_level)
422
423
    def test_verbose_quiet_linkage(self):
424
        parser = option.get_optparser(option.Option.STD_OPTIONS)
425
        self.check(parser, 0, [])
426
        self.check(parser, 1, ['-v'])
427
        self.check(parser, 2, ['-v', '-v'])
428
        self.check(parser, -1, ['-q'])
429
        self.check(parser, -2, ['-qq'])
430
        self.check(parser, -1, ['-v', '-v', '-q'])
431
        self.check(parser, 2, ['-q', '-v', '-v'])
432
        self.check(parser, 0, ['--no-verbose'])
433
        self.check(parser, 0, ['-v', '-q', '--no-quiet'])