~bzr-pqm/bzr/bzr.dev

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
2221.4.1 by Aaron Bentley
Get registry options working
17
from bzrlib import (
18
    builtins,
19
    bzrdir,
20
    errors,
21
    option,
22
    repository,
2221.4.8 by Aaron Bentley
Merge bzr.dev
23
    symbol_versioning,
2221.4.1 by Aaron Bentley
Get registry options working
24
    )
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
25
from bzrlib.builtins import cmd_commit, cmd_log, cmd_status
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"""
41
        eq = self.assertEquals
42
        eq(parse_args(cmd_commit(), ['--help']),
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
43
           ([], {'fixes': [], 'help': True}))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
44
        eq(parse_args(cmd_commit(), ['--message=biter']),
2376.4.10 by Jonathan Lange
Oops. Update tests to account for changed options to commit.
45
           ([], {'fixes': [], 'message': 'biter'}))
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
46
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
47
    def test_no_more_opts(self):
48
        """Terminated options"""
49
        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.
50
                          (['-file-with-dashes'], {'fixes': []}))
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
51
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
52
    def test_option_help(self):
53
        """Options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
54
        out, err = self.run_bzr('commit --help')
1857.1.12 by Aaron Bentley
Fix a bunch of test cases that assumed --merge-type or log-format
55
        self.assertContainsRe(out, r'--file(.|\n)*file containing commit'
56
                                   ' message')
57
        self.assertContainsRe(out, r'-h.*--help')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
58
59
    def test_option_help_global(self):
60
        """Global options have help strings."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
61
        out, err = self.run_bzr('help status')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
62
        self.assertContainsRe(out, r'--show-ids.*show internal object')
63
64
    def test_option_arg_help(self):
65
        """Help message shows option arguments."""
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
66
        out, err = self.run_bzr('help commit')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
67
        self.assertEquals(err, '')
68
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
69
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
70
    def test_unknown_short_opt(self):
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
71
        out, err = self.run_bzr('help -r', retcode=3)
1857.1.1 by Aaron Bentley
Use optparse for parsing options
72
        self.assertContainsRe(err, r'no such option')
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
73
2190.2.1 by Martin Pool
remove global registration of short options
74
    def test_get_short_name(self):
75
        file_opt = option.Option.OPTIONS['file']
2227.1.1 by mbp at sourcefrog
Back out previous incompatible change: Option.short_name is now again
76
        self.assertEquals(file_opt.short_name(), 'F')
2190.2.1 by Martin Pool
remove global registration of short options
77
        force_opt = option.Option.OPTIONS['force']
2227.1.1 by mbp at sourcefrog
Back out previous incompatible change: Option.short_name is now again
78
        self.assertEquals(force_opt.short_name(), None)
2190.2.1 by Martin Pool
remove global registration of short options
79
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
80
    def test_set_short_name(self):
81
        o = option.Option('wiggle')
82
        o.set_short_name('w')
83
        self.assertEqual(o.short_name(), 'w')
84
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
85
    def test_old_short_names(self):
86
        # test the deprecated method for getting and setting short option
87
        # names
88
        expected_warning = (
89
            "access to SHORT_OPTIONS was deprecated in version 0.14."
90
            " Set the short option name when constructing the Option.",
91
            DeprecationWarning, 2)
92
        _warnings = []
93
        def capture_warning(message, category, stacklevel=None):
94
            _warnings.append((message, category, stacklevel))
95
        old_warning_method = symbol_versioning.warn
96
        try:
97
            # an example of the kind of thing plugins might want to do through
98
            # the old interface - make a new option and then give it a short
99
            # name.
100
            symbol_versioning.set_warning_method(capture_warning)
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
101
            example_opt = option.Option('example', help='example option')
102
            option.Option.SHORT_OPTIONS['w'] = example_opt
103
            self.assertEqual(example_opt.short_name(), 'w')
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
104
            self.assertEqual([expected_warning], _warnings)
2227.1.4 by mbp at sourcefrog
add test that legacy SHORT_OPTIONS really works, and set_short_name
105
            # now check that it can actually be parsed with the registered
106
            # value
107
            opts, args = parse([example_opt], ['-w', 'foo'])
108
            self.assertEqual(opts.example, True)
109
            self.assertEqual(args, ['foo'])
2227.1.3 by mbp at sourcefrog
Restore access to SHORT_OPTIONS for compatibility
110
        finally:
111
            symbol_versioning.set_warning_method(old_warning_method)
112
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
113
    def test_allow_dash(self):
114
        """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.
115
        self.assertEqual(
116
            (['-'], {'fixes': []}), parse_args(cmd_commit(), ['-']))
