/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5086.1.2 by Vincent Ladeuil
Cosmetic changes.
1
# Copyright (C) 2005-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
750 by Martin Pool
- stubbed-out tests for python plugins
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
750 by Martin Pool
- stubbed-out tests for python plugins
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.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
12
#
750 by Martin Pool
- stubbed-out tests for python plugins
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
750 by Martin Pool
- stubbed-out tests for python plugins
16
17
"""Tests for plugins"""
18
1185.16.83 by mbp at sourcefrog
- notes on testability of plugins
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
21
# comments.
22
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
23
from cStringIO import StringIO
2967.4.5 by Daniel Watkins
Added test for badly-named plugins.
24
import logging
1185.16.83 by mbp at sourcefrog
- notes on testability of plugins
25
import os
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
26
import sys
750 by Martin Pool
- stubbed-out tests for python plugins
27
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
28
import bzrlib
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
29
from bzrlib import (
30
    osutils,
31
    plugin,
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
32
    plugins,
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
33
    tests,
5086.1.8 by Vincent Ladeuil
Fix warnings during autoload, add doc and a NEWS entry.
34
    trace,
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
35
    )
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
36
1185.16.83 by mbp at sourcefrog
- notes on testability of plugins
37
1492 by Robert Collins
Support decoration of commands.
38
# TODO: Write a test for plugin decoration of commands.
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
39
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
40
class TestPluginMixin(object):
41
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
42
    def create_plugin(self, name, source='', dir='.', file_name=None):
43
        if file_name is None:
44
            file_name = name + '.py'
45
        # 'source' must not fail to load
5086.1.7 by Vincent Ladeuil
Cleaner fix for bug #411413.
46
        path = osutils.pathjoin(dir, file_name)
47
        f = open(path, 'w')
48
        self.addCleanup(os.unlink, path)
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
49
        try:
50
            f.write(source + '\n')
51
        finally:
52
            f.close()
53
54
    def create_plugin_package(self, name, source='', dir='.'):
55
        plugin_dir = osutils.pathjoin(dir, name)
56
        os.mkdir(plugin_dir)
5086.1.7 by Vincent Ladeuil
Cleaner fix for bug #411413.
57
        self.addCleanup(osutils.rmtree, plugin_dir)
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
58
        self.create_plugin(name, source, dir=plugin_dir,
59
                           file_name='__init__.py')
60
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
61
    def _unregister_plugin(self, name):
62
        """Remove the plugin from sys.modules and the bzrlib namespace."""
63
        py_name = 'bzrlib.plugins.%s' % name
64
        if py_name in sys.modules:
65
            del sys.modules[py_name]
66
        if getattr(bzrlib.plugins, name, None) is not None:
67
            delattr(bzrlib.plugins, name)
68
69
    def assertPluginUnknown(self, name):
5086.1.9 by Vincent Ladeuil
Fix bogus helpers and add a test.
70
        self.failIf(getattr(bzrlib.plugins, name, None) is not None)
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
71
        self.failIf('bzrlib.plugins.%s' % name in sys.modules)
72
73
    def assertPluginKnown(self, name):
5086.1.9 by Vincent Ladeuil
Fix bogus helpers and add a test.
74
        self.failUnless(getattr(bzrlib.plugins, name, None) is not None)
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
75
        self.failUnless('bzrlib.plugins.%s' % name in sys.modules)
76
77
78
class TestLoadingPlugins(tests.TestCaseInTempDir, TestPluginMixin):
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
79
80
    activeattributes = {}
81
82
    def test_plugins_with_the_same_name_are_not_loaded(self):
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
83
        # This test tests that having two plugins in different directories does
84
        # not result in both being loaded when they have the same name.  get a
85
        # file name we can use which is also a valid attribute for accessing in
86
        # activeattributes. - we cannot give import parameters.
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
87
        tempattribute = "0"
88
        self.failIf(tempattribute in self.activeattributes)
89
        # set a place for the plugins to record their loading, and at the same
90
        # time validate that the location the plugins should record to is
91
        # valid and correct.
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
92
        self.__class__.activeattributes [tempattribute] = []
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
93
        self.failUnless(tempattribute in self.activeattributes)
94
        # create two plugin directories
95
        os.mkdir('first')
96
        os.mkdir('second')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
97
        # write a plugin that will record when its loaded in the
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
98
        # tempattribute list.
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
99
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
100
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
101
102
        outfile = open(os.path.join('first', 'plugin.py'), 'w')
103
        try:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
104
            outfile.write(template % (tempattribute, 'first'))
105
            outfile.write('\n')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
106
        finally:
107
            outfile.close()
108
109
        outfile = open(os.path.join('second', 'plugin.py'), 'w')
110
        try:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
111
            outfile.write(template % (tempattribute, 'second'))
112
            outfile.write('\n')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
113
        finally:
114
            outfile.close()
115
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
116
        try:
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
117
            bzrlib.plugin.load_from_path(['first', 'second'])
118
            self.assertEqual(['first'], self.activeattributes[tempattribute])
119
        finally:
120
            # remove the plugin 'plugin'
121
            del self.activeattributes[tempattribute]
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
122
            self._unregister_plugin('plugin')
