/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
    builtins,
21
    bzrdir,
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
22
    commands,
2221.4.1 by Aaron Bentley
Get registry options working
23
    errors,
24
    option,
25
    repository,
2221.4.8 by Aaron Bentley
Merge bzr.dev
26
    symbol_versioning,
2221.4.1 by Aaron Bentley
Get registry options working
27
    )
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
28
from bzrlib.builtins import cmd_commit, cmd_log, cmd_status
29
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
30
from bzrlib.tests import TestCase
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
31
from bzrlib.repofmt import knitrepo
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
32
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
33
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
34
def parse(options, args):
35
    parser = option.get_optparser(dict((o.name, o) for o in options))
36
    return parser.parse_args(args)
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
37
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
38
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
39
class OptionTests(TestCase):
40
    """Command-line option tests"""
41
42
    def test_parse_args(self):
43
        """Option parser"""
44
        eq = self.assertEquals
45
        eq(parse_args(cmd_commit(), ['--help']),
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
46
           ([], {'fixes': [], 'help': True}))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
47
        eq(parse_args(cmd_commit(), ['--message=biter']),
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
48
           ([], {'fixes': [], 'message': 'biter'}))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
49
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
50
    def test_no_more_opts(self):
51
        """Terminated options"""
52
        self.assertEquals(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
53
                          (['-file-with-dashes'], {'fixes': []}))
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
54
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
55
    def test_option_help(self):
56
        """Options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
57
        out, err = self.run_bzr('commit --help')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
58
        self.assertContainsRe(out,
59
                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
60
        self.assertContainsRe(out, r'-h.*--help')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
61
62
    def test_option_help_global(self):
63
        """Global options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
64
        out, err = self.run_bzr('help status')
2598.1.4 by Martin Pool
Fix up tests for option help cleanups
65
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
66
67
    def test_option_arg_help(self):
