/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 breezy/tests/test_plugins.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-01 23:52:12 UTC
  • mfrom: (0.140.55 bzr-stats)
  • mto: This revision was merged to the branch mainline in revision 6646.
  • Revision ID: jelmer@jelmer.uk-20170601235212-twcndojyo32c5wkp
Bundle the stats plugin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2012, 2016 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
17
17
"""Tests for plugins"""
18
18
 
19
19
# XXX: There are no plugin tests at the moment because the plugin module
20
 
# affects the global state of the process.  See bzrlib/plugins.py for more
 
20
# affects the global state of the process.  See breezy/plugins.py for more
21
21
# comments.
22
22
 
23
 
from cStringIO import StringIO
24
23
import logging
25
24
import os
26
25
import sys
27
26
 
28
 
import bzrlib
29
 
from bzrlib import (
 
27
import breezy
 
28
from .. import (
 
29
    errors,
30
30
    osutils,
31
31
    plugin,
32
32
    plugins,
33
33
    tests,
34
34
    trace,
35
35
    )
 
36
from ..sixish import (
 
37
    BytesIO,
 
38
    )
36
39
 
37
40
 
38
41
# TODO: Write a test for plugin decoration of commands.
39
42
 
40
 
class TestPluginMixin(object):
 
43
class BaseTestPlugins(tests.TestCaseInTempDir):
41
44
 
42
45
    def create_plugin(self, name, source=None, dir='.', file_name=None):
43
46
        if source is None:
72
75
                           file_name='__init__.py')
73
76
 
74
77
    def _unregister_plugin(self, name):
75
 
        """Remove the plugin from sys.modules and the bzrlib namespace."""
76
 
        py_name = 'bzrlib.plugins.%s' % name
77
 
        if py_name in sys.modules:
78
 
            del sys.modules[py_name]
79
 
        if getattr(bzrlib.plugins, name, None) is not None:
80
 
            delattr(bzrlib.plugins, name)
 
78
        """Remove the plugin from sys.modules and the breezy namespace."""
 
79
        py_name = 'breezy.plugins.%s' % name
 
80
        if py_name in sys.modules:
 
81
            del sys.modules[py_name]
 
82
        if getattr(breezy.plugins, name, None) is not None:
 
83
            delattr(breezy.plugins, name)
 
84
 
 
85
    def _unregister_plugin_submodule(self, plugin_name, submodule_name):
 
86
        """Remove the submodule from sys.modules and the breezy namespace."""
 
87
        py_name = 'breezy.plugins.%s.%s' % (plugin_name, submodule_name)
 
88
        if py_name in sys.modules:
 
89
            del sys.modules[py_name]
 
90
        plugin = getattr(breezy.plugins, plugin_name, None)
 
91
        if plugin is not None:
 
92
            if getattr(plugin, submodule_name, None) is not None:
 
93
                delattr(plugin, submodule_name)
81
94
 
82
95
    def assertPluginUnknown(self, name):
83
 
        self.failIf(getattr(bzrlib.plugins, name, None) is not None)
84
 
        self.failIf('bzrlib.plugins.%s' % name in sys.modules)
 
96
        self.assertFalse(getattr(breezy.plugins, name, None) is not None)
 
97
        self.assertFalse('breezy.plugins.%s' % name in sys.modules)
85
98
 
86
99
    def assertPluginKnown(self, name):
87
 
        self.failUnless(getattr(bzrlib.plugins, name, None) is not None)
88
 
        self.failUnless('bzrlib.plugins.%s' % name in sys.modules)
89
 
 
90
 
 
91
 
class TestLoadingPlugins(tests.TestCaseInTempDir, TestPluginMixin):
 
100
        self.assertTrue(getattr(breezy.plugins, name, None) is not None)
 
101
        self.assertTrue('breezy.plugins.%s' % name in sys.modules)
 
102
 
 
103
 
 
104
class TestLoadingPlugins(BaseTestPlugins):
92
105
 
93
106
    activeattributes = {}
94
107
 
98
111
        # file name we can use which is also a valid attribute for accessing in
99
112
        # activeattributes. - we cannot give import parameters.
100
113
        tempattribute = "0"
101
 
        self.failIf(tempattribute in self.activeattributes)
 
114
        self.assertFalse(tempattribute in self.activeattributes)
102
115
        # set a place for the plugins to record their loading, and at the same
103
116
        # time validate that the location the plugins should record to is
104
117
        # valid and correct.
105
118
        self.__class__.activeattributes [tempattribute] = []
106
 
        self.failUnless(tempattribute in self.activeattributes)
 
119
        self.assertTrue(tempattribute in self.activeattributes)
107
120
        # create two plugin directories
108
121
        os.mkdir('first')
109
122
        os.mkdir('second')
110
123
        # write a plugin that will record when its loaded in the