123
        self.assertPluginUnknown('plugin')
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
124
125
    def test_plugins_from_different_dirs_can_demand_load(self):
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
126
        self.failIf('bzrlib.plugins.pluginone' in sys.modules)
127
        self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
128
        # This test tests that having two plugins in different
129
        # directories with different names allows them both to be loaded, when
130
        # we do a direct import statement.
131
        # Determine a file name we can use which is also a valid attribute
132
        # for accessing in activeattributes. - we cannot give import parameters.
133
        tempattribute = "different-dirs"
134
        self.failIf(tempattribute in self.activeattributes)
135
        # set a place for the plugins to record their loading, and at the same
136
        # time validate that the location the plugins should record to is
137
        # valid and correct.
138
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
139
            [tempattribute] = []
140
        self.failUnless(tempattribute in self.activeattributes)
141
        # create two plugin directories
142
        os.mkdir('first')
143
        os.mkdir('second')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
144
        # write plugins that will record when they are loaded in the
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
145
        # tempattribute list.
146
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
147
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
148
149
        outfile = open(os.path.join('first', 'pluginone.py'), 'w')
150
        try:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
151
            outfile.write(template % (tempattribute, 'first'))
152
            outfile.write('\n')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
153
        finally:
154
            outfile.close()
155
156
        outfile = open(os.path.join('second', 'plugintwo.py'), 'w')
157
        try:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
158
            outfile.write(template % (tempattribute, 'second'))
159
            outfile.write('\n')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
160
        finally:
161
            outfile.close()
162
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
163
        oldpath = bzrlib.plugins.__path__
164
        try:
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
165
            self.failIf('bzrlib.plugins.pluginone' in sys.modules)
166
            self.failIf('bzrlib.plugins.plugintwo' in sys.modules)
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
167
            bzrlib.plugins.__path__ = ['first', 'second']
168
            exec "import bzrlib.plugins.pluginone"
169
            self.assertEqual(['first'], self.activeattributes[tempattribute])
170
            exec "import bzrlib.plugins.plugintwo"
171
            self.assertEqual(['first', 'second'],
172
                self.activeattributes[tempattribute])
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
173
        finally:
174
            # remove the plugin 'plugin'
175
            del self.activeattributes[tempattribute]
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
176
            self._unregister_plugin('pluginone')
177
            self._unregister_plugin('plugintwo')
178
        self.assertPluginUnknown('pluginone')
179
        self.assertPluginUnknown('plugintwo')
1516 by Robert Collins
* bzrlib.plugin.all_plugins has been changed from an attribute to a
180
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
181
    def test_plugins_can_load_from_directory_with_trailing_slash(self):
182
        # This test tests that a plugin can load from a directory when the
183
        # directory in the path has a trailing slash.
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
184
        # check the plugin is not loaded already
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
185
        self.assertPluginUnknown('ts_plugin')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
186
        tempattribute = "trailing-slash"
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
187
        self.failIf(tempattribute in self.activeattributes)
2652.2.3 by Blake Winton
Understand the code and comments of the test, instead of just cargo-culting them.
188
        # set a place for the plugin to record its loading, and at the same
189
        # time validate that the location the plugin should record to is
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
190
        # valid and correct.
191
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
192
            [tempattribute] = []
193
        self.failUnless(tempattribute in self.activeattributes)
2652.2.3 by Blake Winton
Understand the code and comments of the test, instead of just cargo-culting them.
194
        # create a directory for the plugin
195
        os.mkdir('plugin_test')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
196
        # write a plugin that will record when its loaded in the
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
197
        # tempattribute list.
198
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
199
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
200
201
        outfile = open(os.path.join('plugin_test', 'ts_plugin.py'), 'w')
202
        try:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
203
            outfile.write(template % (tempattribute, 'plugin'))
2911.6.4 by Blake Winton
Fix test failures
204
            outfile.write('\n')
2652.2.7 by Blake Winton
fix lines which were wider than 79 chars. Also handle files a little more safely.
205
        finally:
206
            outfile.close()
207
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
208
        try:
2652.2.3 by Blake Winton
Understand the code and comments of the test, instead of just cargo-culting them.
209
            bzrlib.plugin.load_from_path(['plugin_test'+os.sep])
210
            self.assertEqual(['plugin'], self.activeattributes[tempattribute])
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
211
        finally:
212
            del self.activeattributes[tempattribute]
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
213
            self._unregister_plugin('ts_plugin')
214
        self.assertPluginUnknown('ts_plugin')
2652.2.1 by Blake Winton
Add a test for BZR_PLUGIN_PATH, and code and another test to allow BZR_PLUGIN_PATH to contain trailing slashes.
215
3766.3.2 by Robert Collins
Fix reporting of incompatible api plugin load errors, fixing bug 279451.
216
    def load_and_capture(self, name):
217
        """Load plugins from '.' capturing the output.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
218
3766.3.2 by Robert Collins
Fix reporting of incompatible api plugin load errors, fixing bug 279451.
219
        :param name: The name of the plugin.
220
        :return: A string with the log from the plugin loading call.
221
        """
2967.4.5 by Daniel Watkins
Added test for badly-named plugins.
222
        # Capture output
223
        stream = StringIO()
3766.3.2 by Robert Collins
Fix reporting of incompatible api plugin load errors, fixing bug 279451.
224
        try:
225
            handler = logging.StreamHandler(stream)