68
        """Help message shows option arguments."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
69
        out, err = self.run_bzr('help commit')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
70
        self.assertEquals(err, '')
71
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
72
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
73
    def test_unknown_short_opt(self):
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
74
        out, err = self.run_bzr('help -r', retcode=3)
1857.1.1 by Aaron Bentley
Use optparse for parsing options
75
        self.assertContainsRe(err, r'no such option')
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
76
2190.2.1 by Martin Pool
remove global registration of short options
77
    def test_get_short_name(self):
78
        file_opt = option.Option.OPTIONS['file']
2227.1.1 by mbp at sourcefrog
Back out previous incompatible change: Option.short_name is now again
79
        self.assertEquals(file_opt.short_name(), 'F')
2190.2.1 by Martin Pool
remove global registration of short options
80
        force_opt = option.Option.OPTIONS['force']
2227.1.1 by mbp at sourcefrog
Back out previous incompatible change: Option.short_name is now again
81
        self.assertEquals(force_opt.short_name(), None)
2190.2.1 by Martin Pool
remove global registration of short options
82
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
83
    def test_set_short_name(self):
84
        o = option.Option('wiggle')
85
        o.set_short_name('w')
86
        self.assertEqual(o.short_name(), 'w')
87
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
88
    def test_old_short_names(self):
89
        # test the deprecated method for getting and setting short option
90
        # names
91
        expected_warning = (
92
            "access to SHORT_OPTIONS was deprecated in version 0.14."
93
            " Set the short option name when constructing the Option.",
94
            DeprecationWarning, 2)
95
        _warnings = []
96
        def capture_warning(message, category, stacklevel=None):
97
            _warnings.append((message, category, stacklevel))
98
        old_warning_method = symbol_versioning.warn
99
        try:
100
            # an example of the kind of thing plugins might want to do through
101
            # the old interface - make a new option and then give it a short
102
            # name.
103
            symbol_versioning.set_warning_method(capture_warning)
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
104
            example_opt = option.Option('example', help='example option')
105
            option.Option.SHORT_OPTIONS['w'] = example_opt
106
            self.assertEqual(example_opt.short_name(), 'w')
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
107
            self.assertEqual([expected_warning], _warnings)
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
108
            # now check that it can actually be parsed with the registered
109
            # value
110
            opts, args = parse([example_opt], ['-w', 'foo'])
111
            self.assertEqual(opts.example, True)
112
            self.assertEqual(args, ['foo'])
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
113
        finally:
114
            symbol_versioning.set_warning_method(old_warning_method)
115
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
116
    def test_allow_dash(self):
117
        """Test that we can pass a plain '-' as an argument."""
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
118
        self.assertEqual(
119
            (['-'], {'fixes': []}), parse_args(cmd_commit(), ['-']))
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
120
2221.4.1 by Aaron Bentley
Get registry options working
121
    def parse(self, options, args):
122
        parser = option.get_optparser(dict((o.name, o) for o in options))
123
        return parser.parse_args(args)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
124
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
125
    def test_conversion(self):
126
        options = [option.Option('hello')]
2221.4.1 by Aaron Bentley
Get registry options working
127
        opts, args = self.parse(options, ['--no-hello', '--hello'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
128
        self.assertEqual(True, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
129
        opts, args = self.parse(options, [])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
130
        self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
131
        opts, args = self.parse(options, ['--hello', '--no-hello'])
1857.1.22 by Aaron Bentley
Negations set value to False, instead of Optparser.DEFAULT_VALUE
132
        self.assertEqual(False, opts.hello)
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
133
        options = [option.Option('number', type=int)]
2221.4.1 by Aaron Bentley
Get registry options working
134
        opts, args = self.parse(options, ['--number', '6'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
135
        self.assertEqual(6, opts.number)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
136
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
137
                          ['--number'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
138
        self.assertRaises(errors.BzrCommandError, self.parse, options,
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
139
                          ['--no-number'])
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
140
2221.4.1 by Aaron Bentley
Get registry options working
141
    def test_registry_conversion(self):
142
        registry = bzrdir.BzrDirFormatRegistry()
143
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
144
        registry.register_metadir('two', 'RepositoryFormatKnit1', 'two help')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
145
        registry.register_metadir('hidden', 'RepositoryFormatKnit1',
146
            'two help', hidden=True)
2221.4.1 by Aaron Bentley
Get registry options working
147
        registry.set_default('one')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
148
        options = [option.RegistryOption('format', '', registry, str)]
2221.4.1 by Aaron Bentley
Get registry options working
149
        opts, args = self.parse(options, ['--format', 'one'])
150
        self.assertEqual({'format':'one'}, opts)
151
        opts, args = self.parse(options, ['--format', 'two'])
152
        self.assertEqual({'format':'two'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
153
        self.assertRaises(errors.BadOptionValue, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
154
                          ['--format', 'three'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
155
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
156
                          ['--two'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
157
        options = [option.RegistryOption('format', '', registry, str,
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
158
                   value_switches=True)]
2221.4.1 by Aaron Bentley
Get registry options working
159
        opts, args = self.parse(options, ['--two'])
160
        self.assertEqual({'format':'two'}, opts)
161
        opts, args = self.parse(options, ['--two', '--one'])
162
        self.assertEqual({'format':'one'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
163
        opts, args = self.parse(options, ['--two', '--one',
2221.4.1 by Aaron Bentley
Get registry options working
164
                                          '--format', 'two'])
165
        self.assertEqual({'format':'two'}, opts)
1551.12.18 by Aaron Bentley
Allow RegistryOption to omit the value-taking option
166
        options = [option.RegistryOption('format', '', registry, str,
167
                   enum_switch=False)]
168
        self.assertRaises(errors.BzrCommandError, self.parse, options,
169
                          ['--format', 'two'])
2221.4.1 by Aaron Bentley
Get registry options working
170
171
    def test_registry_converter(self):
2221.4.9 by Aaron Bentley
Zap trailing whitespace
172
        options = [option.RegistryOption('format', '',
2204.5.5 by Aaron Bentley
Remove RepositoryFormat.set_default_format, deprecate get_format_type
173
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
2221.4.1 by Aaron Bentley
Get registry options working
174
        opts, args = self.parse(options, ['--format', 'knit'])
175
        self.assertIsInstance(opts.format.repository_format,
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
176
                              knitrepo.RepositoryFormatKnit1)
2221.4.1 by Aaron Bentley
Get registry options working
177
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
178
    def test_from_kwargs(self):
179
        my_option = option.RegistryOption.from_kwargs('my-option',
180
            help='test option', short='be short', be_long='go long')
181
        self.assertEqual(['my-option'],
182
            [x[0] for x in my_option.iter_switches()])
183
        my_option = option.RegistryOption.from_kwargs('my-option',
184
            help='test option', title="My option", short='be short',
185
            be_long='go long', value_switches=True)
186
        self.assertEqual(['my-option', 'be-long', 'short'],
187
            [x[0] for x in my_option.iter_switches()])
188
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
189
    def test_help(self):
190
        registry = bzrdir.BzrDirFormatRegistry()
191
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
192
        registry.register_metadir('two',
193
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
194
            'two help',
195
            )
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
196
        registry.register_metadir('hidden', 'RepositoryFormat7', 'hidden help',
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')])
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
218
        registry = bzrdir.BzrDirFormatRegistry()
219
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
220
        registry.register_metadir('two',
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
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
238
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
239
class TestListOptions(TestCase):
240
    """Tests for ListOption, used to specify lists on the command-line."""
241
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
242
    def parse(self, options, args):
243
        parser = option.get_optparser(dict((o.name, o) for o in options))
244
        return parser.parse_args(args)
245
246
    def test_list_option(self):
247
        options = [option.ListOption('hello', type=str)]
248
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
249
        self.assertEqual(['world', 'sailor'], opts.hello)
250
251
    def test_list_option_no_arguments(self):
252
        options = [option.ListOption('hello', type=str)]
253
        opts, args = self.parse(options, [])
254
        self.assertEqual([], opts.hello)
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
255
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
256
    def test_list_option_with_int_type(self):
257
        options = [option.ListOption('hello', type=int)]
258
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
259
        self.assertEqual([2, 3], opts.hello)
260
261
    def test_list_option_with_int_type_can_be_reset(self):
262
        options = [option.ListOption('hello', type=int)]
263
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
264
                                          '--hello=-', '--hello=5'])
265
        self.assertEqual([5], opts.hello)
266
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
267
    def test_list_option_can_be_reset(self):
268
        """Passing an option of '-' to a list option should reset the list."""
269
        options = [option.ListOption('hello', type=str)]
270
        opts, args = self.parse(
271
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
272
        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
273
274
275
class TestOptionDefinitions(TestCase):
276
    """Tests for options in the Bazaar codebase."""
277
278
    def get_all_options(self):
279
        """Return a list of all options used by Bazaar, both global and command.