111
124
        # tempattribute list.
112
 
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
125
        template = ("from breezy.tests.test_plugins import TestLoadingPlugins\n"
113
126
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
114
127
 
115
128
        outfile = open(os.path.join('first', 'plugin.py'), 'w')
127
140
            outfile.close()
128
141
 
129
142
        try:
130
 
            bzrlib.plugin.load_from_path(['first', 'second'])
 
143
            breezy.plugin.load_from_path(['first', 'second'])
131
144
            self.assertEqual(['first'], self.activeattributes[tempattribute])
132
145
        finally:
133
146
            # remove the plugin 'plugin'
136
149
        self.assertPluginUnknown('plugin')
137
150
 
138
151
    def test_plugins_from_different_dirs_can_demand_load(self):
139
 
        self.failIf('bzrlib.plugins.pluginone' in sys.modules)
140
 
        self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
 
152
        self.assertFalse('breezy.plugins.pluginone' in sys.modules)
 
153
        self.assertFalse('breezy.plugins.plugintwo' in sys.modules)
141
154
        # This test tests that having two plugins in different
142
155
        # directories with different names allows them both to be loaded, when
143
156
        # we do a direct import statement.
144
157
        # Determine a file name we can use which is also a valid attribute
145
158
        # for accessing in activeattributes. - we cannot give import parameters.
146
159
        tempattribute = "different-dirs"
147
 
        self.failIf(tempattribute in self.activeattributes)
 
160
        self.assertFalse(tempattribute in self.activeattributes)
148
161
        # set a place for the plugins to record their loading, and at the same
149
162
        # time validate that the location the plugins should record to is
150
163
        # valid and correct.
151
 
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
 
164
        breezy.tests.test_plugins.TestLoadingPlugins.activeattributes \
152
165
            [tempattribute] = []
153
 
        self.failUnless(tempattribute in self.activeattributes)
 
166
        self.assertTrue(tempattribute in self.activeattributes)
154
167
        # create two plugin directories
155
168
        os.mkdir('first')
156
169
        os.mkdir('second')
157
170
        # write plugins that will record when they are loaded in the
158
171
        # tempattribute list.
159
 
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
172
        template = ("from breezy.tests.test_plugins import TestLoadingPlugins\n"
160
173
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
161
174
 
162
175
        outfile = open(os.path.join('first', 'pluginone.py'), 'w')
173
186
        finally:
174
187
            outfile.close()
175
188
 
176
 
        oldpath = bzrlib.plugins.__path__
 
189
        oldpath = breezy.plugins.__path__
177
190
        try:
178
 
            self.failIf('bzrlib.plugins.pluginone' in sys.modules)
179
 
            self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
180
 
            bzrlib.plugins.__path__ = ['first', 'second']
181
 
            exec "import bzrlib.plugins.pluginone"
 
191
            self.assertFalse('breezy.plugins.pluginone' in sys.modules)
 
192
            self.assertFalse('breezy.plugins.plugintwo' in sys.modules)
 
193
            breezy.plugins.__path__ = ['first', 'second']
 
194
            exec("import breezy.plugins.pluginone")
182
195
            self.assertEqual(['first'], self.activeattributes[tempattribute])
183
 
            exec "import bzrlib.plugins.plugintwo"
 
196
            exec("import breezy.plugins.plugintwo")
184
197
            self.assertEqual(['first', 'second'],
185
198
                self.activeattributes[tempattribute])
186
199
        finally:
197
210
        # check the plugin is not loaded already
198
211
        self.assertPluginUnknown('ts_plugin')
199
212
        tempattribute = "trailing-slash"
200
 
        self.failIf(tempattribute in self.activeattributes)
 
213
        self.assertFalse(tempattribute in self.activeattributes)
201
214
        # set a place for the plugin to record its loading, and at the same
202
215
        # time validate that the location the plugin should record to is
203
216
        # valid and correct.
204
 
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
 
217
        breezy.tests.test_plugins.TestLoadingPlugins.activeattributes \
205
218
            [tempattribute] = []
206
 
        self.failUnless(tempattribute in self.activeattributes)
 
219
        self.assertTrue(tempattribute in self.activeattributes)
207
220
        # create a directory for the plugin
208
221
        os.mkdir('plugin_test')
209
222
        # write a plugin that will record when its loaded in the
210
223
        # tempattribute list.
211
 
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
224
        template = ("from breezy.tests.test_plugins import TestLoadingPlugins\n"
212
225
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
213
226
 
214
227
        outfile = open(os.path.join('plugin_test', 'ts_plugin.py'), 'w')
219
232
            outfile.close()
220
233
 
221
234
        try:
222
 
            bzrlib.plugin.load_from_path(['plugin_test'+os.sep])
 
235
            breezy.plugin.load_from_path(['plugin_test'+os.sep])
223
236
            self.assertEqual(['plugin'], self.activeattributes[tempattribute])
224
237
        finally:
225
238
            del self.activeattributes[tempattribute]
233
246
        :return: A string with the log from the plugin loading call.
234
247
        """
235
248
        # Capture output
236
 
        stream = StringIO()
 
249
        stream = BytesIO()
237
250
        try:
238
251
            handler = logging.StreamHandler(stream)
239
 
            log = logging.getLogger('bzr')
 
252
            log = logging.getLogger('brz')
240
253
            log.addHandler(handler)
241
254
            try:
242
255
                try:
243
 
                    bzrlib.plugin.load_from_path(['.'])
 
256
                    breezy.plugin.load_from_path(['.'])
244
257
                finally:
245
 
                    if 'bzrlib.plugins.%s' % name in sys.modules:
246
 
                        del sys.modules['bzrlib.plugins.%s' % name]
247
 
                    if getattr(bzrlib.plugins, name, None):
248
 
                        delattr(bzrlib.plugins, name)
 
258
                    if 'breezy.plugins.%s' % name in sys.modules:
 
259
                        del sys.modules['breezy.plugins.%s' % name]
 
260
                    if getattr(breezy.plugins, name, None):
 
261
                        delattr(breezy.plugins, name)
249
262
            finally:
250
263
                # Stop capturing output
251
264
                handler.flush()
256
269
            stream.close()
257
270
 
258
271
    def test_plugin_with_bad_api_version_reports(self):
259
 
        # This plugin asks for bzrlib api version 1.0.0, which is not supported
260
 
        # anymore.
 
272
        """Try loading a plugin that requests an unsupported api.
 
273
        
 
274
        Observe that it records the problem but doesn't complain on stderr.
 
275
 
 
276
        See https://bugs.launchpad.net/bzr/+bug/704195
 
277
        """
 
278
        self.overrideAttr(plugin, 'plugin_warnings', {})
261
279
        name = 'wants100.py'
262
280
        f = file(name, 'w')
263
281
        try:
264
 
            f.write("import bzrlib.api\n"
265
 
                "bzrlib.api.require_any_api(bzrlib, [(1, 0, 0)])\n")
 
282
            f.write("import breezy.api\n"
 
283
                "breezy.api.require_any_api(breezy, [(1, 0, 0)])\n")
266
284
        finally:
267
285
            f.close()
268
 
 
269
286
        log = self.load_and_capture(name)
270
 
        self.assertContainsRe(log,
 
287
        self.assertNotContainsRe(log,
 
288
            r"It requested API version")
 
289
        self.assertEqual(
 
290
            ['wants100'],
 
291
            plugin.plugin_warnings.keys())
 
292
        self.assertContainsRe(
 
293
            plugin.plugin_warnings['wants100'][0],
271
294
            r"It requested API version")
272
295
 
273
296
    def test_plugin_with_bad_name_does_not_load(self):
274
297
        # The file name here invalid for a python module.
275
 
        name = 'bzr-bad plugin-name..py'
 
298
        name = 'brz-bad plugin-name..py'
276
299
        file(name, 'w').close()
277
300
        log = self.load_and_capture(name)
278
301
        self.assertContainsRe(log,
279
 
            r"Unable to load 'bzr-bad plugin-name\.' in '\.' as a plugin "
 
302
            r"Unable to load 'brz-bad plugin-name\.' in '\.' as a plugin "
280
303
            "because the file path isn't a valid module name; try renaming "
281
304
            "it to 'bad_plugin_name_'\.")
282
305
 
283
306
 
284
 
class TestPlugins(tests.TestCaseInTempDir, TestPluginMixin):
 
307
class TestPlugins(BaseTestPlugins):
285
308
 
286
309
    def setup_plugin(self, source=""):
287
 
        # This test tests a new plugin appears in bzrlib.plugin.plugins().
 
310
        # This test tests a new plugin appears in breezy.plugin.plugins().
288
311
        # check the plugin is not loaded already
289
312
        self.assertPluginUnknown('plugin')
290
313
        # write a plugin that _cannot_ fail to load.
291
 
        file('plugin.py', 'w').write(source + '\n')
 
314
        with file('plugin.py', 'w') as f: f.write(source + '\n')
292
315
        self.addCleanup(self.teardown_plugin)
293
316
        plugin.load_from_path(['.'])
294
317
 
300
323
        self.setup_plugin()
301
324
        self.assertPluginKnown('plugin')
302
325
        p = plugin.plugins()['plugin']
303
 
        self.assertIsInstance(p, bzrlib.plugin.PlugIn)
 
326
        self.assertIsInstance(p, breezy.plugin.PlugIn)
304
327
        self.assertEqual(p.module, plugins.plugin)
305
328
 
306
329
    def test_trivial_plugin_get_path(self):
350
373
 
351
374
    def test_load_plugin_tests_gives_load_plugin_tests_result(self):
352
375
        source = """
353
 
def load_tests(standard_tests, module, loader):
 
376
def load_tests(loader, standard_tests, pattern):
354
377
    return 'foo'"""
355
378
        self.setup_plugin(source)
356
379
        loader = tests.TestUtil.TestLoader()
380
403
 
381
404
    def test_no_version_info___version__(self):
382
405
        self.setup_plugin()
383
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
406
        plugin = breezy.plugin.plugins()['plugin']
384
407
        self.assertEqual("unknown", plugin.__version__)
385
408
 
386
409
    def test_str__version__with_version_info(self):
387
410
        self.setup_plugin("version_info = '1.2.3'")
388
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
411
        plugin = breezy.plugin.plugins()['plugin']
389
412
        self.assertEqual("1.2.3", plugin.__version__)
390
413
 
391
414
    def test_noniterable__version__with_version_info(self):
392
415
        self.setup_plugin("version_info = (1)")
393
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
416
        plugin = breezy.plugin.plugins()['plugin']
394
417
        self.assertEqual("1", plugin.__version__)
395
418
 
396
419
    def test_1__version__with_version_info(self):
397
420
        self.setup_plugin("version_info = (1,)")
398
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
421
        plugin = breezy.plugin.plugins()['plugin']
399
422
        self.assertEqual("1", plugin.__version__)
400
423
 
401
424
    def test_1_2__version__with_version_info(self):
402
425
        self.setup_plugin("version_info = (1, 2)")
403
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
426
        plugin = breezy.plugin.plugins()['plugin']
404
427
        self.assertEqual("1.2", plugin.__version__)
405
428
 
406
429
    def test_1_2_3__version__with_version_info(self):
407
430
        self.setup_plugin("version_info = (1, 2, 3)")
408
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
431
        plugin = breezy.plugin.plugins()['plugin']
409
432
        self.assertEqual("1.2.3", plugin.__version__)
410
433
 
411
434
    def test_candidate__version__with_version_info(self):
412
435
        self.setup_plugin("version_info = (1, 2, 3, 'candidate', 1)")
413
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
436
        plugin = breezy.plugin.plugins()['plugin']
414
437
        self.assertEqual("1.2.3rc1", plugin.__version__)
415
438
 
416
439
    def test_dev__version__with_version_info(self):
417
440
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 0)")
418
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
441
        plugin = breezy.plugin.plugins()['plugin']
419
442
        self.assertEqual("1.2.3dev", plugin.__version__)
420
443
 
421
444
    def test_dev_fallback__version__with_version_info(self):
422
445
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
423
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
446
        plugin = breezy.plugin.plugins()['plugin']
424
447
        self.assertEqual("1.2.3dev4", plugin.__version__)
425
448
 
426
449
    def test_final__version__with_version_info(self):
427
450
        self.setup_plugin("version_info = (1, 2, 3, 'final', 0)")
428
 
        plugin = bzrlib.plugin.plugins()['plugin']
 
451
        plugin = breezy.plugin.plugins()['plugin']
429
452
        self.assertEqual("1.2.3", plugin.__version__)
430
453
 
431
454
    def test_final_fallback__version__with_version_info(self):
432
455
        self.setup_plugin("version_info = (1, 2, 3, 'final', 2)")
433
 
        plugin = bzrlib.plugin.plugins()['plugin']
434
 
        self.assertEqual("1.2.3.final.2", plugin.__version__)
 
456
        plugin = breezy.plugin.plugins()['plugin']
 
457
        self.assertEqual("1.2.3.2", plugin.__version__)
435
458
 
436
459
 
437
460
class TestPluginHelp(tests.TestCaseInTempDir):
450
473
    def test_plugin_help_builtins_unaffected(self):
451
474
        # Check we don't get false positives
452
475
        help_commands = self.split_help_commands()
453
 
        for cmd_name in bzrlib.commands.builtin_command_names():
454
 
            if cmd_name in bzrlib.commands.plugin_command_names():
 
476
        for cmd_name in breezy.commands.builtin_command_names():
 
477
            if cmd_name in breezy.commands.plugin_command_names():
455
478
                continue
456
479
            try:
457
 
                help = bzrlib.commands.get_cmd_object(cmd_name).get_help_text()
 
480
                help = breezy.commands.get_cmd_object(cmd_name).get_help_text()
458
481
            except NotImplementedError:
459
482
                # some commands have no help
460
483
                pass
471
494
        os.mkdir('plugin_test')
472
495
        f = open(osutils.pathjoin('plugin_test', 'myplug.py'), 'w')
473
496
        f.write("""\
474
 
from bzrlib import commands
 
497
from breezy import commands
475
498
class cmd_myplug(commands.Command):
476
499
    __doc__ = '''Just a simple test plugin.'''
477
500
    aliases = ['mplg']
484
507
 
485
508
        try:
486
509
            # Check its help
487
 
            bzrlib.plugin.load_from_path(['plugin_test'])
488
 
            bzrlib.commands.register_command( bzrlib.plugins.myplug.cmd_myplug)
 
510
            breezy.plugin.load_from_path(['plugin_test'])
 
511
            breezy.commands.register_command( breezy.plugins.myplug.cmd_myplug)
489
512
            help = self.run_bzr('help myplug')[0]
490
513
            self.assertContainsRe(help, 'plugin "myplug"')
491
514
            help = self.split_help_commands()['myplug']
492
515
            self.assertContainsRe(help, '\[myplug\]')
493
516
        finally:
494
517
            # unregister command
495
 
            if 'myplug' in bzrlib.commands.plugin_cmds:
496
 
                bzrlib.commands.plugin_cmds.remove('myplug')
 
518
            if 'myplug' in breezy.commands.plugin_cmds:
 
519
                breezy.commands.plugin_cmds.remove('myplug')
497
520
            # remove the plugin 'myplug'
498
 
            if getattr(bzrlib.plugins, 'myplug', None):
499
 
                delattr(bzrlib.plugins, 'myplug')
 
521
            if getattr(breezy.plugins, 'myplug', None):
 
522
                delattr(breezy.plugins, 'myplug')
500
523
 
501
524
 
502
525
class TestHelpIndex(tests.TestCase):
515
538
        index = plugin.PluginsHelpIndex()
516
539
        # make a new plugin here for this test, even if we're run with
517
540
        # --no-plugins
518
 
        self.assertFalse(sys.modules.has_key('bzrlib.plugins.demo_module'))
519
 
        demo_module = FakeModule('', 'bzrlib.plugins.demo_module')
520
 
        sys.modules['bzrlib.plugins.demo_module'] = demo_module
 
541
        self.assertFalse('breezy.plugins.demo_module' in sys.modules)
 
542
        demo_module = FakeModule('', 'breezy.plugins.demo_module')
 
543
        sys.modules['breezy.plugins.demo_module'] = demo_module
521
544
        try:
522
545
            topics = index.get_topics('demo_module')
523
546
            self.assertEqual(1, len(topics))
524
547
            self.assertIsInstance(topics[0], plugin.ModuleHelpTopic)
525
548
            self.assertEqual(demo_module, topics[0].module)
526
549
        finally:
527
 
            del sys.modules['bzrlib.plugins.demo_module']
 
550
            del sys.modules['breezy.plugins.demo_module']
528
551
 
529
552
    def test_get_topics_no_topic(self):
530
553
        """Searching for something that is not a plugin returns []."""
541
564
    def test_get_plugin_topic_with_prefix(self):
542
565
        """Searching for plugins/demo_module returns help."""
543
566
        index = plugin.PluginsHelpIndex()
544
 
        self.assertFalse(sys.modules.has_key('bzrlib.plugins.demo_module'))
545
 
        demo_module = FakeModule('', 'bzrlib.plugins.demo_module')
546
 
        sys.modules['bzrlib.plugins.demo_module'] = demo_module
 
567
        self.assertFalse('breezy.plugins.demo_module' in sys.modules)
 
568
        demo_module = FakeModule('', 'breezy.plugins.demo_module')
 
569
        sys.modules['breezy.plugins.demo_module'] = demo_module
547
570
        try:
548
571
            topics = index.get_topics('plugins/demo_module')
549
572
            self.assertEqual(1, len(topics))
550
573
            self.assertIsInstance(topics[0], plugin.ModuleHelpTopic)
551
574
            self.assertEqual(demo_module, topics[0].module)
552
575
        finally:
553
 
            del sys.modules['bzrlib.plugins.demo_module']
 
576
            del sys.modules['breezy.plugins.demo_module']
554
577
 
555
578
 
556
579
class FakeModule(object):
594
617
    def test_get_help_text_with_additional_see_also(self):
595
618
        mod = FakeModule('two lines of help\nand more', 'demo')
596
619
        topic = plugin.ModuleHelpTopic(mod)
597
 
        self.assertEqual("two lines of help\nand more\nSee also: bar, foo\n",
598
 
            topic.get_help_text(['foo', 'bar']))
 
620
        self.assertEqual("two lines of help\nand more\n\n:See also: bar, foo\n",
 
621
                         topic.get_help_text(['foo', 'bar']))
599
622
 
600
623
    def test_get_help_topic(self):
601
624
        """The help topic for a plugin is its module name."""
602
 
        mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.demo')
 
625
        mod = FakeModule('two lines of help\nand more', 'breezy.plugins.demo')
603
626
        topic = plugin.ModuleHelpTopic(mod)
604
627
        self.assertEqual('demo', topic.get_help_topic())
605
 
        mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.foo_bar')
 
628
        mod = FakeModule('two lines of help\nand more',
 
629
                         'breezy.plugins.foo_bar')
606
630
        topic = plugin.ModuleHelpTopic(mod)
607
631
        self.assertEqual('foo_bar', topic.get_help_topic())
608
632
 
611
635
 
612
636
    def setUp(self):
613
637
        super(TestLoadFromPath, self).setUp()
614
 
        # Change bzrlib.plugin to think no plugins have been loaded yet.
615
 
        self.overrideAttr(bzrlib.plugins, '__path__', [])
 
638
        # Change breezy.plugin to think no plugins have been loaded yet.
 
639
        self.overrideAttr(breezy.plugins, '__path__', [])
616
640
        self.overrideAttr(plugin, '_loaded', False)
617
641
 
618
642
        # Monkey-patch load_from_path to stop it from actually loading anything.
620
644
 
621
645
    def test_set_plugins_path_with_args(self):
622
646
        plugin.set_plugins_path(['a', 'b'])
623
 
        self.assertEqual(['a', 'b'], bzrlib.plugins.__path__)
 
647
        self.assertEqual(['a', 'b'], breezy.plugins.__path__)
624
648
 
625
649
    def test_set_plugins_path_defaults(self):
626
650
        plugin.set_plugins_path()
627
651
        self.assertEqual(plugin.get_standard_plugins_path(),
628
 
                         bzrlib.plugins.__path__)
 
652
                         breezy.plugins.__path__)
629
653
 
630
654
    def test_get_standard_plugins_path(self):
631
655
        path = plugin.get_standard_plugins_path()
645
669
                    self.fail('No path to global plugins')
646
670
 
647
671
    def test_get_standard_plugins_path_env(self):
648
 
        os.environ['BZR_PLUGIN_PATH'] = 'foo/'
 
672
        self.overrideEnv('BRZ_PLUGIN_PATH', 'foo/')
649
673
        path = plugin.get_standard_plugins_path()
650
674
        for directory in path:
651
675
            self.assertNotContainsRe(directory, r'\\/$')
652
676
 
653
677
    def test_load_plugins(self):
654
678
        plugin.load_plugins(['.'])
655
 
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
 
679
        self.assertEqual(breezy.plugins.__path__, ['.'])
656
680
        # subsequent loads are no-ops
657
681
        plugin.load_plugins(['foo'])
658
 
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
 
682
        self.assertEqual(breezy.plugins.__path__, ['.'])
659
683
 
660
684
    def test_load_plugins_default(self):
661
685
        plugin.load_plugins()
662
686
        path = plugin.get_standard_plugins_path()
663
 
        self.assertEqual(path, bzrlib.plugins.__path__)
 
687
        self.assertEqual(path, breezy.plugins.__path__)
664
688
 
665
689
 
666
690
class TestEnvPluginPath(tests.TestCase):
681
705
 
682
706
    def _set_path(self, *args):
683
707
        path = os.pathsep.join(self._list2paths(*args))
684
 
        osutils.set_or_unset_env('BZR_PLUGIN_PATH', path)
 
708
        self.overrideEnv('BRZ_PLUGIN_PATH', path)
685
709
 
686
710
    def check_path(self, expected_dirs, setting_dirs):
687
711
        if setting_dirs:
688
712
            self._set_path(*setting_dirs)
689
713
        actual = plugin.get_standard_plugins_path()
690
 
        self.assertEquals(self._list2paths(*expected_dirs), actual)
 
714
        self.assertEqual(self._list2paths(*expected_dirs), actual)
691
715
 
692
716
    def test_default(self):
693
717
        self.check_path([self.user, self.core, self.site],
757
781
                        ['+foo', '-bar'])
758
782
 
759
783
 
760
 
class TestDisablePlugin(tests.TestCaseInTempDir, TestPluginMixin):
 
784
class TestDisablePlugin(BaseTestPlugins):
761
785
 
762
786
    def setUp(self):
763
787
        super(TestDisablePlugin, self).setUp()
768
792
        self.addCleanup(self._unregister_plugin, 'test_foo')
769
793
 
770
794
    def test_cannot_import(self):
771
 
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
 
795
        self.overrideEnv('BRZ_DISABLE_PLUGINS', 'test_foo')
772
796
        plugin.set_plugins_path(['.'])
773
797
        try:
774
 
            import bzrlib.plugins.test_foo
 
798
            import breezy.plugins.test_foo
775
799
        except ImportError:
776
800
            pass
777
801
        self.assertPluginUnknown('test_foo')
781
805
        plugin.load_plugins(['.'])
782
806
        self.assertPluginKnown('test_foo')
783
807
        self.assertDocstring("This is the doc for test_foo",
784
 
                             bzrlib.plugins.test_foo)
 
808
                             breezy.plugins.test_foo)
785
809
 
786
810
    def test_not_loaded(self):
787
811
        self.warnings = []
790
814
        self.overrideAttr(trace, 'warning', captured_warning)
791
815
        # Reset the flag that protect against double loading
792
816
        self.overrideAttr(plugin, '_loaded', False)
793
 
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
 
817
        self.overrideEnv('BRZ_DISABLE_PLUGINS', 'test_foo')
794
818
        plugin.load_plugins(['.'])
795
819
        self.assertPluginUnknown('test_foo')
796
820
        # Make sure we don't warn about the plugin ImportError since this has
798
822
        self.assertLength(0, self.warnings)
799
823
 
800
824
 
801
 
class TestLoadPluginAt(tests.TestCaseInTempDir, TestPluginMixin):
 
825
 
 
826
class TestLoadPluginAtSyntax(tests.TestCase):
 
827
 
 
828
    def _get_paths(self, paths):
 
829
        return plugin._get_specific_plugin_paths(paths)
 
830
 
 
831
    def test_empty(self):
 
832
        self.assertEqual([], self._get_paths(None))
 
833
        self.assertEqual([], self._get_paths(''))
 
834
 
 
835
    def test_one_path(self):
 
836
        self.assertEqual([('b', 'man')], self._get_paths('b@man'))
 
837
 
 
838
    def test_bogus_path(self):
 
839
        # We need a '@'
 
840
        self.assertRaises(errors.BzrCommandError, self._get_paths, 'batman')
 
841
        # Too much '@' isn't good either
 
842
        self.assertRaises(errors.BzrCommandError, self._get_paths,
 
843
                          'batman@mobile@cave')
 
844
        # An empty description probably indicates a problem
 
845
        self.assertRaises(errors.BzrCommandError, self._get_paths,
 
846
                          os.pathsep.join(['batman@cave', '', 'robin@mobile']))
 
847
 
 
848
 
 
849
class TestLoadPluginAt(BaseTestPlugins):
802
850
 
803
851
    def setUp(self):
804
852
        super(TestLoadPluginAt, self).setUp()
805
853
        # Make sure we don't pollute the plugins namespace
806
854
        self.overrideAttr(plugins, '__path__')
807
 
        # Be paranoid in case a test fail
808
 
        self.addCleanup(self._unregister_plugin, 'test_foo')
809
855
        # Reset the flag that protect against double loading
810
856
        self.overrideAttr(plugin, '_loaded', False)
811
857
        # Create the same plugin in two directories
813
859
        # The "normal" directory, we use 'standard' instead of 'plugins' to
814
860
        # avoid depending on the precise naming.
815
861
        self.create_plugin_package('test_foo', dir='standard/test_foo')
 
862
        # All the tests will load the 'test_foo' plugin from various locations
 
863
        self.addCleanup(self._unregister_plugin, 'test_foo')
 
864
        # Unfortunately there's global cached state for the specific
 
865
        # registered paths.
 
866
        self.addCleanup(plugin.PluginImporter.reset)
816
867
 
817
868
    def assertTestFooLoadedFrom(self, path):
818
869
        self.assertPluginKnown('test_foo')
819
870
        self.assertDocstring('This is the doc for test_foo',
820
 
                             bzrlib.plugins.test_foo)
821
 
        self.assertEqual(path, bzrlib.plugins.test_foo.dir_source)
 
871
                             breezy.plugins.test_foo)
 
