~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_help.py

(robertc) Fix lp: urls behind an https proxy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011 Canonical Ltd
 
1
# Copyright (C) 2007-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
"""Unit tests for the bzrlib.help module."""
18
18
 
19
 
import textwrap
 
19
from cStringIO import StringIO
20
20
 
21
21
from bzrlib import (
22
22
    builtins,
23
23
    commands,
24
 
    config,
25
24
    errors,
26
25
    help,
27
26
    help_topics,
28
 
    i18n,
29
27
    plugin,
30
28
    tests,
31
29
    )
32
30
 
33
 
from bzrlib.tests.test_i18n import ZzzTranslations
34
 
import re
 
31
 
 
32
class TestHelp(tests.TestCase):
 
33
 
 
34
    def setUp(self):
 
35
        tests.TestCase.setUp(self)
 
36
        commands.install_bzr_command_hooks()
35
37
 
36
38
 
37
39
class TestCommandHelp(tests.TestCase):
38
40
    """Tests for help on commands."""
39
41
 
40
 
    def assertCmdHelp(self, expected, cmd):
41
 
        self.assertEqualDiff(textwrap.dedent(expected), cmd.get_help_text())
42
 
 
43
42
    def test_command_help_includes_see_also(self):
44
43
        class cmd_WithSeeAlso(commands.Command):
45
44
            __doc__ = """A sample command."""
46
45
            _see_also = ['foo', 'bar']
47
 
        self.assertCmdHelp('''\
48
 
            Purpose: A sample command.
49
 
            Usage:   bzr WithSeeAlso
50
 
            
51
 
            Options:
52
 
              --usage        Show usage message and options.
53
 
              -v, --verbose  Display more information.
54
 
              -q, --quiet    Only display errors and warnings.
55
 
              -h, --help     Show help message.
56
 
            
57
 
            See also: bar, foo
58
 
            ''',
59
 
                           cmd_WithSeeAlso())
 
46
        cmd = cmd_WithSeeAlso()
 
47
        helptext = cmd.get_help_text()
 
48
        self.assertEndsWith(
 
49
            helptext,
 
50
            '  -v, --verbose  Display more information.\n'
 
51
            '  -q, --quiet    Only display errors and warnings.\n'
 
52
            '  -h, --help     Show help message.\n'
 
53
            '\n'
 
54
            'See also: bar, foo\n')
60
55
 
61
56
    def test_get_help_text(self):
62
57
        """Commands have a get_help_text method which returns their help."""
63
58
        class cmd_Demo(commands.Command):
64
59
            __doc__ = """A sample command."""
65
 
        self.assertCmdHelp('''\
66
 
            Purpose: A sample command.
67
 
            Usage:   bzr Demo
68
 
            
69
 
            Options:
70
 
              --usage        Show usage message and options.
71
 
              -v, --verbose  Display more information.
72
 
              -q, --quiet    Only display errors and warnings.
73
 
              -h, --help     Show help message.
74
 
 
75
 
            ''',
76
 
                           cmd_Demo())
77
60
        cmd = cmd_Demo()
78
61
        helptext = cmd.get_help_text()
