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

  • Committer: Robert Collins
  • Date: 2007-04-20 03:54:06 UTC
  • mto: This revision was merged to the branch mainline in revision 2441.
  • Revision ID: robertc@robertcollins.net-20070420035406-e68xf089otkpo7xx
Teach Command.get_help_text to show additional help cross references when supplied.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Canonical Ltd
 
2
#
 
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.
 
7
#
 
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.
 
12
#
 
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
 
 
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
 
24
from StringIO import StringIO
 
25
import sys
 
26
import zipfile
 
27
 
 
28
import bzrlib.plugin
 
29
import bzrlib.plugins
 
30
import bzrlib.commands
 
31
import bzrlib.help
 
32
from bzrlib.tests import TestCase, TestCaseInTempDir
 
33
from bzrlib.osutils import pathjoin, abspath
 
34
 
 
35
 
 
36
PLUGIN_TEXT = """\
 
37
import bzrlib.commands
 
38
class cmd_myplug(bzrlib.commands.Command):
 
39
    '''Just a simple test plugin.'''
 
40
    aliases = ['mplg']
 
41
    def run(self):
 
42
        print 'Hello from my plugin'
 
43
"""
 
44
 
 
45
# TODO: Write a test for plugin decoration of commands.
 
46
 
 
47
class TestLoadingPlugins(TestCaseInTempDir):
 
48
 
 
49
    activeattributes = {}
 
50
 
 
51
    def test_plugins_with_the_same_name_are_not_loaded(self):
 
52
        # This test tests that having two plugins in different directories does
 
53
        # not result in both being loaded when they have the same name.  get a
 
54
        # file name we can use which is also a valid attribute for accessing in
 
55
        # activeattributes. - we cannot give import parameters.
 
56
        tempattribute = "0"
 
57
        self.failIf(tempattribute in self.activeattributes)
 
58
        # set a place for the plugins to record their loading, and at the same
 
59
        # time validate that the location the plugins should record to is
 
60
        # valid and correct.
 
61
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
 
62
            [tempattribute] = []
 
63
        self.failUnless(tempattribute in self.activeattributes)
 
64
        # create two plugin directories
 
65
        os.mkdir('first')
 
66
        os.mkdir('second')
 
67
        # write a plugin that will record when its loaded in the 
 
68
        # tempattribute list.
 
69
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
70
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
 
71
        print >> file(os.path.join('first', 'plugin.py'), 'w'), template % (tempattribute, 'first')
 
72
        print >> file(os.path.join('second', 'plugin.py'), 'w'), template % (tempattribute, 'second')
 
73
        try:
 
74
            bzrlib.plugin.load_from_path(['first', 'second'])
 
75
            self.assertEqual(['first'], self.activeattributes[tempattribute])
 
76
        finally:
 
77
            # remove the plugin 'plugin'
 
78
            del self.activeattributes[tempattribute]
 
79
            if getattr(bzrlib.plugins, 'plugin', None):
 
80
                del bzrlib.plugins.plugin
 
81
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
82
 
 
83
    def test_plugins_from_different_dirs_can_demand_load(self):
 
84
        # This test tests that having two plugins in different
 
85
        # directories with different names allows them both to be loaded, when
 
86
        # we do a direct import statement.
 
87
        # Determine a file name we can use which is also a valid attribute
 
88
        # for accessing in activeattributes. - we cannot give import parameters.
 
89
        tempattribute = "different-dirs"
 
90
        self.failIf(tempattribute in self.activeattributes)
 
91
        # set a place for the plugins to record their loading, and at the same
 
92
        # time validate that the location the plugins should record to is
 
93
        # valid and correct.
 
94
        bzrlib.tests.test_plugins.TestLoadingPlugins.activeattributes \
 
95
            [tempattribute] = []
 
96
        self.failUnless(tempattribute in self.activeattributes)
 
97
        # create two plugin directories
 
98
        os.mkdir('first')
 
99
        os.mkdir('second')
 
100
        # write plugins that will record when they are loaded in the 
 
101
        # tempattribute list.
 
102
        template = ("from bzrlib.tests.test_plugins import TestLoadingPlugins\n"
 
103
                    "TestLoadingPlugins.activeattributes[%r].append('%s')\n")
 
104
        print >> file(os.path.join('first', 'pluginone.py'), 'w'), template % (tempattribute, 'first')
 
105
        print >> file(os.path.join('second', 'plugintwo.py'), 'w'), template % (tempattribute, 'second')
 
106
        oldpath = bzrlib.plugins.__path__
 
107
        try:
 
108
            bzrlib.plugins.__path__ = ['first', 'second']
 
109
            exec "import bzrlib.plugins.pluginone"
 
110
            self.assertEqual(['first'], self.activeattributes[tempattribute])
 
111
            exec "import bzrlib.plugins.plugintwo"
 
112
            self.assertEqual(['first', 'second'],
 
113
                self.activeattributes[tempattribute])
 
114
        finally:
 
115
            # remove the plugin 'plugin'
 
116
            del self.activeattributes[tempattribute]
 
117
            if getattr(bzrlib.plugins, 'plugin', None):
 