872
        self.assertEqual(path, breezy.plugins.test_foo.dir_source)
822
873
 
823
874
    def test_regular_load(self):
824
875
        plugin.load_plugins(['standard'])
825
876
        self.assertTestFooLoadedFrom('standard/test_foo')
826
877
 
827
878
    def test_import(self):
828
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
879
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@non-standard-dir')
829
880
        plugin.set_plugins_path(['standard'])
830
881
        try:
831
 
            import bzrlib.plugins.test_foo
 
882
            import breezy.plugins.test_foo
832
883
        except ImportError:
833
884
            pass
834
885
        self.assertTestFooLoadedFrom('non-standard-dir')
835
886
 
836
887
    def test_loading(self):
837
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
888
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@non-standard-dir')
838
889
        plugin.load_plugins(['standard'])
839
890
        self.assertTestFooLoadedFrom('non-standard-dir')
840
891
 
841
892
    def test_compiled_loaded(self):
842
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
893
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@non-standard-dir')
843
894
        plugin.load_plugins(['standard'])
844
895
        self.assertTestFooLoadedFrom('non-standard-dir')
845
 
        self.assertEqual('non-standard-dir/__init__.py',
846
 
                         bzrlib.plugins.test_foo.__file__)
 
896
        self.assertIsSameRealPath('non-standard-dir/__init__.py',
 
897
                                  breezy.plugins.test_foo.__file__)
