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, 'usage: bzr Demo')
54
self.assertEndsWith(helptext, 'show help message\n')
56
def test_command_with_additional_see_also(self):
57
class cmd_WithSeeAlso(commands.Command):
58
"""A sample command."""
59
_see_also = ['foo', 'bar']
60
cmd = cmd_WithSeeAlso()
61
helptext = cmd.get_help_text(['gam'])
64
' -h, --help show help message\n'
66
'See also: bar, foo, gam\n')
68
def test_command_only_additional_see_also(self):
69
class cmd_WithSeeAlso(commands.Command):
70
"""A sample command."""
71
cmd = cmd_WithSeeAlso()
72
helptext = cmd.get_help_text(['gam'])
75
' -h, --help show help message\n'
79
def test_get_help_topic(self):
80
"""The help topic for a Command is its name()."""
81
class cmd_foo_bar(commands.Command):
82
"""A sample command."""
84
self.assertEqual(cmd.name(), cmd.get_help_topic())
87
class TestRegisteredTopic(tests.TestCase):
88
"""Tests for the RegisteredTopic class."""
90
def test_contruct(self):
91
"""Construction takes the help topic name for the registered item."""
93
self.assertTrue('basic' in help_topics.topic_registry)
94
topic = help_topics.RegisteredTopic('basic')
95
self.assertEqual('basic', topic.topic)
97
def test_get_help_text(self):
98
"""A RegisteredTopic returns the get_detail results for get_help_text."""
99
topic = help_topics.RegisteredTopic('commands')
100
self.assertEqual(help_topics.topic_registry.get_detail('commands'),
101
topic.get_help_text())
103
def test_get_help_text_with_additional_see_also(self):
104
topic = help_topics.RegisteredTopic('commands')
106
topic.get_help_text(['foo', 'bar']),
108
'See also: bar, foo\n')
110
def test_get_help_topic(self):
111
"""The help topic for a RegisteredTopic is its topic from construction."""
112
topic = help_topics.RegisteredTopic('foobar')
113
self.assertEqual('foobar', topic.get_help_topic())
114
topic = help_topics.RegisteredTopic('baz')
115
self.assertEqual('baz', topic.get_help_topic())
118
class TestTopicIndex(tests.TestCase):
119
"""Tests for the HelpTopicIndex class."""
121
def test_default_constructable(self):
122
index = help_topics.HelpTopicIndex()
124
def test_get_topics_None(self):
125
"""Searching for None returns the basic help topic."""
126
index = help_topics.HelpTopicIndex()
127
topics = index.get_topics(None)
128
self.assertEqual(1, len(topics))
129
self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
130
self.assertEqual('basic', topics[0].topic)
132
def test_get_topics_topics(self):
133
"""Searching for a string returns the matching string."""
134
index = help_topics.HelpTopicIndex()
135
topics = index.get_topics('topics')
136
self.assertEqual(1, len(topics))
137
self.assertIsInstance(topics[0], help_topics.RegisteredTopic)
138
self.assertEqual('topics', topics[0].topic)
140
def test_get_topics_no_topic(self):
141
"""Searching for something not registered returns []."""
142
index = help_topics.HelpTopicIndex()
143
self.assertEqual([], index.get_topics('nothing by this name'))
145
def test_prefix(self):
146
"""TopicIndex has a prefix of ''."""
147
index = help_topics.HelpTopicIndex()
148
self.assertEqual('', index.prefix)
151
class TestCommandIndex(tests.TestCase):
152
"""Tests for the HelpCommandIndex class."""
154
def test_default_constructable(self):
155
index = commands.HelpCommandIndex()
157
def test_get_topics_None(self):
158
"""Searching for None returns an empty list."""
159
index = commands.HelpCommandIndex()
160
self.assertEqual([], index.get_topics(None))
162
def test_get_topics_rocks(self):
163
"""Searching for 'rocks' returns the cmd_rocks command instance."""
164
index = commands.HelpCommandIndex()
165
topics = index.get_topics('rocks')
166
self.assertEqual(1, len(topics))
167
self.assertIsInstance(topics[0], builtins.cmd_rocks)
169
def test_get_topics_no_topic(self):
170
"""Searching for something that is not a command returns []."""
171
index = commands.HelpCommandIndex()
172
self.assertEqual([], index.get_topics('nothing by this name'))
174
def test_prefix(self):
175
"""CommandIndex has a prefix of 'commands/'."""
176
index = commands.HelpCommandIndex()
177
self.assertEqual('commands/', index.prefix)
179
def test_get_topic_with_prefix(self):
180
"""Searching for commands/rocks returns the rocks command object."""
181
index = commands.HelpCommandIndex()
182
topics = index.get_topics('commands/rocks')
183
self.assertEqual(1, len(topics))
184
self.assertIsInstance(topics[0], builtins.cmd_rocks)
187
class TestHelpIndices(tests.TestCase):
188
"""Tests for the HelpIndices class."""
190
def test_default_search_path(self):
191
"""The default search path should include internal indexs."""
192
indices = help.HelpIndices()
193
self.assertEqual(3, len(indices.search_path))
194
# help topics should be searched in first.
195
self.assertIsInstance(indices.search_path[0],
196
help_topics.HelpTopicIndex)
197
# with commands being search second.
198
self.assertIsInstance(indices.search_path[1],
199
commands.HelpCommandIndex)
200
# and plugins are a third index.
201
self.assertIsInstance(indices.search_path[2],
202
plugin.PluginsHelpIndex)
204
def test_search_for_unknown_topic_raises(self):
205
"""Searching for an unknown topic should raise NoHelpTopic."""
206
indices = help.HelpIndices()
207
indices.search_path = []
208
error = self.assertRaises(errors.NoHelpTopic, indices.search, 'foo')
209
self.assertEqual('foo', error.topic)
211
def test_search_calls_get_topic(self):
212
"""Searching should call get_topics in all indexes in order."""
214
class RecordingIndex(object):
215
def __init__(self, name):
217
def get_topics(self, topic):
218
calls.append(('get_topics', self.prefix, topic))
220
index = help.HelpIndices()
221
index.search_path = [RecordingIndex('1'), RecordingIndex('2')]
225
('get_topics', '1', None),
226
('get_topics', '2', None),
233
('get_topics', '1', 'bar'),
234
('get_topics', '2', 'bar'),
238
def test_search_returns_index_and_results(self):
239
"""Searching should return help topics with their index"""
240
class CannedIndex(object):
241
def __init__(self, prefix, search_result):
243
self.result = search_result
244
def get_topics(self, topic):
246
index = help.HelpIndices()
247
index_one = CannedIndex('1', ['a'])
248
index_two = CannedIndex('2', ['b', 'c'])
249
index.search_path = [index_one, index_two]
250
self.assertEqual([(index_one, 'a'), (index_two, 'b'), (index_two, 'c')],
253
def test_search_checks_for_duplicate_prefixes(self):
254
"""Its an error when there are multiple indices with the same prefix."""
255
indices = help.HelpIndices()
256
indices.search_path = [help_topics.HelpTopicIndex(),
257
help_topics.HelpTopicIndex()]
258
self.assertRaises(errors.DuplicateHelpPrefix, indices.search, None)