226
            log = logging.getLogger('bzr')
227
            log.addHandler(handler)
228
            try:
229
                try:
230
                    bzrlib.plugin.load_from_path(['.'])
231
                finally:
232
                    if 'bzrlib.plugins.%s' % name in sys.modules:
233
                        del sys.modules['bzrlib.plugins.%s' % name]
234
                    if getattr(bzrlib.plugins, name, None):
235
                        delattr(bzrlib.plugins, name)
236
            finally:
237
                # Stop capturing output
238
                handler.flush()
239
                handler.close()
240
                log.removeHandler(handler)
241
            return stream.getvalue()
242
        finally:
243
            stream.close()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
244
3766.3.2 by Robert Collins
Fix reporting of incompatible api plugin load errors, fixing bug 279451.
245
    def test_plugin_with_bad_api_version_reports(self):
246
        # This plugin asks for bzrlib api version 1.0.0, which is not supported
247
        # anymore.
248
        name = 'wants100.py'
249
        f = file(name, 'w')
250
        try:
251
            f.write("import bzrlib.api\n"
252
                "bzrlib.api.require_any_api(bzrlib, [(1, 0, 0)])\n")
253
        finally:
254
            f.close()
255
256
        log = self.load_and_capture(name)
257
        self.assertContainsRe(log,
258
            r"It requested API version")
259
260
    def test_plugin_with_bad_name_does_not_load(self):
261
        # The file name here invalid for a python module.
262
        name = 'bzr-bad plugin-name..py'
263
        file(name, 'w').close()
264
        log = self.load_and_capture(name)
265
        self.assertContainsRe(log,
3290.1.1 by James Westby
Strip "bzr_" from the start of the suggested plugin name.
266
            r"Unable to load 'bzr-bad plugin-name\.' in '\.' as a plugin "
267
            "because the file path isn't a valid module name; try renaming "
268
            "it to 'bad_plugin_name_'\.")
2967.4.5 by Daniel Watkins
Added test for badly-named plugins.
269
1516 by Robert Collins
* bzrlib.plugin.all_plugins has been changed from an attribute to a
270
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
271
class TestPlugins(tests.TestCaseInTempDir, TestPluginMixin):
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
272
273
    def setup_plugin(self, source=""):
274
        # This test tests a new plugin appears in bzrlib.plugin.plugins().
275
        # check the plugin is not loaded already
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
276
        self.assertPluginUnknown('plugin')
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
277
        # write a plugin that _cannot_ fail to load.
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
278
        file('plugin.py', 'w').write(source + '\n')
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
279
        self.addCleanup(self.teardown_plugin)
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
280
        plugin.load_from_path(['.'])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
281
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
282
    def teardown_plugin(self):
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
283
        self._unregister_plugin('plugin')
284
        self.assertPluginUnknown('plugin')
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
285
286
    def test_plugin_appears_in_plugins(self):
287
        self.setup_plugin()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
288
        self.assertPluginKnown('plugin')
289
        p = plugin.plugins()['plugin']
290
        self.assertIsInstance(p, bzrlib.plugin.PlugIn)
291
        self.assertEqual(p.module, plugins.plugin)
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
292
293
    def test_trivial_plugin_get_path(self):
294
        self.setup_plugin()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
295
        p = plugin.plugins()['plugin']
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
296
        plugin_path = self.test_dir + '/plugin.py'
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
297
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
298
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
299
    def test_plugin_get_path_py_not_pyc(self):
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
300
        # first import creates plugin.pyc
301
        self.setup_plugin()
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
302
        self.teardown_plugin()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
303
        plugin.load_from_path(['.']) # import plugin.pyc
304
        p = plugin.plugins()['plugin']
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
305
        plugin_path = self.test_dir + '/plugin.py'
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
306
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
307
308
    def test_plugin_get_path_pyc_only(self):
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
309
        # first import creates plugin.pyc (or plugin.pyo depending on __debug__)
310
        self.setup_plugin()
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
311
        self.teardown_plugin()
312
        os.unlink(self.test_dir + '/plugin.py')
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
313
        plugin.load_from_path(['.']) # import plugin.pyc (or .pyo)
314
        p = plugin.plugins()['plugin']
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
315
        if __debug__:
316
            plugin_path = self.test_dir + '/plugin.pyc'
317
        else:
318
            plugin_path = self.test_dir + '/plugin.pyo'
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
319
        self.assertIsSameRealPath(plugin_path, osutils.normpath(p.path()))
3193.2.1 by Alexander Belchenko
show path to plugin module as *.py instead of *.pyc if python source available
320
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
321
    def test_no_test_suite_gives_None_for_test_suite(self):
322
        self.setup_plugin()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
323
        p = plugin.plugins()['plugin']
324
        self.assertEqual(None, p.test_suite())
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
325
326
    def test_test_suite_gives_test_suite_result(self):
327
        source = """def test_suite(): return 'foo'"""
328
        self.setup_plugin(source)
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
329
        p = plugin.plugins()['plugin']
330
        self.assertEqual('foo', p.test_suite())
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
331
3302.8.21 by Vincent Ladeuil
Fixed as per Robert's review.
332
    def test_no_load_plugin_tests_gives_None_for_load_plugin_tests(self):