847
898
 
848
899
        # Try importing again now that the source has been compiled
849
900
        self._unregister_plugin('test_foo')
854
905
            suffix = 'pyc'
855
906
        else:
856
907
            suffix = 'pyo'
857
 
        self.assertEqual('non-standard-dir/__init__.%s' % suffix,
858
 
                         bzrlib.plugins.test_foo.__file__)
 
908
        self.assertIsSameRealPath('non-standard-dir/__init__.%s' % suffix,
 
909
                                  breezy.plugins.test_foo.__file__)
859
910
 
860
911
    def test_submodule_loading(self):
861
912
        # We create an additional directory under the one for test_foo
862
913
        self.create_plugin_package('test_bar', dir='non-standard-dir/test_bar')
863
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
864
 
        plugin.set_plugins_path(['standard'])
865
 
        import bzrlib.plugins.test_foo
866
 
        self.assertEqual('bzrlib.plugins.test_foo',
867
 
                         bzrlib.plugins.test_foo.__package__)
868
 
        import bzrlib.plugins.test_foo.test_bar
869
 
        self.assertEqual('non-standard-dir/test_bar/__init__.py',
870
 
                         bzrlib.plugins.test_foo.test_bar.__file__)
 
914
        self.addCleanup(self._unregister_plugin_submodule,
 
915
                        'test_foo', 'test_bar')
 
