~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commands.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
from cStringIO import StringIO
18
18
import errno
 
19
import inspect
19
20
import sys
20
21
 
21
22
from bzrlib import (
24
25
    config,
25
26
    errors,
26
27
    option,
 
28
    symbol_versioning,
27
29
    tests,
28
30
    )
29
31
from bzrlib.commands import display_command
32
34
 
33
35
class TestCommands(tests.TestCase):
34
36
 
 
37
    def test_all_commands_have_help(self):
 
38
        commands._register_builtin_commands()
 
39
        commands_without_help = set()
 
40
        base_doc = inspect.getdoc(commands.Command)
 
41
        for cmd_name in commands.all_command_names():
 
42
            cmd = commands.get_cmd_object(cmd_name)
 
43
            cmd_help = cmd.help()
 
44
            if not cmd_help or cmd_help == base_doc:
 
45
                commands_without_help.append(cmd_name)
 
46
        self.assertLength(0, commands_without_help)
 
47
 
35
48
    def test_display_command(self):
36
49
        """EPIPE message is selectively suppressed"""
37
50
        def pipe_thrower():
64
77
    @staticmethod
65
78
    def get_command(options):
66
79
        class cmd_foo(commands.Command):
67
 
            'Bar'
 
80
            __doc__ = 'Bar'
68
81
 
69
82
            takes_options = options
70
83
 
111
124
 
112
125
    def test_unicode(self):
113
126
        my_config = self._get_config("[ALIASES]\n"
114
 
            u"iam=whoami 'Erik B\u00e5gfors <erik@bagfors.nu>'\n")
 
127
            u'iam=whoami "Erik B\u00e5gfors <erik@bagfors.nu>"\n')
115
128
        self.assertEqual([u'whoami', u'Erik B\u00e5gfors <erik@bagfors.nu>'],
116
129
                          commands.get_alias("iam", config=my_config))
117
130
 
119
132
class TestSeeAlso(tests.TestCase):
120
133
    """Tests for the see also functional of Command."""
121
134
 
 
135
    @staticmethod
 
136
    def _get_command_with_see_also(see_also):
 
137
        class ACommand(commands.Command):
 
138
            __doc__ = """A sample command."""
 
139
            _see_also = see_also
 
140
        return ACommand()
 
141
 
122
142
    def test_default_subclass_no_see_also(self):
123
 
        class ACommand(commands.Command):
124
 
            """A sample command."""
125
 
        command = ACommand()
 
143
        command = self._get_command_with_see_also([])
126
144
        self.assertEqual([], command.get_see_also())
127
145
 
128
146
    def test__see_also(self):
129
147
        """When _see_also is defined, it sets the result of get_see_also()."""
130
 
        class ACommand(commands.Command):
131
 
            _see_also = ['bar', 'foo']
132
 
        command = ACommand()
 
148
        command = self._get_command_with_see_also(['bar', 'foo'])
133
149
        self.assertEqual(['bar', 'foo'], command.get_see_also())
134
150
 
135
151
    def test_deduplication(self):
136
152
        """Duplicates in _see_also are stripped out."""
137
 
        class ACommand(commands.Command):
138
 
            _see_also = ['foo', 'foo']
139
 
        command = ACommand()
 
153
        command = self._get_command_with_see_also(['foo', 'foo'])
140
154
        self.assertEqual(['foo'], command.get_see_also())
141
155
 
142
156
    def test_sorted(self):
143
157
        """_see_also is sorted by get_see_also."""
144
 
        class ACommand(commands.Command):
145
 
            _see_also = ['foo', 'bar']
146
 
        command = ACommand()
 
158
        command = self._get_command_with_see_also(['foo', 'bar'])
147
159
        self.assertEqual(['bar', 'foo'], command.get_see_also())
148
160
 
149
161
    def test_additional_terms(self):
150
162
        """Additional terms can be supplied and are deduped and sorted."""
151
 
        class ACommand(commands.Command):
152
 
            _see_also = ['foo', 'bar']
153
 
        command = ACommand()
 
163
        command = self._get_command_with_see_also(['foo', 'bar'])
154
164
        self.assertEqual(['bar', 'foo', 'gam'],
155
165
            command.get_see_also(['gam', 'bar', 'gam']))
156
166
 
163
173
        del sys.modules['bzrlib.tests.fake_command']
164
174
        global lazy_command_imported
165
175
        lazy_command_imported = False
 
176
        commands.install_bzr_command_hooks()
166
177
 
167
178
    @staticmethod
168
179
    def remove_fake():
205
216
        # commands are registered).
206
217
        # when they are simply created.
207
218
        hook_calls = []
 
219
        commands.install_bzr_command_hooks()
208
220
        commands.Command.hooks.install_named_hook(
209
221
            "extend_command", hook_calls.append, None)
210
222
        # create a command, should not fire
211
 
        class ACommand(commands.Command):
212
 
            """A sample command."""
213
 
        cmd = ACommand()
 
223
        class cmd_test_extend_command_hook(commands.Command):
 
224
            __doc__ = """A sample command."""
214
225
        self.assertEqual([], hook_calls)
215
226
        # -- as a builtin
216
227
        # register the command class, should not fire
217
228
        try:
218
 
            builtins.cmd_test_extend_command_hook = ACommand
 
229
            commands.builtin_command_registry.register(cmd_test_extend_command_hook)
219
230
            self.assertEqual([], hook_calls)
220
231
            # and ask for the object, should fire
221
232
            cmd = commands.get_cmd_object('test-extend-command-hook')
225
236
            self.assertSubset([cmd], hook_calls)
