~bzr-pqm/bzr/bzr.dev

2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2005 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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
23
import os
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
24
from StringIO import StringIO
2215.4.1 by Alexander Belchenko
Bugfix #68124: Allow plugins import from zip archives.
25
import zipfile
750 by Martin Pool
- stubbed-out tests for python plugins
26
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
27
import bzrlib.plugin
28
import bzrlib.plugins
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
29
import bzrlib.commands
30
import bzrlib.help
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
31
from bzrlib.tests import TestCaseInTempDir
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
32
from bzrlib.osutils import pathjoin, abspath
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
33
1143 by Martin Pool
- remove dead code and remove some small errors (pychecker)
34
class PluginTest(TestCaseInTempDir):
750 by Martin Pool
- stubbed-out tests for python plugins
35
    """Create an external plugin and test loading."""
1185.16.84 by mbp at sourcefrog
- fix indents
36
#    def test_plugin_loading(self):
37
#        orig_help = self.run_bzr_captured('bzr help commands')[0]
38
#        os.mkdir('plugin_test')
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
39
#        f = open(pathjoin('plugin_test', 'myplug.py'), 'wt')
1185.16.84 by mbp at sourcefrog
- fix indents
40
#        f.write(PLUGIN_TEXT)
41
#        f.close()
42
#        newhelp = self.run_bzr_captured('bzr help commands')[0]
43
#        assert newhelp.startswith('You have been overridden\n')
44
#        # We added a line, but the rest should work
45
#        assert newhelp[25:] == help
46
#
47
#        assert backtick('bzr commit -m test') == "I'm sorry dave, you can't do that\n"
48
#
49
#        shutil.rmtree('plugin_test')
50
#
750 by Martin Pool
- stubbed-out tests for python plugins
51
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
52
#         os.environ['BZRPLUGINPATH'] = abspath('plugin_test')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
53
#         help = backtick('bzr help commands')
54
#         assert help.find('myplug') != -1
55
#         assert help.find('Just a simple test plugin.') != -1
56
57
58
#         assert backtick('bzr myplug') == 'Hello from my plugin\n'
59
#         assert backtick('bzr mplg') == 'Hello from my plugin\n'
60
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
61
#         f = open(pathjoin('plugin_test', 'override.py'), 'wb')
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
62
#         f.write("""import bzrlib, bzrlib.commands
63
#     class cmd_commit(bzrlib.commands.cmd_commit):
64
#         '''Commit changes into a new revision.'''
65
#         def run(self, *args, **kwargs):
66
#             print "I'm sorry dave, you can't do that"
67
68
#     class cmd_help(bzrlib.commands.cmd_help):
69
#         '''Show help on a command or other topic.'''
70
#         def run(self, *args, **kwargs):
71
#             print "You have been overridden"
72
#             bzrlib.commands.cmd_help.run(self, *args, **kwargs)
73
74
#         """
1185.16.83 by mbp at sourcefrog
- notes on testability of plugins
75
1185.16.84 by mbp at sourcefrog
- fix indents
76
PLUGIN_TEXT = """\
77
import bzrlib.commands
78
class cmd_myplug(bzrlib.commands.Command):
79
    '''Just a simple test plugin.'''
80
    aliases = ['mplg']
81
    def run(self):
82
        print 'Hello from my plugin'
83
"""
1492 by Robert Collins
Support decoration of commands.
84
85
# 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
86
87
class TestOneNamedPluginOnly(TestCaseInTempDir):
88
89
    activeattributes = {}
90
91
    def test_plugins_with_the_same_name_are_not_loaded(self):
92
        # This test tests that having two plugins in different
93
        # directories does not result in both being loaded.
94
        # get a file name we can use which is also a valid attribute
95
        # for accessing in activeattributes. - we cannot give import parameters.
96
        tempattribute = "0"
97
        self.failIf(tempattribute in self.activeattributes)
98
        # set a place for the plugins to record their loading, and at the same
99
        # time validate that the location the plugins should record to is
100
        # valid and correct.
101
        bzrlib.tests.test_plugins.TestOneNamedPluginOnly.activeattributes \
102
            [tempattribute] = []
103
        self.failUnless(tempattribute in self.activeattributes)
104
        # create two plugin directories
105
        os.mkdir('first')
106
        os.mkdir('second')
107
        # write a plugin that will record when its loaded in the 
108
        # tempattribute list.
109
        template = ("from bzrlib.tests.test_plugins import TestOneNamedPluginOnly\n"
110
                    "TestOneNamedPluginOnly.activeattributes[%r].append('%s')\n")
111
        print >> file(os.path.join('first', 'plugin.py'), 'w'), template % (tempattribute, 'first')
112
        print >> file(os.path.join('second', 'plugin.py'), 'w'), template % (tempattribute, 'second')
113
        try:
114
            bzrlib.plugin.load_from_dirs(['first', 'second'])
115
            self.assertEqual(['first'], self.activeattributes[tempattribute])
116
        finally:
117
            # remove the plugin 'plugin'
118
            del self.activeattributes[tempattribute]