1852.1.1 by John Arbash Meinel
Allow a plain '-' to be supplied as an argument. bug #50984
117
2221.4.1 by Aaron Bentley
Get registry options working
118
    def parse(self, options, args):
119
        parser = option.get_optparser(dict((o.name, o) for o in options))
120
        return parser.parse_args(args)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
121
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
122
    def test_conversion(self):
123
        options = [option.Option('hello')]
2221.4.1 by Aaron Bentley
Get registry options working
124
        opts, args = self.parse(options, ['--no-hello', '--hello'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
125
        self.assertEqual(True, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
126
        opts, args = self.parse(options, [])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
127
        self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
2221.4.1 by Aaron Bentley
Get registry options working
128
        opts, args = self.parse(options, ['--hello', '--no-hello'])
1857.1.22 by Aaron Bentley
Negations set value to False, instead of Optparser.DEFAULT_VALUE
129
        self.assertEqual(False, opts.hello)
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
130
        options = [option.Option('number', type=int)]
2221.4.1 by Aaron Bentley
Get registry options working
131
        opts, args = self.parse(options, ['--number', '6'])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
132
        self.assertEqual(6, opts.number)
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
                          ['--number'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
135
        self.assertRaises(errors.BzrCommandError, self.parse, options,
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
136
                          ['--no-number'])
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
137
2221.4.1 by Aaron Bentley
Get registry options working
138
    def test_registry_conversion(self):
139
        registry = bzrdir.BzrDirFormatRegistry()
140
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
141
        registry.register_metadir('two', 'RepositoryFormatKnit1', 'two help')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
142
        registry.register_metadir('hidden', 'RepositoryFormatKnit1',
143
            'two help', hidden=True)
2221.4.1 by Aaron Bentley
Get registry options working
144
        registry.set_default('one')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
145
        options = [option.RegistryOption('format', '', registry, str)]
2221.4.1 by Aaron Bentley
Get registry options working
146
        opts, args = self.parse(options, ['--format', 'one'])
147
        self.assertEqual({'format':'one'}, opts)
148
        opts, args = self.parse(options, ['--format', 'two'])
149
        self.assertEqual({'format':'two'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
150
        self.assertRaises(errors.BadOptionValue, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
151
                          ['--format', 'three'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
152
        self.assertRaises(errors.BzrCommandError, self.parse, options,
2221.4.1 by Aaron Bentley
Get registry options working
153
                          ['--two'])
2221.4.9 by Aaron Bentley
Zap trailing whitespace
154
        options = [option.RegistryOption('format', '', registry, str,
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
155
                   value_switches=True)]
2221.4.1 by Aaron Bentley
Get registry options working
156
        opts, args = self.parse(options, ['--two'])
157
        self.assertEqual({'format':'two'}, opts)
158
        opts, args = self.parse(options, ['--two', '--one'])
159
        self.assertEqual({'format':'one'}, opts)
2221.4.9 by Aaron Bentley
Zap trailing whitespace
160
        opts, args = self.parse(options, ['--two', '--one',
2221.4.1 by Aaron Bentley
Get registry options working
161
                                          '--format', 'two'])
162
        self.assertEqual({'format':'two'}, opts)
1551.12.18 by Aaron Bentley
Allow RegistryOption to omit the value-taking option
163
        options = [option.RegistryOption('format', '', registry, str,
164
                   enum_switch=False)]
165
        self.assertRaises(errors.BzrCommandError, self.parse, options,
166
                          ['--format', 'two'])
2221.4.1 by Aaron Bentley
Get registry options working
167
168
    def test_registry_converter(self):
2221.4.9 by Aaron Bentley
Zap trailing whitespace
169
        options = [option.RegistryOption('format', '',
2204.5.5 by Aaron Bentley
Remove RepositoryFormat.set_default_format, deprecate get_format_type
170
                   bzrdir.format_registry, bzrdir.format_registry.make_bzrdir)]
2221.4.1 by Aaron Bentley
Get registry options working
171
        opts, args = self.parse(options, ['--format', 'knit'])
172
        self.assertIsInstance(opts.format.repository_format,
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
173
                              knitrepo.RepositoryFormatKnit1)
2221.4.1 by Aaron Bentley
Get registry options working
174
1551.12.24 by Aaron Bentley
Add RegistryOption.from_swargs to simplify simple registry options
175
    def test_from_kwargs(self):
176
        my_option = option.RegistryOption.from_kwargs('my-option',
177
            help='test option', short='be short', be_long='go long')
178
        self.assertEqual(['my-option'],
179
            [x[0] for x in my_option.iter_switches()])
180
        my_option = option.RegistryOption.from_kwargs('my-option',
181
            help='test option', title="My option", short='be short',
182
            be_long='go long', value_switches=True)
183
        self.assertEqual(['my-option', 'be-long', 'short'],
184
            [x[0] for x in my_option.iter_switches()])
185
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
186
    def test_help(self):
187
        registry = bzrdir.BzrDirFormatRegistry()
188
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
189
        registry.register_metadir('two',
190
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
191
            'two help',
192
            )
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
193
        registry.register_metadir('hidden', 'RepositoryFormat7', 'hidden help',
194
            hidden=True)
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
195
        registry.set_default('one')
196
        options = [option.RegistryOption('format', 'format help', registry,
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
197
                   str, value_switches=True, title='Formats')]
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
198
        parser = option.get_optparser(dict((o.name, o) for o in options))
199
        value = parser.format_option_help()
200
        self.assertContainsRe(value, 'format.*format help')
201
        self.assertContainsRe(value, 'one.*one help')
2221.4.12 by Aaron Bentley
Add option grouping to RegistryOption and clean up format options
202
        self.assertContainsRe(value, 'Formats:\n *--format')
1551.13.2 by Aaron Bentley
Hide dirstate-with-subtree format
203
        self.assertNotContainsRe(value, 'hidden help')
2221.4.2 by Aaron Bentley
Implement RegistryOption on init
204
1857.1.16 by Aaron Bentley
Add tests for iter_switches
205
    def test_iter_switches(self):
206
        opt = option.Option('hello', help='fg')
207
        self.assertEqual(list(opt.iter_switches()),
208
                         [('hello', None, None, 'fg')])
209
        opt = option.Option('hello', help='fg', type=int)
210
        self.assertEqual(list(opt.iter_switches()),
211
                         [('hello', None, 'ARG', 'fg')])
212
        opt = option.Option('hello', help='fg', type=int, argname='gar')
213
        self.assertEqual(list(opt.iter_switches()),
214
                         [('hello', None, 'GAR', 'fg')])
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
215
        registry = bzrdir.BzrDirFormatRegistry()
216
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
2241.1.21 by Martin Pool
Change register_metadir to take fully-qualified repository class name.
217
        registry.register_metadir('two',
218
                'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
219
                'two help',
220
                )
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
221
        registry.set_default('one')
222
        opt = option.RegistryOption('format', 'format help', registry,
223
                                    value_switches=False)
224
        self.assertEqual(list(opt.iter_switches()),
225
                         [('format', None, 'ARG', 'format help')])
226
        opt = option.RegistryOption('format', 'format help', registry,
227
                                    value_switches=True)
228
        self.assertEqual(list(opt.iter_switches()),
229
                         [('format', None, 'ARG', 'format help'),
2221.4.9 by Aaron Bentley
Zap trailing whitespace
230
                          ('default', None, None, 'one help'),
231
                          ('one', None, None, 'one help'),
232
                          ('two', None, None, 'two help'),
2221.4.4 by Aaron Bentley
Fix iter_switches behavior when value_switches is true
233
                          ])
1857.1.16 by Aaron Bentley
Add tests for iter_switches
234
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
235
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
236
class TestListOptions(TestCase):
237
    """Tests for ListOption, used to specify lists on the command-line."""
238
2376.4.1 by jml at canonical
Blackbox-driven --fixes option to commit.
239
    def parse(self, options, args):
240
        parser = option.get_optparser(dict((o.name, o) for o in options))
241
        return parser.parse_args(args)
242
243
    def test_list_option(self):
244
        options = [option.ListOption('hello', type=str)]
245
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
246
        self.assertEqual(['world', 'sailor'], opts.hello)
247
248
    def test_list_option_no_arguments(self):
249
        options = [option.ListOption('hello', type=str)]
250
        opts, args = self.parse(options, [])
251
        self.assertEqual([], opts.hello)
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
252
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
253
    def test_list_option_with_int_type(self):
254
        options = [option.ListOption('hello', type=int)]
255
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
256
        self.assertEqual([2, 3], opts.hello)
257
258
    def test_list_option_with_int_type_can_be_reset(self):
259
        options = [option.ListOption('hello', type=int)]
260
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
261
                                          '--hello=-', '--hello=5'])
262
        self.assertEqual([5], opts.hello)
263
2376.4.11 by Jonathan Lange
Provide a way of resetting list options (specifying '-' as the argument)
264
    def test_list_option_can_be_reset(self):
265
        """Passing an option of '-' to a list option should reset the list."""
266
        options = [option.ListOption('hello', type=str)]
267
        opts, args = self.parse(
268
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
269
        self.assertEqual(['c'], opts.hello)