3302.8.10 by Vincent Ladeuil
Prepare bzrlib.plugin to use the new test loader.
333
        self.setup_plugin()
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
334
        loader = tests.TestUtil.TestLoader()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
335
        p = plugin.plugins()['plugin']
336
        self.assertEqual(None, p.load_plugin_tests(loader))
3302.8.10 by Vincent Ladeuil
Prepare bzrlib.plugin to use the new test loader.
337
3302.8.21 by Vincent Ladeuil
Fixed as per Robert's review.
338
    def test_load_plugin_tests_gives_load_plugin_tests_result(self):
3302.8.10 by Vincent Ladeuil
Prepare bzrlib.plugin to use the new test loader.
339
        source = """
340
def load_tests(standard_tests, module, loader):
341
    return 'foo'"""
342
        self.setup_plugin(source)
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
343
        loader = tests.TestUtil.TestLoader()
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
344
        p = plugin.plugins()['plugin']
345
        self.assertEqual('foo', p.load_plugin_tests(loader))
346
347
    def check_version_info(self, expected, source='', name='plugin'):
348
        self.setup_plugin(source)
349
        self.assertEqual(expected, plugin.plugins()[name].version_info())
3302.8.10 by Vincent Ladeuil
Prepare bzrlib.plugin to use the new test loader.
350
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
351
    def test_no_version_info(self):
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
352
        self.check_version_info(None)
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
353
354
    def test_with_version_info(self):
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
355
        self.check_version_info((1, 2, 3, 'dev', 4),
356
                                "version_info = (1, 2, 3, 'dev', 4)")
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
357
358
    def test_short_version_info_gets_padded(self):
359
        # the gtk plugin has version_info = (1,2,3) rather than the 5-tuple.
360
        # so we adapt it
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
361
        self.check_version_info((1, 2, 3, 'final', 0),
362
                                "version_info = (1, 2, 3)")
363
364
    def check_version(self, expected, source=None, name='plugin'):
365
        self.setup_plugin(source)
366
        self.assertEqual(expected, plugins[name].__version__)
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
367
368
    def test_no_version_info___version__(self):
369
        self.setup_plugin()
370
        plugin = bzrlib.plugin.plugins()['plugin']
371
        self.assertEqual("unknown", plugin.__version__)
372
3777.6.7 by Marius Kruger
* Can now also handle non-iteratable and string plugin versions.
373
    def test_str__version__with_version_info(self):
374
        self.setup_plugin("version_info = '1.2.3'")
375
        plugin = bzrlib.plugin.plugins()['plugin']
376
        self.assertEqual("1.2.3", plugin.__version__)
377
378
    def test_noniterable__version__with_version_info(self):
379
        self.setup_plugin("version_info = (1)")
380
        plugin = bzrlib.plugin.plugins()['plugin']
381
        self.assertEqual("1", plugin.__version__)
382
383
    def test_1__version__with_version_info(self):
384
        self.setup_plugin("version_info = (1,)")
385
        plugin = bzrlib.plugin.plugins()['plugin']
386
        self.assertEqual("1", plugin.__version__)
387
388
    def test_1_2__version__with_version_info(self):
3777.6.5 by Marius Kruger
add 2 more tests for plugin version numbers
389
        self.setup_plugin("version_info = (1, 2)")
390
        plugin = bzrlib.plugin.plugins()['plugin']
391
        self.assertEqual("1.2", plugin.__version__)
392
3777.6.7 by Marius Kruger
* Can now also handle non-iteratable and string plugin versions.
393
    def test_1_2_3__version__with_version_info(self):
3777.6.5 by Marius Kruger
add 2 more tests for plugin version numbers
394
        self.setup_plugin("version_info = (1, 2, 3)")
395
        plugin = bzrlib.plugin.plugins()['plugin']
396
        self.assertEqual("1.2.3", plugin.__version__)
397
398
    def test_candidate__version__with_version_info(self):
3777.6.4 by Marius Kruger
fix tests
399
        self.setup_plugin("version_info = (1, 2, 3, 'candidate', 1)")
400
        plugin = bzrlib.plugin.plugins()['plugin']
401
        self.assertEqual("1.2.3rc1", plugin.__version__)
402
403
    def test_dev__version__with_version_info(self):
404
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 0)")
405
        plugin = bzrlib.plugin.plugins()['plugin']
406
        self.assertEqual("1.2.3dev", plugin.__version__)
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
407
3777.6.7 by Marius Kruger
* Can now also handle non-iteratable and string plugin versions.
408
    def test_dev_fallback__version__with_version_info(self):
409
        self.setup_plugin("version_info = (1, 2, 3, 'dev', 4)")
410
        plugin = bzrlib.plugin.plugins()['plugin']
4634.50.6 by John Arbash Meinel
Handle a plugin fallback versioning issue.
411
        self.assertEqual("1.2.3dev4", plugin.__version__)
3777.6.7 by Marius Kruger
* Can now also handle non-iteratable and string plugin versions.
412
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
413
    def test_final__version__with_version_info(self):
3777.6.4 by Marius Kruger
fix tests
414
        self.setup_plugin("version_info = (1, 2, 3, 'final', 0)")
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
415
        plugin = bzrlib.plugin.plugins()['plugin']
416
        self.assertEqual("1.2.3", plugin.__version__)
