1
# Copyright (C) 2007 Canonical Ltd
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.
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.
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
17
"""Unit tests for the bzrlib.help module."""
19
from cStringIO import StringIO
32
class TestCommandHelp(tests.TestCase):
33
"""Tests for help on commands."""
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()
43
' -h, --help Show help message.\n'
45
'See also: bar, foo\n')
47
def test_get_help_text(self):
48
"""Commands have a get_help_text method which returns their help."""
49
class cmd_Demo(commands.Command):
50
"""A sample command."""
52
helptext = cmd.get_help_text()
53
self.assertStartsWith(helptext, 'Purpose: A sample command.')
54
self.assertContainsRe(helptext, 'Usage: bzr Demo')
55
self.assertEndsWith(helptext, 'Show help message.\n\n')
57
def test_command_with_additional_see_also(self):
58
class cmd_WithSeeAlso(commands.Command):
59
"""A sample command."""
60
_see_also = ['foo', 'bar']
61
cmd = cmd_WithSeeAlso()
62
helptext = cmd.get_help_text(['gam'])
65
' -h, --help Show help message.\n'
67
'See also: bar, foo, gam\n')
69
def test_command_only_additional_see_also(self):
70
class cmd_WithSeeAlso(commands.Command):
71
"""A sample command."""
72
cmd = cmd_WithSeeAlso()
73
helptext = cmd.get_help_text(['gam'])
76
' -h, --help Show help message.\n'
80
def test_get_help_topic(self):
81
"""The help topic for a Command is its name()."""
82
class cmd_foo_bar(commands.Command):
83
"""A sample command."""
85
self.assertEqual(cmd.name(), cmd.get_help_topic())
88
class TestRegisteredTopic(tests.TestCase):
89
"""Tests for the RegisteredTopic class."""
91
def test_contruct(self):
92
"""Construction takes the help topic name for the registered item."""
94
self.assertTrue('basic' in help_topics.topic_registry)
95
topic = help_topics.RegisteredTopic('basic')
96
self.assertEqual('basic', topic.topic)
98
def test_get_help_text(self):
99
"""A RegisteredTopic returns the get_detail results for get_help_text."""
100
topic = help_topics.RegisteredTopic('commands')
101
self.assertEqual(help_topics.topic_registry.get_detail('commands'),
102
topic.get_help_text())
104
def test_get_help_text_with_additional_see_also(self):
105
topic = help_topics.RegisteredTopic('commands')
107
topic.get_help_text(['foo', 'bar']),
109
'See also: bar, foo\n')
111
def test_get_help_topic(self):
112
"""The help topic for a RegisteredTopic is its topic from construction."""
113
topic = help_topics.RegisteredTopic('foobar')
114
self.assertEqual('foobar', topic.get_help_topic())
115
topic = help_topics.RegisteredTopic('baz')
116
self.assertEqual('baz', topic.get_help_topic())
119
class TestTopicIndex(tests.TestCase):
120
"""Tests for the HelpTopicIndex class."""
122
def test_default_constructable(self):
123
index = help_topics.HelpTopicIndex()
125
def test_get_topics_None(self):
126
"""Searching for None returns the basic help topic."""
127
index = help_topics.HelpTopicIndex()
128
topics = index.get_topics(None)
129
self.assertEqual(1, len(topics))
130
self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
131
self.assertEqual('basic', topics[0].topic)
133
def test_get_topics_topics(self):
134
"""Searching for a string returns the matching string."""
135
index = help_topics.HelpTopicIndex()
136
topics = index.get_topics('topics')
137
self.assertEqual(1, len(topics))
138
self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
139
self.assertEqual('topics', topics[0].topic)
141
def test_get_topics_no_topic(self):
142
"""Searching for something not registered returns []."""
143
index = help_topics.HelpTopicIndex()
144
self.assertEqual([], index.get_topics('nothing by this name'))
146
def test_prefix(self):
147
"""TopicIndex has a prefix of ''."""
148
index = help_topics.HelpTopicIndex()
149
self.assertEqual('', index.prefix)
152
class TestCommandIndex(tests.TestCase):
153
"""Tests for the HelpCommandIndex class."""
155
def test_default_constructable(self):
156
index = commands.HelpCommandIndex()
158
def test_get_topics_None(self):
159
"""Searching for None returns an empty list."""
160
index = commands.HelpCommandIndex()
161
self.assertEqual([], index.get_topics(None))
163
def test_get_topics_rocks(self):
164
"""Searching for 'rocks' returns the cmd_rocks command instance."""
165
index = commands.HelpCommandIndex()
166
topics = index.get_topics('rocks')
167
self.assertEqual(1, len(topics))
168
self.assertIsInstance(topics[0], builtins.cmd_rocks)
170
def test_get_topics_no_topic(self):
171
"""Searching for something that is not a command returns []."""
172
index = commands.HelpCommandIndex()
173
self.assertEqual([], index.get_topics('nothing by this name'))
175
def test_prefix(self):
176
"""CommandIndex has a prefix of 'commands/'."""
177
index = commands.HelpCommandIndex()
178
self.assertEqual('commands/', index.prefix)
180
def test_get_topic_with_prefix(self):
181
"""Searching for commands/rocks returns the rocks command object."""
182
index = commands.HelpCommandIndex()
183
topics = index.get_topics('commands/rocks')
184
self.assertEqual(1, len(topics))
185
self.assertIsInstance(topics[0], builtins.cmd_rocks)
188
class TestHelpIndices(tests.TestCase):
189
"""Tests for the HelpIndices class."""
191
def test_default_search_path(self):
192
"""The default search path should include internal indexs."""
193
indices = help.HelpIndices()
194
self.assertEqual(3, len(indices.search_path))
195
# help topics should be searched in first.
196
self.assertIsInstance(indices.search_path[0],
197
help_topics.HelpTopicIndex)
198
# with commands being search second.
199
self.assertIsInstance(indices.search_path[1],
200
commands.HelpCommandIndex)
201
# and plugins are a third index.
202
self.assertIsInstance(indices.search_path[2],
203
plugin.PluginsHelpIndex)
205
def test_search_for_unknown_topic_raises(self):
206
"""Searching for an unknown topic should raise NoHelpTopic."""
207
indices = help.HelpIndices()
208
indices.search_path = []
209
error = self.assertRaises(errors.NoHelpTopic, indices.search, 'foo')
210
self.assertEqual('foo', error.topic)
212
def test_search_calls_get_topic(self):
213
"""Searching should call get_topics in all indexes in order."""
215
class RecordingIndex(object):
216
def __init__(self, name):
218
def get_topics(self, topic):
219
calls.append(('get_topics', self.prefix, topic))
221
index = help.HelpIndices()
222
index.search_path = [RecordingIndex('1'), RecordingIndex('2')]
226
('get_topics', '1', None),
227
('get_topics', '2', None),
234
('get_topics', '1', 'bar'),
235
('get_topics', '2', 'bar'),
239
def test_search_returns_index_and_results(self):
240
"""Searching should return help topics with their index"""
241
class CannedIndex(object):
242
def __init__(self, prefix, search_result):
244
self.result = search_result
245
def get_topics(self, topic):
247
index = help.HelpIndices()
248
index_one = CannedIndex('1', ['a'])
249
index_two = CannedIndex('2', ['b', 'c'])
250
index.search_path = [index_one, index_two]
251
self.assertEqual([(index_one, 'a'), (index_two, 'b'), (index_two, 'c')],
254
def test_search_checks_for_duplicate_prefixes(self):
255
"""Its an error when there are multiple indices with the same prefix."""
256
indices = help.HelpIndices()
257
indices.search_path = [help_topics.HelpTopicIndex(),
258
help_topics.HelpTopicIndex()]
259
self.assertRaises(errors.DuplicateHelpPrefix, indices.search, None)