916
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@non-standard-dir')
 
917
        plugin.set_plugins_path(['standard'])
 
918
        import breezy.plugins.test_foo
 
919
        self.assertEqual('breezy.plugins.test_foo',
 
920
                         breezy.plugins.test_foo.__package__)
 
921
        import breezy.plugins.test_foo.test_bar
 
922
        self.assertIsSameRealPath('non-standard-dir/test_bar/__init__.py',
 
923
                                  breezy.plugins.test_foo.test_bar.__file__)
 
924
 
 
925
    def test_relative_submodule_loading(self):
 
926
        self.create_plugin_package('test_foo', dir='another-dir', source='''
 
927
import test_bar
 
928
''')
 
929
        # We create an additional directory under the one for test_foo
 
930
        self.create_plugin_package('test_bar', dir='another-dir/test_bar')
 
931
        self.addCleanup(self._unregister_plugin_submodule,
 
932
                        'test_foo', 'test_bar')
 
933
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@another-dir')
 
934
        plugin.set_plugins_path(['standard'])
 
935
        import breezy.plugins.test_foo
 
936
        self.assertEqual('breezy.plugins.test_foo',
 
937
                         breezy.plugins.test_foo.__package__)
 
938
        self.assertIsSameRealPath('another-dir/test_bar/__init__.py',
 
939
                                  breezy.plugins.test_foo.test_bar.__file__)