417
4634.50.6 by John Arbash Meinel
Handle a plugin fallback versioning issue.
418
    def test_final_fallback__version__with_version_info(self):
419
        self.setup_plugin("version_info = (1, 2, 3, 'final', 2)")
420
        plugin = bzrlib.plugin.plugins()['plugin']
421
        self.assertEqual("1.2.3.final.2", plugin.__version__)
422
2762.2.1 by Robert Collins
* ``bzr plugins`` now lists the version number for each plugin in square
423
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
424
class TestPluginHelp(tests.TestCaseInTempDir):
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
425
426
    def split_help_commands(self):
427
        help = {}
428
        current = None
3908.1.1 by Andrew Bennetts
Try harder to avoid loading plugins during the test suite.
429
        out, err = self.run_bzr('--no-plugins help commands')
430
        for line in out.splitlines():
2034.1.2 by Aaron Bentley
Fix testcase
431
            if not line.startswith(' '):
432
                current = line.split()[0]
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
433
            help[current] = help.get(current, '') + line
434
435
        return help
436
437
    def test_plugin_help_builtins_unaffected(self):
438
        # Check we don't get false positives
439
        help_commands = self.split_help_commands()
440
        for cmd_name in bzrlib.commands.builtin_command_names():
441
            if cmd_name in bzrlib.commands.plugin_command_names():
442
                continue
443
            try:
2432.1.12 by Robert Collins
Relocate command help onto Command.
444
                help = bzrlib.commands.get_cmd_object(cmd_name).get_help_text()
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
445
            except NotImplementedError:
446
                # some commands have no help
447
                pass
448
            else:
2666.1.1 by Ian Clatworthy
Bazaar User Reference generated from online help
449
                self.assertNotContainsRe(help, 'plugin "[^"]*"')
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
450
2432.1.12 by Robert Collins
Relocate command help onto Command.
451
            if cmd_name in help_commands.keys():
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
452
                # some commands are hidden
453
                help = help_commands[cmd_name]
2666.1.1 by Ian Clatworthy
Bazaar User Reference generated from online help
454
                self.assertNotContainsRe(help, 'plugin "[^"]*"')
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
455
456
    def test_plugin_help_shows_plugin(self):
457
        # Create a test plugin
458
        os.mkdir('plugin_test')
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
459
        f = open(osutils.pathjoin('plugin_test', 'myplug.py'), 'w')
5086.1.2 by Vincent Ladeuil
Cosmetic changes.
460
        f.write("""\
5086.1.3 by Vincent Ladeuil
Fix imports in test_plugins.
461
from bzrlib import commands
462
class cmd_myplug(commands.Command):
5086.1.2 by Vincent Ladeuil
Cosmetic changes.
463
    '''Just a simple test plugin.'''
464
    aliases = ['mplg']
465
    def run(self):
466
        print 'Hello from my plugin'
467
468
"""
469
)
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
470
        f.close()
471
472
        try:
473
            # Check its help
2256.2.2 by Robert Collins
Allow 'import bzrlib.plugins.NAME' to work when the plugin NAME has not
474
            bzrlib.plugin.load_from_path(['plugin_test'])
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
475
            bzrlib.commands.register_command( bzrlib.plugins.myplug.cmd_myplug)
2530.3.4 by Martin Pool
Deprecate run_bzr_captured in favour of just run_bzr
476
            help = self.run_bzr('help myplug')[0]
2666.1.1 by Ian Clatworthy
Bazaar User Reference generated from online help
477
            self.assertContainsRe(help, 'plugin "myplug"')
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
478
            help = self.split_help_commands()['myplug']
2034.1.4 by Aaron Bentley
Change angle brackets to square brackets
479
            self.assertContainsRe(help, '\[myplug\]')
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
480
        finally:
2204.3.2 by Alexander Belchenko
cherrypicking: test_plugin_help_shows_plugin: fix cleanup after test
481
            # unregister command
3785.1.1 by Aaron Bentley
Switch from dict to Registry for plugin_cmds
482
            if 'myplug' in bzrlib.commands.plugin_cmds:
483
                bzrlib.commands.plugin_cmds.remove('myplug')
2204.3.2 by Alexander Belchenko
cherrypicking: test_plugin_help_shows_plugin: fix cleanup after test
484
            # remove the plugin 'myplug'
485
            if getattr(bzrlib.plugins, 'myplug', None):
486
                delattr(bzrlib.plugins, 'myplug')
2215.4.1 by Alexander Belchenko
Bugfix #68124: Allow plugins import from zip archives.
487
488
2432.1.25 by Robert Collins
Return plugin module docstrings for 'bzr help plugin'.
489
class TestHelpIndex(tests.TestCase):
490
    """Tests for the PluginsHelpIndex class."""
491
492
    def test_default_constructable(self):
493
        index = plugin.PluginsHelpIndex()
494
495
    def test_get_topics_None(self):
496
        """Searching for None returns an empty list."""
497
        index = plugin.PluginsHelpIndex()
498
        self.assertEqual([], index.get_topics(None))
499
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
500
    def test_get_topics_for_plugin(self):
501
        """Searching for plugin name gets its docstring."""
2432.1.25 by Robert Collins
Return plugin module docstrings for 'bzr help plugin'.
502
        index = plugin.PluginsHelpIndex()
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
503
        # make a new plugin here for this test, even if we're run with