226
237
            del hook_calls[:]
227
238
        finally:
228
 
            del builtins.cmd_test_extend_command_hook
 
239
            commands.builtin_command_registry.remove('test-extend-command-hook')
229
240
        # -- as a plugin lazy registration
230
241
        try:
231
242
            # register the command class, should not fire
237
248
            self.assertEqual([cmd], hook_calls)
238
249
        finally:
239
250
            commands.plugin_cmds.remove('fake')
 
251
 
 
252
 
 
253
class TestGetCommandHook(tests.TestCase):
 
254
 
 
255
    def test_fires_on_get_cmd_object(self):
 
256
        # The get_command(cmd) hook fires when commands are delivered to the
 
257
        # ui.
 
258
        commands.install_bzr_command_hooks()
 
259
        hook_calls = []
 
260
        class ACommand(commands.Command):
 
261
            __doc__ = """A sample command."""
 
262
        def get_cmd(cmd_or_None, cmd_name):
 
263
            hook_calls.append(('called', cmd_or_None, cmd_name))
 
264
            if cmd_name in ('foo', 'info'):
 
265
                return ACommand()
 
266
        commands.Command.hooks.install_named_hook(
 
267
            "get_command", get_cmd, None)
 
268
        # create a command directly, should not fire
 
269
        cmd = ACommand()
 
270
        self.assertEqual([], hook_calls)
 
271
        # ask by name, should fire and give us our command
 
272
        cmd = commands.get_cmd_object('foo')
 
273
        self.assertEqual([('called', None, 'foo')], hook_calls)
 
274
        self.assertIsInstance(cmd, ACommand)
 
275
        del hook_calls[:]
 
276
        # ask by a name that is supplied by a builtin - the hook should still
 
277
        # fire and we still get our object, but we should see the builtin
 
278
        # passed to the hook.
 
279
        cmd = commands.get_cmd_object('info')
 
280
        self.assertIsInstance(cmd, ACommand)
 
281
        self.assertEqual(1, len(hook_calls))
 
282
        self.assertEqual('info', hook_calls[0][2])
 
283
        self.assertIsInstance(hook_calls[0][1], builtins.cmd_info)
 
284
 
 
285
 
 
286
class TestGetMissingCommandHook(tests.TestCase):
 
287
 
 
288
    def hook_missing(self):
 
289
        """Hook get_missing_command for testing."""
 
290
        self.hook_calls = []
 
291
        class ACommand(commands.Command):
 
292
            __doc__ = """A sample command."""
 
293
        def get_missing_cmd(cmd_name):
 
294
            self.hook_calls.append(('called', cmd_name))
 
295
            if cmd_name in ('foo', 'info'):
 
296
                return ACommand()
 
297
        commands.Command.hooks.install_named_hook(
 
298
            "get_missing_command", get_missing_cmd, None)
 
299
        self.ACommand = ACommand
 
300
 
 
301
    def test_fires_on_get_cmd_object(self):
 
302
        # The get_missing_command(cmd) hook fires when commands are delivered to the
 
303
        # ui.
 
304
        self.hook_missing()
 
305
        # create a command directly, should not fire
 
306
        self.cmd = self.ACommand()
 
307
        self.assertEqual([], self.hook_calls)
 
308
        # ask by name, should fire and give us our command
 
309
        cmd = commands.get_cmd_object('foo')
 
310
        self.assertEqual([('called', 'foo')], self.hook_calls)
 
311
        self.assertIsInstance(cmd, self.ACommand)
 
312
        del self.hook_calls[:]
 
313
        # ask by a name that is supplied by a builtin - the hook should not
 
314
        # fire and we still get our object.
 
315
        commands.install_bzr_command_hooks()
 
316
        cmd = commands.get_cmd_object('info')
 
317
        self.assertNotEqual(None, cmd)
 
318
        self.assertEqual(0, len(self.hook_calls))
 
319
 
 
320
    def test_skipped_on_HelpCommandIndex_get_topics(self):
 
321
        # The get_missing_command(cmd_name) hook is not fired when
 
322
        # looking up help topics.
 
323
        self.hook_missing()
 
324
        topic = commands.HelpCommandIndex()
 
325
        topics = topic.get_topics('foo')
 
326
        self.assertEqual([], self.hook_calls)
 
327
 
 
328
 
 
329
class TestListCommandHook(tests.TestCase):
 
330
 
 
331
    def test_fires_on_all_command_names(self):
 
332
        # The list_commands() hook fires when all_command_names() is invoked.
 
333
        hook_calls = []
 
334
        commands.install_bzr_command_hooks()
 
335
        def list_my_commands(cmd_names):
 
336
            hook_calls.append('called')
 
337
            cmd_names.update(['foo', 'bar'])
 
338
            return cmd_names
 
339
        commands.Command.hooks.install_named_hook(
 
340
            "list_commands", list_my_commands, None)
 
341
        # Get a command, which should not trigger the hook.
 
342
        cmd = commands.get_cmd_object('info')
 
343
        self.assertEqual([], hook_calls)
 
344
        # Get all command classes (for docs and shell completion).
 
345
        cmds = list(commands.all_command_names())
 
346
        self.assertEqual(['called'], hook_calls)
 
347
        self.assertSubset(['foo', 'bar'], cmds)
 
348
 
 
349
class TestDeprecations(tests.TestCase):
 
350
 
 
351
    def test_shlex_split_unicode_deprecation(self):
 
352
        res = self.applyDeprecated(
 
353
                symbol_versioning.deprecated_in((2, 2, 0)),
 
354
                commands.shlex_split_unicode, 'whatever')