118
                del bzrlib.plugins.plugin
 
119
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
120
 
 
121
 
 
122
class TestAllPlugins(TestCaseInTempDir):
 
123
 
 
124
    def test_plugin_appears_in_all_plugins(self):
 
125
        # This test tests a new plugin appears in bzrlib.plugin.all_plugins().
 
126
        # check the plugin is not loaded already
 
127
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
128
        # write a plugin that _cannot_ fail to load.
 
129
        print >> file('plugin.py', 'w'), ""
 
130
        try:
 
131
            bzrlib.plugin.load_from_path(['.'])
 
132
            self.failUnless('plugin' in bzrlib.plugin.all_plugins())
 
133
            self.failUnless(getattr(bzrlib.plugins, 'plugin', None))
 
134
            self.assertEqual(bzrlib.plugin.all_plugins()['plugin'],
 
135
                             bzrlib.plugins.plugin)
 
136
        finally:
 
137
            # remove the plugin 'plugin'
 
138
            if 'bzrlib.plugins.plugin' in sys.modules:
 
139
                del sys.modules['bzrlib.plugins.plugin']
 
140
            if getattr(bzrlib.plugins, 'plugin', None):
 
141
                del bzrlib.plugins.plugin
 
142
        self.failIf(getattr(bzrlib.plugins, 'plugin', None))
 
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():
 
151
            if not line.startswith(' '):
 
152
                current = line.split()[0]
 
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
            try:
 
164
                help = bzrlib.commands.get_cmd_object(cmd_name).get_help_text()
 
165
            except NotImplementedError:
 
166
                # some commands have no help
 
167
                pass
 
168
            else:
 
169
                self.assertNotContainsRe(help, 'From plugin "[^"]*"')
 
170
 
 
171
            if cmd_name in help_commands.keys():
 
172
                # some commands are hidden
 
173
                help = help_commands[cmd_name]
 
174
                self.assertNotContainsRe(help, 'From plugin "[^"]*"')
 
175
 
 
176
    def test_plugin_help_shows_plugin(self):
 
177
        # Create a test plugin
 
178
        os.mkdir('plugin_test')
 
179
        f = open(pathjoin('plugin_test', 'myplug.py'), 'w')
 
180
        f.write(PLUGIN_TEXT)
 
181
        f.close()
 
182
 
 
183
        try:
 
184
            # Check its help
 
185
            bzrlib.plugin.load_from_path(['plugin_test'])
 
186
            bzrlib.commands.register_command( bzrlib.plugins.myplug.cmd_myplug)
 
187
            help = self.capture('help myplug')
 
188
            self.assertContainsRe(help, 'From plugin "myplug"')
 
189
            help = self.split_help_commands()['myplug']
 
190
            self.assertContainsRe(help, '\[myplug\]')
 
191
        finally:
 
192
            # unregister command
 
193
            if bzrlib.commands.plugin_cmds.get('myplug', None):
 
194
                del bzrlib.commands.plugin_cmds['myplug']
 
195
            # remove the plugin 'myplug'
 
196
            if getattr(bzrlib.plugins, 'myplug', None):
 
197
                delattr(bzrlib.plugins, 'myplug')
 
198
 
 
199
 
 
200
class TestPluginFromZip(TestCaseInTempDir):
 
201
 
 
202
    def make_zipped_plugin(self, zip_name, filename):
 
203
        z = zipfile.ZipFile(zip_name, 'w')
 
204
        z.writestr(filename, PLUGIN_TEXT)
 
205
        z.close()
 
206
 
 
207
    def check_plugin_load(self, zip_name, plugin_name):
 
208
        self.assertFalse(plugin_name in dir(bzrlib.plugins),
 
209
                         'Plugin already loaded')
 
210
        try:
 
211
            bzrlib.plugin.load_from_zip(zip_name)
 
212
            self.assertTrue(plugin_name in dir(bzrlib.plugins),
 
213
                            'Plugin is not loaded')
 
214
        finally:
 
215
            # unregister plugin
 
216
            if getattr(bzrlib.plugins, plugin_name, None):
 
217
                delattr(bzrlib.plugins, plugin_name)
 
218
 
 
219
    def test_load_module(self):
 
220
        self.make_zipped_plugin('./test.zip', 'ziplug.py')
 
221
        self.check_plugin_load('./test.zip', 'ziplug')
 
222
 
 
223
    def test_load_package(self):
 
224
        self.make_zipped_plugin('./test.zip', 'ziplug/__init__.py')
 
225
        self.check_plugin_load('./test.zip', 'ziplug')
 
226
 
 
227
 
 
228
class TestSetPluginsPath(TestCase):
 
229
    
 
230
    def test_set_plugins_path(self):
 
231
        """set_plugins_path should set the module __path__ correctly."""
 
232
        old_path = bzrlib.plugins.__path__
 
233
        try:
 
234
            bzrlib.plugins.__path__ = []
 
235
            expected_path = bzrlib.plugin.set_plugins_path()
 
236
            self.assertEqual(expected_path, bzrlib.plugins.__path__)
 
237
        finally:
 
238
            bzrlib.plugins.__path__ = old_path