504
        # --no-plugins
505
        self.assertFalse(sys.modules.has_key('bzrlib.plugins.demo_module'))
506
        demo_module = FakeModule('', 'bzrlib.plugins.demo_module')
507
        sys.modules['bzrlib.plugins.demo_module'] = demo_module
2457.1.1 by Robert Collins
(robertc) Fix bzr --no-plugins selftest which was broken by the help indices patch. (Robert Collins, Martin Pool)
508
        try:
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
509
            topics = index.get_topics('demo_module')
2457.1.1 by Robert Collins
(robertc) Fix bzr --no-plugins selftest which was broken by the help indices patch. (Robert Collins, Martin Pool)
510
            self.assertEqual(1, len(topics))
511
            self.assertIsInstance(topics[0], plugin.ModuleHelpTopic)
512
            self.assertEqual(demo_module, topics[0].module)
513
        finally:
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
514
            del sys.modules['bzrlib.plugins.demo_module']
2432.1.25 by Robert Collins
Return plugin module docstrings for 'bzr help plugin'.
515
516
    def test_get_topics_no_topic(self):
517
        """Searching for something that is not a plugin returns []."""
518
        # test this by using a name that cannot be a plugin - its not
519
        # a valid python identifier.
520
        index = plugin.PluginsHelpIndex()
521
        self.assertEqual([], index.get_topics('nothing by this name'))
522
523
    def test_prefix(self):
524
        """PluginsHelpIndex has a prefix of 'plugins/'."""
525
        index = plugin.PluginsHelpIndex()
526
        self.assertEqual('plugins/', index.prefix)
527
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
528
    def test_get_plugin_topic_with_prefix(self):
529
        """Searching for plugins/demo_module returns help."""
2432.1.25 by Robert Collins
Return plugin module docstrings for 'bzr help plugin'.
530
        index = plugin.PluginsHelpIndex()
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
531
        self.assertFalse(sys.modules.has_key('bzrlib.plugins.demo_module'))
532
        demo_module = FakeModule('', 'bzrlib.plugins.demo_module')
533
        sys.modules['bzrlib.plugins.demo_module'] = demo_module
2457.1.1 by Robert Collins
(robertc) Fix bzr --no-plugins selftest which was broken by the help indices patch. (Robert Collins, Martin Pool)
534
        try:
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
535
            topics = index.get_topics('plugins/demo_module')
2457.1.1 by Robert Collins
(robertc) Fix bzr --no-plugins selftest which was broken by the help indices patch. (Robert Collins, Martin Pool)
536
            self.assertEqual(1, len(topics))
537
            self.assertIsInstance(topics[0], plugin.ModuleHelpTopic)
538
            self.assertEqual(demo_module, topics[0].module)
539
        finally:
2475.1.1 by Martin Pool
Rename test_plugin tests and the example module used there.
540
            del sys.modules['bzrlib.plugins.demo_module']
2432.1.25 by Robert Collins
Return plugin module docstrings for 'bzr help plugin'.
541
542
543
class FakeModule(object):
544
    """A fake module to test with."""
545
546
    def __init__(self, doc, name):
547
        self.__doc__ = doc
548
        self.__name__ = name
549
550
551
class TestModuleHelpTopic(tests.TestCase):
552
    """Tests for the ModuleHelpTopic class."""
553
554
    def test_contruct(self):
555
        """Construction takes the module to document."""
556
        mod = FakeModule('foo', 'foo')
557
        topic = plugin.ModuleHelpTopic(mod)
558
        self.assertEqual(mod, topic.module)
559
560
    def test_get_help_text_None(self):
561
        """A ModuleHelpTopic returns the docstring for get_help_text."""
562
        mod = FakeModule(None, 'demo')
563
        topic = plugin.ModuleHelpTopic(mod)
564
        self.assertEqual("Plugin 'demo' has no docstring.\n",
565
            topic.get_help_text())
566
567
    def test_get_help_text_no_carriage_return(self):
568
        """ModuleHelpTopic.get_help_text adds a \n if needed."""
569
        mod = FakeModule('one line of help', 'demo')
570
        topic = plugin.ModuleHelpTopic(mod)
571
        self.assertEqual("one line of help\n",
572
            topic.get_help_text())
573
574
    def test_get_help_text_carriage_return(self):
575
        """ModuleHelpTopic.get_help_text adds a \n if needed."""
576
        mod = FakeModule('two lines of help\nand more\n', 'demo')
577
        topic = plugin.ModuleHelpTopic(mod)
578
        self.assertEqual("two lines of help\nand more\n",
579
            topic.get_help_text())
580
581
    def test_get_help_text_with_additional_see_also(self):
582
        mod = FakeModule('two lines of help\nand more', 'demo')
583
        topic = plugin.ModuleHelpTopic(mod)
584
        self.assertEqual("two lines of help\nand more\nSee also: bar, foo\n",
585
            topic.get_help_text(['foo', 'bar']))
2432.1.29 by Robert Collins
Add get_help_topic to ModuleHelpTopic.
586
587
    def test_get_help_topic(self):
588
        """The help topic for a plugin is its module name."""
2432.1.30 by Robert Collins
Fix the ModuleHelpTopic get_help_topic to be tested with closer to real world data and strip the bzrlib.plugins. prefix from the name.
589
        mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.demo')