79
62
        self.assertStartsWith(helptext,
129
112
                Example 2::
130
113
 
131
114
                    cmd arg2
132
 
 
133
 
                A code block follows.
134
 
 
135
 
                ::
136
 
 
137
 
                    bzr Demo something
138
115
            """
139
116
        cmd = cmd_Demo()
140
117
        helptext = cmd.get_help_text()
145
122
            '\n'
146
123
            'Options:\n'
147
124
            '  --usage        Show usage message and options.\n'
 
125
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
148
126
            '  -v, --verbose  Display more information.\n'
149
127
            '  -q, --quiet    Only display errors and warnings.\n'
150
128
            '  -h, --help     Show help message.\n'
157
135
            '    Example 2:\n'
158
136
            '\n'
159
137
            '        cmd arg2\n'
160
 
            '\n'
161
 
            '    A code block follows.\n'
162
 
            '\n'
163
 
            '        bzr Demo something\n'
164
138
            '\n')
165
139
        helptext = cmd.get_help_text(plain=False)
166
140
        self.assertEquals(helptext,
169
143
            '\n'
170
144
            ':Options:\n'
171
145
            '  --usage        Show usage message and options.\n'
 
146
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
172
147
            '  -v, --verbose  Display more information.\n'
173
148
            '  -q, --quiet    Only display errors and warnings.\n'
174
149
            '  -h, --help     Show help message.\n'
181
156
            '    Example 2::\n'
182
157
            '\n'
183
158
            '        cmd arg2\n'
184
 
            '\n'
185
 
            '    A code block follows.\n'
186
 
            '\n'
187
 
            '    ::\n'
188
 
            '\n'
189
 
            '        bzr Demo something\n'
190
159
            '\n')
191
160
 
192
161
    def test_concise_help_text(self):
210
179
            '\n'
211
180
            'Options:\n'
212
181
            '  --usage        Show usage message and options.\n'
 
182
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
213
183
            '  -v, --verbose  Display more information.\n'
214
184
            '  -q, --quiet    Only display errors and warnings.\n'
215
185
            '  -h, --help     Show help message.\n'
229
199
            '\n'
230
200
            'Options:\n'
231
201
            '  --usage        Show usage message and options.\n'
 
202
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
232
203
            '  -v, --verbose  Display more information.\n'
233
204
            '  -q, --quiet    Only display errors and warnings.\n'
234
205
            '  -h, --help     Show help message.\n'
263
234
            '\n'
264
235
            'Options:\n'
265
236
            '  --usage        Show usage message and options.\n'
 
237
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
266
238
            '  -v, --verbose  Display more information.\n'
267
239
            '  -q, --quiet    Only display errors and warnings.\n'
268
240
            '  -h, --help     Show help message.\n'
306
278
            '\n'
307
279
            'Options:\n'
308
280
            '  --usage        Show usage message and options.\n'
 
281
            '  -0, --null     Use an ASCII NUL (\\0) separator rather than a newline.\n'
309
282
            '  -v, --verbose  Display more information.\n'
310
283
            '  -q, --quiet    Only display errors and warnings.\n'
311
284
            '  -h, --help     Show help message.\n'
314
287
            '  Blah blah blah.\n\n')
315
288
 
316
289
 
317
 
class ZzzTranslationsForDoc(ZzzTranslations):
318
 
 
319
 
    _section_pat = re.compile(':\w+:\\n\\s+')
320
 
    _indent_pat = re.compile('\\s+')
321
 
 
322
 
    def zzz(self, s):
323
 
        m = self._section_pat.match(s)
324
 
        if m is None:
325
 
            m = self._indent_pat.match(s)
326
 
        if m:
327
 
            return u'%szz{{%s}}' % (m.group(0), s[m.end():])
328
 
        return u'zz{{%s}}' % s
329
 
 
330
 
 
331
 
class TestCommandHelpI18n(tests.TestCase):
332
 
    """Tests for help on translated commands."""
333
 
 
334
 
    def setUp(self):
335
 
        super(TestCommandHelpI18n, self).setUp()
336
 
        self.overrideAttr(i18n, '_translations', ZzzTranslationsForDoc())
337
 
 
338
 
    def assertCmdHelp(self, expected, cmd):
339
 
        self.assertEqualDiff(textwrap.dedent(expected), cmd.get_help_text())
340
 
 
341
 
    def test_command_help_includes_see_also(self):
342
 
        class cmd_WithSeeAlso(commands.Command):
343
 
            __doc__ = """A sample command."""
344
 
            _see_also = ['foo', 'bar']
345
 
        self.assertCmdHelp('''\
346
 
            zz{{:Purpose: zz{{A sample command.}}
347
 
            }}zz{{:Usage:   bzr WithSeeAlso
348
 
            }}
349
 
            zz{{:Options:
350
 
              --usage        zz{{Show usage message and options.}}
351
 
              -v, --verbose  zz{{Display more information.}}
352
 
              -q, --quiet    zz{{Only display errors and warnings.}}
353
 
              -h, --help     zz{{Show help message.}}
354
 
            }}
355
 
            zz{{:See also: bar, foo}}
356
 
            ''',
357
 
                           cmd_WithSeeAlso())
358
 
 
359
 
    def test_get_help_text(self):
360
 
        """Commands have a get_help_text method which returns their help."""
361
 
        class cmd_Demo(commands.Command):
362
 
            __doc__ = """A sample command."""
363
 
        self.assertCmdHelp('''\
364
 
            zz{{:Purpose: zz{{A sample command.}}
365
 
            }}zz{{:Usage:   bzr Demo
366
 
            }}
367
 
            zz{{:Options:
368
 
              --usage        zz{{Show usage message and options.}}
369
 
              -v, --verbose  zz{{Display more information.}}
370
 
              -q, --quiet    zz{{Only display errors and warnings.}}
371
 
              -h, --help     zz{{Show help message.}}
372
 
            }}
373
 
            ''',
374
 
                           cmd_Demo())
375
 
 
376
 
    def test_command_with_additional_see_also(self):
377
 
        class cmd_WithSeeAlso(commands.Command):
378
 
            __doc__ = """A sample command."""
379
 
            _see_also = ['foo', 'bar']
380
 
        cmd = cmd_WithSeeAlso()
381
 
        helptext = cmd.get_help_text(['gam'])
382
 
        self.assertEndsWith(
383
 
            helptext,
384
 
            '  -v, --verbose  zz{{Display more information.}}\n'
385
 
            '  -q, --quiet    zz{{Only display errors and warnings.}}\n'
386
 
            '  -h, --help     zz{{Show help message.}}\n'
387
 
            '}}\n'
388
 
            'zz{{:See also: bar, foo, gam}}\n')
389
 
 
390
 
    def test_command_only_additional_see_also(self):
391
 
        class cmd_WithSeeAlso(commands.Command):
392
 
            __doc__ = """A sample command."""
393
 
        cmd = cmd_WithSeeAlso()
394
 
        helptext = cmd.get_help_text(['gam'])
395
 
        self.assertEndsWith(
396
 
            helptext,
397
 
            'zz{{:Options:\n'
398
 
            '  --usage        zz{{Show usage message and options.}}\n'
399
 
            '  -v, --verbose  zz{{Display more information.}}\n'
400
 
            '  -q, --quiet    zz{{Only display errors and warnings.}}\n'
401
 
            '  -h, --help     zz{{Show help message.}}\n'
402
 
            '}}\n'
403
 
            'zz{{:See also: gam}}\n')
404
 
 
405
 
 
406
 
    def test_help_custom_section_ordering(self):
407
 
        """Custom descriptive sections should remain in the order given."""
408
 
        # The help formatter expect the class name to start with 'cmd_'
409
 
        class cmd_Demo(commands.Command):
410
 
            __doc__ = """A sample command.
411
 
 
412
 
            Blah blah blah.
413
 
 
414
 
            :Formats:
415
 
              Interesting stuff about formats.
416
 
 
417
 
            :Examples:
418
 
              Example 1::
419
 
 
420
 
                cmd arg1
421
 
 
422
 
            :Tips:
423
 
              Clever things to keep in mind.
424
 
            """
425
 
        self.assertCmdHelp('''\
426
 
            zz{{:Purpose: zz{{A sample command.}}
427
 
            }}zz{{:Usage:   bzr Demo
428
 
            }}
429
 
            zz{{:Options:
430
 
              --usage        zz{{Show usage message and options.}}
431
 
              -v, --verbose  zz{{Display more information.}}
432
 
              -q, --quiet    zz{{Only display errors and warnings.}}
433
 
              -h, --help     zz{{Show help message.}}
434
 
            }}
435
 
            Description:
436
 
              zz{{zz{{Blah blah blah.}}
437
 
            
438
 
            }}:Formats:
439
 
              zz{{Interesting stuff about formats.}}
440
 
            
441
 
            Examples:
442
 
              zz{{Example 1::}}
443
 
            
444
 
                zz{{cmd arg1}}
445
 
            
446
 
            Tips:
447
 
              zz{{Clever things to keep in mind.}}
448
 
 
449
 
            ''',
450
 
                           cmd_Demo())
451
 
 
452
 
    def test_help_text_custom_usage(self):
453
 
        """Help text may contain a custom usage section."""
454
 
        class cmd_Demo(commands.Command):
455
 
            __doc__ = """A sample command.
456
 
 
457
 
            :Usage:
458
 
                cmd Demo [opts] args
459
 
 
460
 
                cmd Demo -h
461
 
 
462
 
            Blah blah blah.
463
 
            """
464
 
        self.assertCmdHelp('''\
465
 
            zz{{:Purpose: zz{{A sample command.}}
466
 
            }}zz{{:Usage:
467
 
                zz{{cmd Demo [opts] args}}
468
 
            
469
 
                zz{{cmd Demo -h}}
470
 
 
471
 
            }}
472
 
            zz{{:Options:
473
 
              --usage        zz{{Show usage message and options.}}
474
 
              -v, --verbose  zz{{Display more information.}}
475
 
              -q, --quiet    zz{{Only display errors and warnings.}}
476
 
              -h, --help     zz{{Show help message.}}
477
 
            }}
478
 
            Description:
479
 
              zz{{zz{{Blah blah blah.}}
480
 
 
481
 
            }}
482
 
            ''',
483
 
                           cmd_Demo())
484
 
 
485
 
 
486
 
class TestHelp(tests.TestCase):
487
 
 
488
 
    def setUp(self):
489
 
        tests.TestCase.setUp(self)
490
 
        commands.install_bzr_command_hooks()
491
 
 
492
 
 
493
290
class TestRegisteredTopic(TestHelp):
494
291
    """Tests for the RegisteredTopic class."""
495
292
 
501
298
        self.assertEqual('basic', topic.topic)
502
299
 
503
300
    def test_get_help_text(self):
504
 
        """RegisteredTopic returns the get_detail results for get_help_text."""
 
301
        """A RegisteredTopic returns the get_detail results for get_help_text."""
505
302
        topic = help_topics.RegisteredTopic('commands')
506
303
        self.assertEqual(help_topics.topic_registry.get_detail('commands'),
507
 
                         topic.get_help_text())
 
304
            topic.get_help_text())
508
305
 
509
306
    def test_get_help_text_with_additional_see_also(self):
510
307
        topic = help_topics.RegisteredTopic('commands')
522
319
            '\n')
523
320
 
524
321
    def test_get_help_topic(self):
525
 
        """The help topic for RegisteredTopic is its topic from construction."""
 
322
        """The help topic for a RegisteredTopic is its topic from construction."""
526
323
        topic = help_topics.RegisteredTopic('foobar')
527
324
        self.assertEqual('foobar', topic.get_help_topic())
528
325
        topic = help_topics.RegisteredTopic('baz')
562
359
        self.assertEqual('', index.prefix)
563
360
 
564
361
 
565
 
class TestConfigOptionIndex(TestHelp):
566
 
    """Tests for the HelpCommandIndex class."""
567
 
 
568
 
    def setUp(self):
569
 
        super(TestConfigOptionIndex, self).setUp()
570
 
        self.index = help_topics.ConfigOptionHelpIndex()
571
 
 
572
 
    def test_get_topics_None(self):
573
 
        """Searching for None returns an empty list."""
574
 
        self.assertEqual([], self.index.get_topics(None))
575
 
 
576
 
    def test_get_topics_no_topic(self):
577
 
        self.assertEqual([], self.index.get_topics('nothing by this name'))
578
 
 
579
 
    def test_prefix(self):
580
 
        self.assertEqual('configuration/', self.index.prefix)
581
 
 
582
 
    def test_get_topic_with_prefix(self):
583
 
        topics = self.index.get_topics('configuration/default_format')
584
 
        self.assertLength(1, topics)
585
 
        opt = topics[0]
586
 
        self.assertIsInstance(opt, config.Option)
587
 
        self.assertEquals('default_format', opt.name)
588
 
 
589
 
 
590
362
class TestCommandIndex(TestHelp):
591
363
    """Tests for the HelpCommandIndex class."""
592
364
 
629
401
    def test_default_search_path(self):
630
402
        """The default search path should include internal indexs."""
631
403
        indices = help.HelpIndices()
632
 
        self.assertEqual(4, len(indices.search_path))
 
404
        self.assertEqual(3, len(indices.search_path))
633
405
        # help topics should be searched in first.
634
406
        self.assertIsInstance(indices.search_path[0],
635
 
                              help_topics.HelpTopicIndex)
 
407
            help_topics.HelpTopicIndex)
636
408
        # with commands being search second.
637
409
        self.assertIsInstance(indices.search_path[1],
638
 
                              commands.HelpCommandIndex)
639
 
        # plugins are a third index.
 
410
            commands.HelpCommandIndex)
 
411
        # and plugins are a third index.
640
412
        self.assertIsInstance(indices.search_path[2],
641
 
                              plugin.PluginsHelpIndex)
642
 
        # config options are a fourth index
643
 
        self.assertIsInstance(indices.search_path[3],
644
 
                              help_topics.ConfigOptionHelpIndex)
 
413
            plugin.PluginsHelpIndex)
645
414
 
646
415
    def test_search_for_unknown_topic_raises(self):
647
416
        """Searching for an unknown topic should raise NoHelpTopic."""