~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_options.py

Clean up the lock.py code to use less indenting, and conform to better coding practise.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
import re
18
 
 
19
17
from bzrlib import (
20
18
    builtins,
21
19
    bzrdir,
22
 
    commands,
23
20
    errors,
24
21
    option,
25
22
    repository,
30
27
from bzrlib.tests import TestCase
31
28
from bzrlib.repofmt import knitrepo
32
29
 
33
 
 
34
30
def parse(options, args):
35
31
    parser = option.get_optparser(dict((o.name, o) for o in options))
36
32
    return parser.parse_args(args)
37
33
 
38
 
 
39
34
class OptionTests(TestCase):
40
35
    """Command-line option tests"""
41
36
 
43
38
        """Option parser"""
44
39
        eq = self.assertEquals
45
40
        eq(parse_args(cmd_commit(), ['--help']),
46
 
           ([], {'fixes': [], 'help': True}))
 
41
           ([], {'help': True}))
47
42
        eq(parse_args(cmd_commit(), ['--message=biter']),
48
 
           ([], {'fixes': [], 'message': 'biter'}))
 
43
           ([], {'message': 'biter'}))
 
44
        ## eq(parse_args(cmd_log(),  '-r 500'.split()),
 
45
        ##   ([], {'revision': RevisionSpec_int(500)}))
49
46
 
50
47
    def test_no_more_opts(self):
51
48
        """Terminated options"""
52
49
        self.assertEquals(parse_args(cmd_commit(), ['--', '-file-with-dashes']),
53
 
                          (['-file-with-dashes'], {'fixes': []}))
 
50
                          (['-file-with-dashes'], {}))
54
51
 
55
52
    def test_option_help(self):
56
53
        """Options have help strings."""
57
 
        out, err = self.run_bzr('commit --help')
58
 
        self.assertContainsRe(out,
59
 
                r'--file(.|\n)*Take commit message from this file\.')
 
54
        out, err = self.run_bzr_captured(['commit', '--help'])
 
55
        self.assertContainsRe(out, r'--file(.|\n)*file containing commit'
 
56
                                   ' message')
60
57
        self.assertContainsRe(out, r'-h.*--help')
61
58
 
62
59
    def test_option_help_global(self):
63
60
        """Global options have help strings."""
64
 
        out, err = self.run_bzr('help status')
65
 
        self.assertContainsRe(out, r'--show-ids.*Show internal object.')
 
61
        out, err = self.run_bzr_captured(['help', 'status'])
 
62
        self.assertContainsRe(out, r'--show-ids.*show internal object')
66
63
 
67
64
    def test_option_arg_help(self):
68
65
        """Help message shows option arguments."""
69
 
        out, err = self.run_bzr('help commit')
 
66
        out, err = self.run_bzr_captured(['help', 'commit'])
70
67
        self.assertEquals(err, '')
71
68
        self.assertContainsRe(out, r'--file[ =]MSGFILE')
72
69
 
73
70
    def test_unknown_short_opt(self):
74
 
        out, err = self.run_bzr('help -r', retcode=3)
 
71
        out, err = self.run_bzr_captured(['help', '-r'], retcode=3)
75
72
        self.assertContainsRe(err, r'no such option')
76
73
 
 
74
    def test_get_short_name(self):
 
75
        file_opt = option.Option.OPTIONS['file']
 
76
        self.assertEquals(file_opt.short_name(), 'F')
 
77
        force_opt = option.Option.OPTIONS['force']
 
78
        self.assertEquals(force_opt.short_name(), None)
 
79
 
77
80
    def test_set_short_name(self):
78
81
        o = option.Option('wiggle')
79
82
        o.set_short_name('w')
80
83
        self.assertEqual(o.short_name(), 'w')
81
84
 
 
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)
 
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')
 
104
            self.assertEqual([expected_warning], _warnings)
 
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'])
 
110
        finally:
 
111
            symbol_versioning.set_warning_method(old_warning_method)
 
112
 
82
113
    def test_allow_dash(self):
83
114
        """Test that we can pass a plain '-' as an argument."""
84
 
        self.assertEqual(
85
 
            (['-'], {'fixes': []}), parse_args(cmd_commit(), ['-']))
 
115
        self.assertEqual((['-'], {}), parse_args(cmd_commit(), ['-']))
86
116
 
87
117
    def parse(self, options, args):
88
118
        parser = option.get_optparser(dict((o.name, o) for o in options))
108
138
        registry = bzrdir.BzrDirFormatRegistry()
109
139
        registry.register_metadir('one', 'RepositoryFormat7', 'one help')
110
140
        registry.register_metadir('two', 'RepositoryFormatKnit1', 'two help')
111
 
        registry.register_metadir('hidden', 'RepositoryFormatKnit1',
112
 
            'two help', hidden=True)
113
141
        registry.set_default('one')
114
142
        options = [option.RegistryOption('format', '', registry, str)]
115
143
        opts, args = self.parse(options, ['--format', 'one'])
159
187
            'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
160
188
            'two help',
161
189
            )
162
 
        registry.register_metadir('hidden', 'RepositoryFormat7', 'hidden help',
163
 
            hidden=True)
164
190
        registry.set_default('one')
165
191
        options = [option.RegistryOption('format', 'format help', registry,
166
192
                   str, value_switches=True, title='Formats')]
169
195
        self.assertContainsRe(value, 'format.*format help')