2432.1.29 by Robert Collins
Add get_help_topic to ModuleHelpTopic.
590
        topic = plugin.ModuleHelpTopic(mod)
591
        self.assertEqual('demo', topic.get_help_topic())
2432.1.30 by Robert Collins
Fix the ModuleHelpTopic get_help_topic to be tested with closer to real world data and strip the bzrlib.plugins. prefix from the name.
592
        mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.foo_bar')
2432.1.29 by Robert Collins
Add get_help_topic to ModuleHelpTopic.
593
        topic = plugin.ModuleHelpTopic(mod)
594
        self.assertEqual('foo_bar', topic.get_help_topic())
3835.2.7 by Aaron Bentley
Add tests for plugins
595
596
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
597
class TestLoadFromPath(tests.TestCaseInTempDir):
598
599
    def setUp(self):
600
        super(TestLoadFromPath, self).setUp()
601
        # Change bzrlib.plugin to think no plugins have been loaded yet.
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
602
        self.overrideAttr(bzrlib.plugins, '__path__', [])
603
        self.overrideAttr(plugin, '_loaded', False)
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
604
605
        # Monkey-patch load_from_path to stop it from actually loading anything.
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
606
        self.overrideAttr(plugin, 'load_from_path', lambda dirs: None)
3835.2.7 by Aaron Bentley
Add tests for plugins
607
608
    def test_set_plugins_path_with_args(self):
609
        plugin.set_plugins_path(['a', 'b'])
610
        self.assertEqual(['a', 'b'], bzrlib.plugins.__path__)
611
612
    def test_set_plugins_path_defaults(self):
613
        plugin.set_plugins_path()
614
        self.assertEqual(plugin.get_standard_plugins_path(),
615
                         bzrlib.plugins.__path__)
616
617
    def test_get_standard_plugins_path(self):
618
        path = plugin.get_standard_plugins_path()
619
        for directory in path:
4412.2.1 by Vincent Ladeuil
Fix some OSX test regressions (well actual test bugs indeed).
620
            self.assertNotContainsRe(directory, r'\\/$')
3835.2.7 by Aaron Bentley
Add tests for plugins
621
        try:
622
            from distutils.sysconfig import get_python_lib
623
        except ImportError:
624
            pass
625
        else:
626
            if sys.platform != 'win32':
627
                python_lib = get_python_lib()
628
                for directory in path:
629
                    if directory.startswith(python_lib):
630
                        break
631
                else:
632
                    self.fail('No path to global plugins')
633
634
    def test_get_standard_plugins_path_env(self):
635
        os.environ['BZR_PLUGIN_PATH'] = 'foo/'
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
636
        path = plugin.get_standard_plugins_path()
637
        for directory in path:
638
            self.assertNotContainsRe(directory, r'\\/$')
3835.2.7 by Aaron Bentley
Add tests for plugins
639
640
    def test_load_plugins(self):
641
        plugin.load_plugins(['.'])
642
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
643
        # subsequent loads are no-ops
644
        plugin.load_plugins(['foo'])
645
        self.assertEqual(bzrlib.plugins.__path__, ['.'])
646
647
    def test_load_plugins_default(self):
648
        plugin.load_plugins()
649
        path = plugin.get_standard_plugins_path()
650
        self.assertEqual(path, bzrlib.plugins.__path__)
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
651
652
5086.1.2 by Vincent Ladeuil
Cosmetic changes.
653
class TestEnvPluginPath(tests.TestCase):
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
654
655
    def setUp(self):
