~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_msgeditor.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-03-16 14:01:20 UTC
  • mfrom: (3280.2.5 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20080316140120-i3yq8yr1l66m11h7
Start 1.4 development

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Test commit message editor.
18
18
"""
20
20
import os
21
21
import sys
22
22
 
 
23
import bzrlib
23
24
from bzrlib import (
24
 
    commit,
25
 
    config,
26
25
    errors,
27
26
    msgeditor,
28
27
    osutils,
29
 
    tests,
30
 
    trace,
31
28
    )
32
29
from bzrlib.branch import Branch
33
30
from bzrlib.config import ensure_config_dir_exists, config_filename
36
33
    edit_commit_message_encoded
37
34
)
38
35
from bzrlib.tests import (
39
 
    TestCaseInTempDir,
 
36
    iter_suite_tests,
 
37
    probe_bad_non_ascii,
 
38
    split_suite_by_re,
40
39
    TestCaseWithTransport,
41
40
    TestNotApplicable,
42
41
    TestSkipped,
43
 
    multiply_tests,
44
 
    probe_bad_non_ascii,
45
 
    split_suite_by_re,
46
42
    )
47
 
from bzrlib.tests.EncodingAdapter import encoding_scenarios
 
43
from bzrlib.tests.EncodingAdapter import EncodingTestAdapter
48
44
from bzrlib.trace import mutter
49
45
 
50
46
 
52
48
    """Parameterize the test for tempfile creation with different encodings."""
53
49
    to_adapt, result = split_suite_by_re(standard_tests,
54
50
        "test__create_temp_file_with_commit_template_in_unicode_dir")
55
 
    return multiply_tests(to_adapt, encoding_scenarios, result)
 
51
    for test in iter_suite_tests(to_adapt):
 
52
        result.addTests(EncodingTestAdapter().adapt(test))
 
53
    return result
56
54
 
57
55
 
58
56
class MsgEditorTest(TestCaseWithTransport):
69
67
                "filesystem encoding %s" % sys.getfilesystemencoding())
70
68
        working_tree.add(filename)
71
69
        return working_tree
72
 
 
 
70
    
73
71
    def test_commit_template(self):
74
72
        """Test building a commit message template"""
75
73
        working_tree = self.make_uncommitted_tree()
81
79
  hell\u00d8
82
80
""")
83
81
 
84
 
    def make_multiple_pending_tree(self):
85
 
        from bzrlib import config
86
 
        config.GlobalConfig().set_user_option('email',
87
 
                                              'Bilbo Baggins <bb@hobbit.net>')
88
 
        tree = self.make_branch_and_tree('a')
89
 
        tree.commit('Initial checkin.', timestamp=1230912900, timezone=0)
90
 
        tree2 = tree.bzrdir.clone('b').open_workingtree()
91
 
        tree.commit('Minor tweak.', timestamp=1231977840, timezone=0)
92
 
        tree2.commit('Feature X work.', timestamp=1233186240, timezone=0)
93
 
        tree3 = tree2.bzrdir.clone('c').open_workingtree()
94
 
        tree2.commit('Feature X finished.', timestamp=1233187680, timezone=0)
95
 
        tree3.commit('Feature Y, based on initial X work.',
96
 
                     timestamp=1233285960, timezone=0)
97
 
        tree.merge_from_branch(tree2.branch)
98
 
        tree.merge_from_branch(tree3.branch, force=True)
99
 
        return tree
100
 
 
101
 
    def test_commit_template_pending_merges(self):
102
 
        """Test building a commit message template when there are pending
103
 
        merges.  The commit message should show all pending merge revisions,
104
 
        as does 'status -v', not only the merge tips.
105
 
        """
106
 
        working_tree = self.make_multiple_pending_tree()
107
 
        template = msgeditor.make_commit_message_template(working_tree, None)
108
 
        self.assertEqualDiff(template,
109
 
u"""\
110
 
pending merges:
111
 
  Bilbo Baggins 2009-01-29 Feature X finished.
112
 
    Bilbo Baggins 2009-01-28 Feature X work.
113
 
  Bilbo Baggins 2009-01-30 Feature Y, based on initial X work.
114
 
""")
115
 
 
116
82
    def test_commit_template_encoded(self):
