/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_help.py

  • Committer: Robert Collins
  • Date: 2007-09-19 05:14:14 UTC
  • mto: (2835.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2836.
  • Revision ID: robertc@robertcollins.net-20070919051414-2tgjqteg7k3ps4h0
* ``pull``, ``merge`` and ``push`` will no longer silently correct some
  repository index errors that occured as a result of the Weave disk format.
  Instead the ``reconcile`` command needs to be run to correct those
  problems if they exist (and it has been able to fix most such problems
  since bzr 0.8). Some new problems have been identified during this release
  and you should run ``bzr check`` once on every repository to see if you
  need to reconcile. If you cannot ``pull`` or ``merge`` from a remote
  repository due to mismatched parent errors - a symptom of index errors -
  you should simply take a full copy of that remote repository to a clean
  directory outside any local repositories, then run reconcile on it, and
  finally pull from it locally. (And naturally email the repositories owner
  to ask them to upgrade and run reconcile).
  (Robert Collins)

* ``VersionedFile.fix_parents`` has been removed as a harmful API.
  ``VersionedFile.join`` will no longer accept different parents on either
  side of a join - it will either ignore them, or error, depending on the
  implementation. See notes when upgrading for more information.
  (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007 Canonical Ltd
 
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
 
16
 
 
17
"""Unit tests for the bzrlib.help module."""
 
18
 
 
19
from cStringIO import StringIO
 
20
 
 
21
from bzrlib import (
 
22
    builtins,
 
23
    commands,
 
24
    errors,
 
25
    help,
 
26
    help_topics,
 
27
    plugin,
 
28
    tests,
 
29
    )
 
30
 
 
31
 
 
32
class TestCommandHelp(tests.TestCase):
 
33
    """Tests for help on commands."""
 
34
 
 
35
    def test_command_help_includes_see_also(self):
 
36
        class cmd_WithSeeAlso(commands.Command):
 
37
            """A sample command."""
 
38
            _see_also = ['foo', 'bar']
 
39
        cmd = cmd_WithSeeAlso()
 
40
        helptext = cmd.get_help_text()
 
41
        self.assertEndsWith(
 
42
            helptext,
 
43
            '  -v, --verbose  Display more information.\n'
 
44
            '  -q, --quiet    Only display errors and warnings.\n'
 
45
            '  -h, --help     Show help message.\n'
 
46
            '\n'
 
47
            'See also: bar, foo\n')
 
48
 
 
49
    def test_get_help_text(self):
 
50
        """Commands have a get_help_text method which returns their help."""
 
51
        class cmd_Demo(commands.Command):
 
52
            """A sample command."""
 
53
        cmd = cmd_Demo()
 
54
        helptext = cmd.get_help_text()
 
55
        self.assertStartsWith(helptext,
 
56
            'Purpose: A sample command.\n'
 
57
            'Usage:   bzr Demo')
 
58
        self.assertEndsWith(helptext,
 
59
            '  -h, --help     Show help message.\n\n')
 
60
 
 
61
    def test_command_with_additional_see_also(self):
 
62
        class cmd_WithSeeAlso(commands.Command):
 
63
            """A sample command."""
 
64
            _see_also = ['foo', 'bar']
 
65
        cmd = cmd_WithSeeAlso()
 
66
        helptext = cmd.get_help_text(['gam'])
 
67
        self.assertEndsWith(
 
68
            helptext,
 
69
            '  -v, --verbose  Display more information.\n'
 
70
            '  -q, --quiet    Only display errors and warnings.\n'
 
71
            '  -h, --help     Show help message.\n'
 
72
            '\n'
 
73
            'See also: bar, foo, gam\n')
 
74
 
 
75
    def test_command_only_additional_see_also(self):
 
76
        class cmd_WithSeeAlso(commands.Command):
 
77
            """A sample command."""
 
78
        cmd = cmd_WithSeeAlso()
 
79
        helptext = cmd.get_help_text(['gam'])
 
80
        self.assertEndsWith(
 
81
            helptext,
 
82
            '  -v, --verbose  Display more information.\n'
 
83
            '  -q, --quiet    Only display errors and warnings.\n'
 
84
            '  -h, --help     Show help message.\n'
 
85
            '\n'
 
86
            'See also: gam\n')
 
87
 
 
88
    def test_get_help_topic(self):
 
89
        """The help topic for a Command is its name()."""
 
90
        class cmd_foo_bar(commands.Command):
 
91
            """A sample command."""
 
92
        cmd = cmd_foo_bar()
 
93
        self.assertEqual(cmd.name(), cmd.get_help_topic())
 
94
 
 
95
    def test_formatted_help_text(self):
 
96
        """Help text should be plain text by default."""
 
97
        class cmd_Demo(commands.Command):
 
98
            """A sample command.
 
99
 
 
100
            :Examples:
 
101
                Example 1::
 
102
 
 
103
                    cmd arg1
 
104
 
 
105
                Example 2::
 
106
 
 
107
                    cmd arg2
 
108
            """
 
109
        cmd = cmd_Demo()
 
110
        helptext = cmd.get_help_text()
 
111
        self.assertEquals(
 
112
            helptext,
 
113
            'Purpose: A sample command.\n'
 
114
            'Usage:   bzr Demo\n'
 
115
            '\n'
 
116
            'Options:\n'
 
117
            '  -v, --verbose  Display more information.\n'
 
118
            '  -q, --quiet    Only display errors and warnings.\n'
 
119
            '  -h, --help     Show help message.\n'
 
120
            '\n'
 
121
            'Examples:\n'
 
122
            '    Example 1:\n'
 
123
            '\n'
 
124
            '        cmd arg1\n'
 
125
            '\n'
 
126
            '    Example 2:\n'
 
127
            '\n'
 
128
            '        cmd arg2\n'
 
129
            '\n')
 
130
        helptext = cmd.get_help_text(plain=False)
 
131
        self.assertEquals(helptext,
 
132
            ':Purpose: A sample command.\n'
 
133
            ':Usage:   bzr Demo\n'
 
134
            '\n'
 
135
            ':Options:\n'
 
136
            '  -v, --verbose  Display more information.\n'
 
137
            '  -q, --quiet    Only display errors and warnings.\n'
 
138
            '  -h, --help     Show help message.\n'
 
139
            '\n'
 
140
            ':Examples:\n'
 
141
            '    Example 1::\n'
 
142
            '\n'
 
143
            '        cmd arg1\n'
 
144
            '\n'
 
145
            '    Example 2::\n'
 
146
            '\n'
 
147
            '        cmd arg2\n'
 
148
            '\n')
 
149
 
 
150
    def test_help_text_custom_usage(self):
 
151
        """Help text may contain a custom usage section."""
 
152
        class cmd_Demo(commands.Command):
 
153
            """A sample command.
 
154
 
 
155
            :Usage:
 
156
                cmd Demo [opts] args
 
157
 
 
158
                cmd Demo -h
 
159
 
 
160
            Blah blah blah.
 
161
            """
 
162
        cmd = cmd_Demo()
 
163
        helptext = cmd.get_help_text()
 
164
        self.assertEquals(helptext,
 
165
            'Purpose: A sample command.\n'
 
166
            'Usage:\n'
 
167
            '    cmd Demo [opts] args\n'
 
168
            '\n'
 
169
            '    cmd Demo -h\n'
 
170
            '\n'
 
171
            '\n'
 
172
            'Options:\n'
 
173
            '  -v, --verbose  Display more information.\n'
 
174
            '  -q, --quiet    Only display errors and warnings.\n'
 
175
            '  -h, --help     Show help message.\n'
 
176
            '\n'
 
177
            'Description:\n'
 
178
            '  Blah blah blah.\n\n')
 
179
 
 
180
 
 
181
class TestRegisteredTopic(tests.TestCase):
 
182
    """Tests for the RegisteredTopic class."""
 
183
 
 
184
    def test_contruct(self):
 
185
        """Construction takes the help topic name for the registered item."""
 
186
        # validate our test 
 
187
        self.assertTrue('basic' in help_topics.topic_registry)
 
188
        topic = help_topics.RegisteredTopic('basic')
 
189
        self.assertEqual('basic', topic.topic)
 
190
 
 
191
    def test_get_help_text(self):
 
192
        """A RegisteredTopic returns the get_detail results for get_help_text."""
 
193
        topic = help_topics.RegisteredTopic('commands')
 
194
        self.assertEqual(help_topics.topic_registry.get_detail('commands'),
 
195
            topic.get_help_text())
 
196
 
 
197
    def test_get_help_text_with_additional_see_also(self):
 
198
        topic = help_topics.RegisteredTopic('commands')
 
199
        self.assertEndsWith(
 
200
            topic.get_help_text(['foo', 'bar']),
 
201
            '\n'
 
202
            'See also: bar, foo\n')
 
203
 
 
204
    def test_get_help_topic(self):
 
205
        """The help topic for a RegisteredTopic is its topic from construction."""
 
206
        topic = help_topics.RegisteredTopic('foobar')
 
207
        self.assertEqual('foobar', topic.get_help_topic())
 
208
        topic = help_topics.RegisteredTopic('baz')
 
209
        self.assertEqual('baz', topic.get_help_topic())
 
210
 
 
211
 
 
212
class TestTopicIndex(tests.TestCase):
 
213
    """Tests for the HelpTopicIndex class."""
 
214
 
 
215
    def test_default_constructable(self):
 
216
        index = help_topics.HelpTopicIndex()
 
217
 
 
218
    def test_get_topics_None(self):
 
219
        """Searching for None returns the basic help topic."""
 
220
        index = help_topics.HelpTopicIndex()
 
221
        topics = index.get_topics(None)
 
222
        self.assertEqual(1, len(topics))
 
223
        self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
 
224
        self.assertEqual('basic', topics[0].topic)
 
225
 
 
226
    def test_get_topics_topics(self):
 
227
        """Searching for a string returns the matching string."""
 
228
        index = help_topics.HelpTopicIndex()
 
229
        topics = index.get_topics('topics')
 
230
        self.assertEqual(1, len(topics))
 
231
        self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
 
232
        self.assertEqual('topics', topics[0].topic)
 
233
 
 
234
    def test_get_topics_no_topic(self):
 
235
        """Searching for something not registered returns []."""
 
236
        index = help_topics.HelpTopicIndex()
 
237
        self.assertEqual([], index.get_topics('nothing by this name'))
 
238
 
 
239
    def test_prefix(self):
 
240
        """TopicIndex has a prefix of ''."""
 
241
        index = help_topics.HelpTopicIndex()
 
242
        self.assertEqual('', index.prefix)
 
243
 
 
244
 
 
245
class TestCommandIndex(tests.TestCase):
 
246
    """Tests for the HelpCommandIndex class."""
 
247
 
 
248
    def test_default_constructable(self):
 
249
        index = commands.HelpCommandIndex()
 
250
 
 
251
    def test_get_topics_None(self):
 
252
        """Searching for None returns an empty list."""
 
253
        index = commands.HelpCommandIndex()
 
254
        self.assertEqual([], index.get_topics(None))
 
255
 
 
256
    def test_get_topics_rocks(self):
 
257
        """Searching for 'rocks' returns the cmd_rocks command instance."""
 
258
        index = commands.HelpCommandIndex()
 
259
        topics = index.get_topics('rocks')
 
260
        self.assertEqual(1, len(topics))
 
261
        self.assertIsInstance(topics[0], builtins.cmd_rocks)
 
262
 
 
263
    def test_get_topics_no_topic(self):
 
264
        """Searching for something that is not a command returns []."""
 
265
        index = commands.HelpCommandIndex()
 
266
        self.assertEqual([], index.get_topics('nothing by this name'))
 
267
 
 
268
    def test_prefix(self):
 
269
        """CommandIndex has a prefix of 'commands/'."""
 
270
        index = commands.HelpCommandIndex()
 
271
        self.assertEqual('commands/', index.prefix)
 
272
 
 
273
    def test_get_topic_with_prefix(self):
 
274
        """Searching for commands/rocks returns the rocks command object."""
 
275
        index = commands.HelpCommandIndex()
 
276
        topics = index.get_topics('commands/rocks')
 
277
        self.assertEqual(1, len(topics))
 
278
        self.assertIsInstance(topics[0], builtins.cmd_rocks)
 
279
 
 
280
 
 
281
class TestHelpIndices(tests.TestCase):
 
282
    """Tests for the HelpIndices class."""
 
283
 
 
284
    def test_default_search_path(self):
 
285
        """The default search path should include internal indexs."""
 
286
        indices = help.HelpIndices()
 
287
        self.assertEqual(3, len(indices.search_path))
 
288
        # help topics should be searched in first.
 
289
        self.assertIsInstance(indices.search_path[0],
 
290
            help_topics.HelpTopicIndex)
 
291
        # with commands being search second.
 
292
        self.assertIsInstance(indices.search_path[1],
 
293
            commands.HelpCommandIndex)
 
294
        # and plugins are a third index.
 
295
        self.assertIsInstance(indices.search_path[2],
 
296
            plugin.PluginsHelpIndex)
 
297
 
 
298
    def test_search_for_unknown_topic_raises(self):
 
299
        """Searching for an unknown topic should raise NoHelpTopic."""
 
300
        indices = help.HelpIndices()
 
301
        indices.search_path = []
 
302
        error = self.assertRaises(errors.NoHelpTopic, indices.search, 'foo')
 
303
        self.assertEqual('foo', error.topic)
 
304
 
 
305
    def test_search_calls_get_topic(self):
 
306
        """Searching should call get_topics in all indexes in order."""
 
307
        calls = []
 
308
        class RecordingIndex(object):
 
309
            def __init__(self, name):
 
310
                self.prefix = name
 
311
            def get_topics(self, topic):
 
312
                calls.append(('get_topics', self.prefix, topic))
 
313
                return ['something']
 
314
        index = help.HelpIndices()
 
315
        index.search_path = [RecordingIndex('1'), RecordingIndex('2')]
 
316
        # try with None
 
317
        index.search(None)
 
318
        self.assertEqual([
 
319
            ('get_topics', '1', None),
 
320
            ('get_topics', '2', None),
 
321
            ],
 
322
            calls)
 
323
        # and with a string
 
324
        del calls[:]
 
325
        index.search('bar')
 
326
        self.assertEqual([
 
327
            ('get_topics', '1', 'bar'),
 
328
            ('get_topics', '2', 'bar'),
 
329
            ],
 
330
            calls)
 
331
 
 
332
    def test_search_returns_index_and_results(self):
 
333
        """Searching should return help topics with their index"""
 
334
        class CannedIndex(object):
 
335
            def __init__(self, prefix, search_result):
 
336
                self.prefix = prefix
 
337
                self.result = search_result
 
338
            def get_topics(self, topic):
 
339
                return self.result
 
340
        index = help.HelpIndices()
 
341
        index_one = CannedIndex('1', ['a'])
 
342
        index_two = CannedIndex('2', ['b', 'c'])
 
343
        index.search_path = [index_one, index_two]
 
344
        self.assertEqual([(index_one, 'a'), (index_two, 'b'), (index_two, 'c')],
 
345
            index.search(None))
 
346
 
 
347
    def test_search_checks_for_duplicate_prefixes(self):
 
348
        """Its an error when there are multiple indices with the same prefix."""
 
349
        indices = help.HelpIndices()
 
350
        indices.search_path = [help_topics.HelpTopicIndex(),
 
351
            help_topics.HelpTopicIndex()]
 
352
        self.assertRaises(errors.DuplicateHelpPrefix, indices.search, None)