871
940
 
872
941
    def test_loading_from___init__only(self):
873
942
        # We rename the existing __init__.py file to ensure that we don't load
876
945
        random = 'non-standard-dir/setup.py'
877
946
        os.rename(init, random)
878
947
        self.addCleanup(os.rename, random, init)
879
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@non-standard-dir')
 
948
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@non-standard-dir')
880
949
        plugin.load_plugins(['standard'])
881
950
        self.assertPluginUnknown('test_foo')
882
951
 
890
959
''' % ('test_foo', plugin_path)
891
960
        self.create_plugin('test_foo', source=source,
892
961
                           dir=plugin_dir, file_name=plugin_file_name)
893
 
        osutils.set_or_unset_env('BZR_PLUGINS_AT', 'test_foo@%s' % plugin_path)
 
962
        self.overrideEnv('BRZ_PLUGINS_AT', 'test_foo@%s' % plugin_path)
894
963
        plugin.load_plugins(['standard'])
895
964
        self.assertTestFooLoadedFrom(plugin_path)
 
965
 
 
966
 
 
967
class TestDescribePlugins(BaseTestPlugins):
 
968
 
 
969
    def test_describe_plugins(self):
 
970
        class DummyModule(object):
 
971
            __doc__ = 'Hi there'
 
972
        class DummyPlugin(object):
 
973
            __version__ = '0.1.0'
 
974
            module = DummyModule()
 
975
        def dummy_plugins():
 
976
            return { 'good': DummyPlugin() }
 
977
        self.overrideAttr(plugin, 'plugin_warnings',
 
978
            {'bad': ['Failed to load (just testing)']})
 
979
        self.overrideAttr(plugin, 'plugins', dummy_plugins)
 
980
        self.assertEqual("""\
 
981
bad (failed to load)
 
982
  ** Failed to load (just testing)
 
983
 
 
984
good 0.1.0
 
985
  Hi there
 
986
 
 
987
""", ''.join(plugin.describe_plugins()))