656
        super(TestEnvPluginPath, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
657
        self.overrideAttr(plugin, 'DEFAULT_PLUGIN_PATH', None)
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
658
659
        self.user = plugin.get_user_plugin_path()
660
        self.site = plugin.get_site_plugin_path()
661
        self.core = plugin.get_core_plugin_path()
662
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
663
    def _list2paths(self, *args):
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
664
        paths = []
665
        for p in args:
666
            plugin._append_new_path(paths, p)
667
        return paths
668
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
669
    def _set_path(self, *args):
670
        path = os.pathsep.join(self._list2paths(*args))
671
        osutils.set_or_unset_env('BZR_PLUGIN_PATH', path)
672
673
    def check_path(self, expected_dirs, setting_dirs):
674
        if setting_dirs:
675
            self._set_path(*setting_dirs)
676
        actual = plugin.get_standard_plugins_path()
677
        self.assertEquals(self._list2paths(*expected_dirs), actual)
678
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
679
    def test_default(self):
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
680
        self.check_path([self.user, self.core, self.site],
681
                        None)
682
683
    def test_adhoc_policy(self):
684
        self.check_path([self.user, self.core, self.site],
685
                        ['+user', '+core', '+site'])
686
687
    def test_fallback_policy(self):
688
        self.check_path([self.core, self.site, self.user],
689
                        ['+core', '+site', '+user'])
690
691
    def test_override_policy(self):
692
        self.check_path([self.user, self.site, self.core],
693
                        ['+user', '+site', '+core'])
694
695
    def test_disable_user(self):
696
        self.check_path([self.core, self.site], ['-user'])
697
698
    def test_disable_user_twice(self):
699
        # Ensures multiple removals don't left cruft
700
        self.check_path([self.core, self.site], ['-user', '-user'])
701
4628.2.5 by Vincent Ladeuil
Fixes prompted by review.
702
    def test_duplicates_are_removed(self):
703
        self.check_path([self.user, self.core, self.site],
704
                        ['+user', '+user'])
705
        # And only the first reference is kept (since the later references will
5086.1.2 by Vincent Ladeuil
Cosmetic changes.
706
        # only produce '<plugin> already loaded' mutters)
4628.2.5 by Vincent Ladeuil
Fixes prompted by review.
707
        self.check_path([self.user, self.core, self.site],
708
                        ['+user', '+user', '+core',
709
                         '+user', '+site', '+site',
710
                         '+core'])
711
5086.1.5 by Vincent Ladeuil
Fix typo in test name.
712
    def test_disable_overrides_enable(self):
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
713
        self.check_path([self.core, self.site], ['-user', '+user'])
714
715
    def test_disable_core(self):
4628.2.3 by Vincent Ladeuil
Update doc and add NEWS entry.
716
        self.check_path([self.site], ['-core'])
717
        self.check_path([self.user, self.site], ['+user', '-core'])
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
718
719
    def test_disable_site(self):
4628.2.3 by Vincent Ladeuil
Update doc and add NEWS entry.
720
        self.check_path([self.core], ['-site'])
721
        self.check_path([self.user, self.core], ['-site', '+user'])
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
722
723
    def test_override_site(self):
4628.2.3 by Vincent Ladeuil
Update doc and add NEWS entry.
724
        self.check_path(['mysite', self.user, self.core],
725
                        ['mysite', '-site', '+user'])
726
        self.check_path(['mysite', self.core],
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
727
                        ['mysite', '-site'])
728
729
    def test_override_core(self):
4628.2.3 by Vincent Ladeuil
Update doc and add NEWS entry.
730
        self.check_path(['mycore', self.user, self.site],
731
                        ['mycore', '-core', '+user', '+site'])
732
        self.check_path(['mycore', self.site],
4628.2.2 by Vincent Ladeuil
Add [+-]{user|core|site} handling in BZR_PLUGIN_PATH.
733
                        ['mycore', '-core'])
734
735
    def test_my_plugin_only(self):
736
        self.check_path(['myplugin'], ['myplugin', '-user', '-core', '-site'])
737
738
    def test_my_plugin_first(self):
739
        self.check_path(['myplugin', self.core, self.site, self.user],
740
                        ['myplugin', '+core', '+site', '+user'])
4628.2.1 by Vincent Ladeuil
Start introducing accessors for plugin paths.
741
4628.2.5 by Vincent Ladeuil
Fixes prompted by review.
742
    def test_bogus_references(self):
743
        self.check_path(['+foo', '-bar', self.core, self.site],
744
                        ['+foo', '-bar'])
5086.1.4 by Vincent Ladeuil
Slight plugin tests rewriting.
745
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
746
747
class TestDisablePlugin(tests.TestCaseInTempDir, TestPluginMixin):
748
5086.1.7 by Vincent Ladeuil
Cleaner fix for bug #411413.
749
    def setUp(self):
750
        super(TestDisablePlugin, self).setUp()
751
        self.create_plugin_package('test_foo')
752
        # Make sure we don't pollute the plugins namespace
753
        self.overrideAttr(plugins, '__path__')
754
        # Be paranoid in case a test fail
755
        self.addCleanup(self._unregister_plugin, 'test_foo')
5086.1.8 by Vincent Ladeuil
Fix warnings during autoload, add doc and a NEWS entry.
756
757
    def test_cannot_import(self):
5086.1.10 by Vincent Ladeuil
Fixed as per review comments.
758
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
759
        plugin.set_plugins_path(['.'])
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
760
        try:
761
            import bzrlib.plugins.test_foo
762
        except ImportError:
763
            pass
5086.1.7 by Vincent Ladeuil
Cleaner fix for bug #411413.
764
        self.assertPluginUnknown('test_foo')
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
765
5086.1.9 by Vincent Ladeuil
Fix bogus helpers and add a test.
766
    def test_regular_load(self):
767
        self.overrideAttr(plugin, '_loaded', False)
768
        plugin.load_plugins(['.'])
769
        self.assertPluginKnown('test_foo')
770
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
771
    def test_not_loaded(self):
5086.1.8 by Vincent Ladeuil
Fix warnings during autoload, add doc and a NEWS entry.
772
        self.warnings = []
773
        def captured_warning(*args, **kwargs):
774
            self.warnings.append((args, kwargs))
775
        self.overrideAttr(trace, 'warning', captured_warning)
776
        self.overrideAttr(plugin, '_loaded', False)
5086.1.10 by Vincent Ladeuil
Fixed as per review comments.
777
        osutils.set_or_unset_env('BZR_DISABLE_PLUGINS', 'test_foo')
778
        plugin.load_plugins(plugin.set_plugins_path(['.']))
5086.1.6 by Vincent Ladeuil
Crude fix for bug #411413.
779
        self.assertPluginUnknown('test_foo')
5086.1.8 by Vincent Ladeuil
Fix warnings during autoload, add doc and a NEWS entry.
780
        # Make sure we don't warn about the plugin ImportError since this has
781
        # been *requested* by the user.
782
        self.assertLength(0, self.warnings)