117
83
        """Test building a commit message template"""
118
84
        working_tree = self.make_uncommitted_tree()
143
109
  hell\u00d8
144
110
""".encode('utf8') in template)
145
111
 
146
 
    def make_do_nothing_editor(self):
 
112
    def test_run_editor(self):
147
113
        if sys.platform == "win32":
148
114
            f = file('fed.bat', 'w')
149
115
            f.write('@rem dummy fed')
150
116
            f.close()
151
 
            return 'fed.bat'
 
117
            os.environ['BZR_EDITOR'] = 'fed.bat'
152
118
        else:
153
119
            f = file('fed.sh', 'wb')
154
120
            f.write('#!/bin/sh\n')
155
121
            f.close()
156
122
            os.chmod('fed.sh', 0755)
157
 
            return './fed.sh'
 
123
            os.environ['BZR_EDITOR'] = './fed.sh'
158
124
 
159
 
    def test_run_editor(self):
160
 
        os.environ['BZR_EDITOR'] = self.make_do_nothing_editor()
161
125
        self.assertEqual(True, msgeditor._run_editor(''),
162
126
                         'Unable to run dummy fake editor')
163
127
 
237
201
        self.assertRaises((IOError, OSError), msgeditor.edit_commit_message, '')
238
202
 
239
203
    def test__get_editor(self):
240
 
        os.environ['BZR_EDITOR'] = 'bzr_editor'
241
 
        os.environ['VISUAL'] = 'visual'
242
 
        os.environ['EDITOR'] = 'editor'
243
 
 
244
 
        conf = config.GlobalConfig.from_string('editor = config_editor\n',
245
 
                                               save=True)
246
 
 
247
 
        editors = list(msgeditor._get_editor())
248
 
        editors = [editor for (editor, cfg_src) in editors]
249
 
 
250
 
        self.assertEqual(['bzr_editor', 'config_editor', 'visual', 'editor'],
251
 
                         editors[:4])
252
 
 
253
 
        if sys.platform == 'win32':
254
 
            self.assertEqual(['wordpad.exe', 'notepad.exe'], editors[4:])
255
 
        else:
256
 
            self.assertEqual(['/usr/bin/editor', 'vi', 'pico', 'nano', 'joe'],
257
 
                             editors[4:])
258
 
 
259
 
 
260
 
    def test__run_editor_EACCES(self):
261
 
        """If running a configured editor raises EACESS, the user is warned."""
262
 
        os.environ['BZR_EDITOR'] = 'eacces.py'
263
 
        f = file('eacces.py', 'wb')
264
 
        f.write('# Not a real editor')
265
 
        f.close()
266
 
        # Make the fake editor unreadable (and unexecutable)
267
 
        os.chmod('eacces.py', 0)
268
 
        # Set $EDITOR so that _run_editor will terminate before trying real
269
 
        # editors.
270
 
        os.environ['EDITOR'] = self.make_do_nothing_editor()
271
 
        # Call _run_editor, capturing mutter.warning calls.
272
 
        warnings = []
273
 
        def warning(*args):
274
 
            if len(args) > 1:
275
 
                warnings.append(args[0] % args[1:])
276
 
            else:
277
 
                warnings.append(args[0])
278
 
        _warning = trace.warning
279
 
        trace.warning = warning
 
204
        # Test that _get_editor can return a decent list of items
 
205
        bzr_editor = os.environ.get('BZR_EDITOR')
 
206
        visual = os.environ.get('VISUAL')
 
207
        editor = os.environ.get('EDITOR')
280
208
        try:
281
 
            msgeditor._run_editor('')
 
209
            os.environ['BZR_EDITOR'] = 'bzr_editor'
 
210
            os.environ['VISUAL'] = 'visual'
 
211
            os.environ['EDITOR'] = 'editor'
 
212
 
 
213
            ensure_config_dir_exists()
 
214
            f = open(config_filename(), 'wb')
 
215
            f.write('editor = config_editor\n')
 
216
            f.close()
 
217
 
 
218
            editors = list(msgeditor._get_editor())
 
219
 
 
220
            self.assertEqual(['bzr_editor', 'config_editor', 'visual',
 
221
                              'editor'], editors[:4])
 
222
 
 
223
            if sys.platform == 'win32':
 
224
                self.assertEqual(['wordpad.exe', 'notepad.exe'], editors[4:])
 
225
            else:
 
226
                self.assertEqual(['/usr/bin/editor', 'vi', 'pico', 'nano',
 
227
                                  'joe'], editors[4:])
 
228
 
282
229
        finally:
283
 
            trace.warning = _warning
284
 
        self.assertStartsWith(warnings[0], 'Could not start editor "eacces.py"')
 
230
            # Restore the environment
 
231
            if bzr_editor is None:
 
232
                del os.environ['BZR_EDITOR']
 
233
            else:
 
234
                os.environ['BZR_EDITOR'] = bzr_editor
 
235
            if visual is None:
 
236
                del os.environ['VISUAL']
 
237
            else:
 
238
                os.environ['VISUAL'] = visual
 
239
            if editor is None:
 
240
                del os.environ['EDITOR']
 
241
            else:
 
242
                os.environ['EDITOR'] = editor
285
243
 
286
244
    def test__create_temp_file_with_commit_template(self):
287
245
        # check that commit template written properly
299
257
        self.assertFileEqual(expected, msgfilename)
300
258
 
301
259
    def test__create_temp_file_with_commit_template_in_unicode_dir(self):
302
 
        self.requireFeature(tests.UnicodeFilenameFeature)
 
260
        from bzrlib.tests.test_diff import UnicodeFilename
 
261
        self.requireFeature(UnicodeFilename)
303
262
        if hasattr(self, 'info'):
304
263
            os.mkdir(self.info['directory'])
305
264
            os.chdir(self.info['directory'])
321
280
            # LANG env variable has no effect on Windows
322
281
            # but some characters anyway cannot be represented
323
282
            # in default user encoding
324
 
            char = probe_bad_non_ascii(osutils.get_user_encoding())
 
283
            char = probe_bad_non_ascii(bzrlib.user_encoding)
325
284
            if char is None:
326
285
                raise TestSkipped('Cannot find suitable non-ascii character '
327
 
                    'for user_encoding (%s)' % osutils.get_user_encoding())
 
286
                    'for user_encoding (%s)' % bzrlib.user_encoding)
328
287
 
329
288
            self.make_fake_editor(message=char)
330
289
 
333
292
                              msgeditor.edit_commit_message, '')
334
293
        finally:
335
294
            osutils.set_or_unset_env('LANG', old_env)
336
 
 
337
 
    def test_generate_commit_message_template_no_hooks(self):
338
 
        commit_obj = commit.Commit()
339
 
        self.assertIs(None,
340
 
            msgeditor.generate_commit_message_template(commit_obj))
341
 
 
342
 
    def test_generate_commit_message_template_hook(self):
343
 
        msgeditor.hooks.install_named_hook("commit_message_template",
344
 
                lambda commit_obj, msg: "save me some typing\n", None)
345
 
        commit_obj = commit.Commit()
346
 
        self.assertEquals("save me some typing\n",
347
 
            msgeditor.generate_commit_message_template(commit_obj))
348
 
 
349
 
 
350
 
# GZ 2009-11-17: This wants moving to osutils when the errno checking code is
351
 
class TestPlatformErrnoWorkarounds(TestCaseInTempDir):
352
 
    """Ensuring workarounds enshrined in code actually serve a purpose"""
353
 
 
354
 
    def test_subprocess_call_bad_file(self):
355
 
        if sys.platform != "win32":
356
 
            raise TestNotApplicable("Workarounds for windows only")
357
 
        import subprocess, errno
358
 
        ERROR_BAD_EXE_FORMAT = 193
359
 
        file("textfile.txt", "w").close()
360
 
        e = self.assertRaises(WindowsError, subprocess.call, "textfile.txt")
361
 
        # Python2.4 used the 'winerror' as the errno, which confuses a lot of
362
 
        # our error trapping code. Make sure that we understand the mapping
363
 
        # correctly.
364
 
        if sys.version_info >= (2, 5):
365
 
            self.assertEqual(e.errno, errno.ENOEXEC)
366
 
            self.assertEqual(e.winerror, ERROR_BAD_EXE_FORMAT)
367
 
        else:
368
 
            self.assertEqual(e.errno, ERROR_BAD_EXE_FORMAT)