170
196
        self.assertContainsRe(value, 'one.*one help')
171
197
        self.assertContainsRe(value, 'Formats:\n *--format')
172
 
        self.assertNotContainsRe(value, 'hidden help')
173
198
 
174
199
    def test_iter_switches(self):
175
200
        opt = option.Option('hello', help='fg')
201
226
                          ('two', None, None, 'two help'),
202
227
                          ])
203
228
 
204
 
 
205
 
class TestListOptions(TestCase):
206
 
    """Tests for ListOption, used to specify lists on the command-line."""
207
 
 
208
 
    def parse(self, options, args):
209
 
        parser = option.get_optparser(dict((o.name, o) for o in options))
210
 
        return parser.parse_args(args)
211
 
 
212
 
    def test_list_option(self):
213
 
        options = [option.ListOption('hello', type=str)]
214
 
        opts, args = self.parse(options, ['--hello=world', '--hello=sailor'])
215
 
        self.assertEqual(['world', 'sailor'], opts.hello)
216
 
 
217
 
    def test_list_option_no_arguments(self):
218
 
        options = [option.ListOption('hello', type=str)]
219
 
        opts, args = self.parse(options, [])
220
 
        self.assertEqual([], opts.hello)
221
 
 
222
 
    def test_list_option_with_int_type(self):
223
 
        options = [option.ListOption('hello', type=int)]
224
 
        opts, args = self.parse(options, ['--hello=2', '--hello=3'])
225
 
        self.assertEqual([2, 3], opts.hello)
226
 
 
227
 
    def test_list_option_with_int_type_can_be_reset(self):
228
 
        options = [option.ListOption('hello', type=int)]
229
 
        opts, args = self.parse(options, ['--hello=2', '--hello=3',
230
 
                                          '--hello=-', '--hello=5'])
231
 
        self.assertEqual([5], opts.hello)
232
 
 
233
 
    def test_list_option_can_be_reset(self):
234
 
        """Passing an option of '-' to a list option should reset the list."""
235
 
        options = [option.ListOption('hello', type=str)]
236
 
        opts, args = self.parse(
237
 
            options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
238
 
        self.assertEqual(['c'], opts.hello)
239
 
 
240
 
 
241
 
class TestOptionDefinitions(TestCase):
242
 
    """Tests for options in the Bazaar codebase."""
243
 
 
244
 
    def get_builtin_command_options(self):
245
 
        g = []
246
 
        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
247
 
            cmd = cmd_class()
248
 
            for opt_name, opt in sorted(cmd.options().items()):
249
 
                g.append((cmd_name, opt))
250
 
        return g
251
 
 
252
 
    def test_global_options_used(self):
253
 
        # In the distant memory, options could only be declared globally.  Now
254
 
        # we prefer to declare them in the command, unless like -r they really
255
 
        # are used very widely with the exact same meaning.  So this checks
256
 
        # for any that should be garbage collected.
257
 
        g = dict(option.Option.OPTIONS.items())
258
 
        used_globals = {}
259
 
        msgs = []
260
 
        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
261
 
            for option_or_name in sorted(cmd_class.takes_options):
262
 
                if not isinstance(option_or_name, basestring):
263
 
                    self.assertIsInstance(option_or_name, option.Option)
264
 
                elif not option_or_name in g:
265
 
                    msgs.append("apparent reference to undefined "
266
 
                        "global option %r from %r"
267
 
                        % (option_or_name, cmd_class))
268
 
                else:
269
 
                    used_globals.setdefault(option_or_name, []).append(cmd_name)
270
 
        unused_globals = set(g.keys()) - set(used_globals.keys())
271
 
        # not enforced because there might be plugins that use these globals
272
 
        ## for option_name in sorted(unused_globals):
273
 
        ##    msgs.append("unused global option %r" % option_name)
274
 
        ## for option_name, cmds in sorted(used_globals.items()):
275
 
        ##     if len(cmds) <= 1:
276
 
        ##         msgs.append("global option %r is only used by %r"
277
 
        ##                 % (option_name, cmds))
278
 
        if msgs:
279
 
            self.fail("problems with global option definitions:\n"
280
 
                    + '\n'.join(msgs))
281
 
 
282
 
    def test_option_grammar(self):
283
 
        msgs = []
284
 
        # Option help should be written in sentence form, and have a final
285
 
        # period and be all on a single line, because the display code will
286
 
        # wrap it.
287
 
        option_re = re.compile(r'^[A-Z][^\n]+\.$')
288
 
        for scope, option in self.get_builtin_command_options():
289
 
            if not option.help:
290
 
                msgs.append('%-16s %-16s %s' %
291
 
                       ((scope or 'GLOBAL'), option.name, 'NO HELP'))
292
 
            elif not option_re.match(option.help):
293
 
                msgs.append('%-16s %-16s %s' %
294
 
                        ((scope or 'GLOBAL'), option.name, option.help))
295
 
        if msgs:
296
 
            self.fail("The following options don't match the style guide:\n"
297
 
                    + '\n'.join(msgs))
 
229
#     >>> parse_args('log -r 500'.split())
 
230
#     (['log'], {'revision': [<RevisionSpec_int 500>]})
 
231
#     >>> parse_args('log -r500..600'.split())
 
232
#     (['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
233
#     >>> parse_args('log -vr500..600'.split())
 
234
#     (['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
235
#     >>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
 
236
#     (['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})