119
            if getattr(bzrlib.plugins, 'plugin', None):
120
                del bzrlib.plugins.plugin
121
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
1516 by Robert Collins
* bzrlib.plugin.all_plugins has been changed from an attribute to a
122
123
124
class TestAllPlugins(TestCaseInTempDir):
125
126
    def test_plugin_appears_in_all_plugins(self):
127
        # This test tests a new plugin appears in bzrlib.plugin.all_plugins().
128
        # check the plugin is not loaded already
129
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
130
        # write a plugin that _cannot_ fail to load.
131
        print >> file('plugin.py', 'w'), ""
132
        try:
133
            bzrlib.plugin.load_from_dirs(['.'])
134
            self.failUnless('plugin' in bzrlib.plugin.all_plugins())
135
            self.failUnless(getattr(bzrlib.plugins, 'plugin', None))
136
            self.assertEqual(bzrlib.plugin.all_plugins()['plugin'],
137
                             bzrlib.plugins.plugin)
138
        finally:
139
            # remove the plugin 'plugin'
140
            if getattr(bzrlib.plugins, 'plugin', None):
141
                del bzrlib.plugins.plugin
142
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
143
144
145
class TestPluginHelp(TestCaseInTempDir):
146
147
    def split_help_commands(self):
148
        help = {}
149
        current = None
150
        for line in self.capture('help commands').splitlines():
2034.1.2 by Aaron Bentley
Fix testcase
151
            if not line.startswith(' '):
152
                current = line.split()[0]
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
153
            help[current] = help.get(current, '') + line
154
155
        return help
156
157
    def test_plugin_help_builtins_unaffected(self):
158
        # Check we don't get false positives
159
        help_commands = self.split_help_commands()
160
        for cmd_name in bzrlib.commands.builtin_command_names():
161
            if cmd_name in bzrlib.commands.plugin_command_names():
162
                continue
163
            help = StringIO()
164
            try:
165
                bzrlib.help.help_on_command(cmd_name, help)
166
            except NotImplementedError:
167
                # some commands have no help
168
                pass
169
            else:
170
                help.seek(0)
171
                self.assertNotContainsRe(help.read(), 'From plugin "[^"]*"')
172
173
            if help in help_commands.keys():
174
                # some commands are hidden
175
                help = help_commands[cmd_name]
176
                self.assertNotContainsRe(help, 'From plugin "[^"]*"')
177
178
    def test_plugin_help_shows_plugin(self):
179
        # Create a test plugin
180
        os.mkdir('plugin_test')
181
        f = open(pathjoin('plugin_test', 'myplug.py'), 'w')
182
        f.write(PLUGIN_TEXT)
183
        f.close()
184
185
        try:
186
            # Check its help
187
            bzrlib.plugin.load_from_dirs(['plugin_test'])
188
            bzrlib.commands.register_command( bzrlib.plugins.myplug.cmd_myplug)
189
            help = self.capture('help myplug')
190
            self.assertContainsRe(help, 'From plugin "myplug"')
191
            help = self.split_help_commands()['myplug']
2034.1.4 by Aaron Bentley
Change angle brackets to square brackets
192
            self.assertContainsRe(help, '\[myplug\]')
1733.2.5 by Michael Ellerman
Show which plugin (if any) provides a command.
193
        finally:
2204.3.2 by Alexander Belchenko
cherrypicking: test_plugin_help_shows_plugin: fix cleanup after test
194
            # unregister command
195
            if bzrlib.commands.plugin_cmds.get('myplug', None):
196
                del bzrlib.commands.plugin_cmds['myplug']
197
            # remove the plugin 'myplug'
198
            if getattr(bzrlib.plugins, 'myplug', None):
199
                delattr(bzrlib.plugins, 'myplug')
2215.4.1 by Alexander Belchenko
Bugfix #68124: Allow plugins import from zip archives.
200
201
202
class TestPluginFromZip(TestCaseInTempDir):
203
204
    def make_zipped_plugin(self, zip_name, filename):
205
        z = zipfile.ZipFile(zip_name, 'w')
206
        z.writestr(filename, PLUGIN_TEXT)
207
        z.close()
208
209
    def check_plugin_load(self, zip_name, plugin_name):
210
        self.assertFalse(plugin_name in dir(bzrlib.plugins),
211
                         'Plugin already loaded')
212
        try:
213
            bzrlib.plugin.load_from_zips([zip_name])
214
            self.assertTrue(plugin_name in dir(bzrlib.plugins),
215
                            'Plugin is not loaded')
216
        finally:
217
            # unregister plugin
218
            if getattr(bzrlib.plugins, plugin_name, None):
219
                delattr(bzrlib.plugins, plugin_name)
220
221
    def test_load_module(self):
222
        self.make_zipped_plugin('./test.zip', 'ziplug.py')
223
        self.check_plugin_load('./test.zip', 'ziplug')
224
225
    def test_load_package(self):
226
        self.make_zipped_plugin('./test.zip', 'ziplug/__init__.py')
227
        self.check_plugin_load('./test.zip', 'ziplug')