280
        
281
        The list returned contains elements of (scope, option) where 'scope' 
282
        is either None for global options, or a command name.
283
284
        This includes options provided by plugins.
285
        """
286
        g = [(None, opt) for name, opt
287
             in sorted(option.Option.OPTIONS.items())]
288
        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
289
            cmd = cmd_class()
290
            for opt_name, opt in sorted(cmd.options().items()):
291
                g.append((cmd_name, opt))
292
        return g
293
294
    def test_get_all_options(self):
295
        all = self.get_all_options()
296
        self.assertTrue(len(all) > 100,
297
                "too few options found: %r" % all)
298
299
    def test_option_grammar(self):
300
        msgs = []
2598.1.2 by Martin Pool
Also check that option help ends in a period, and fix those that don't
301
        # Option help should be written in sentence form, and have a final
302
        # period and be all on a single line, because the display code will
303
        # wrap it.
304
        option_re = re.compile(r'^[A-Z][^\n]+\.$')
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
305
        for scope, option in self.get_all_options():
306
            if not option.help:
307
                # TODO: Also complain about options that have no help message?
308
                continue
309
            if not option_re.match(option.help):
310
                msgs.append('%-16s %-16s %s' %
311
                        ((scope or 'GLOBAL'), option.name, option.help))
312
        if msgs:
313
            self.fail("The following options don't match the style guide:\n"
314
                    + '\n'.join(msgs))
315
316
    # TODO: Scan for global options that aren't used by any command?
317
    #
318
    # TODO: Check that there are two spaces between sentences.