~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_msgeditor.py

  • Committer: Vincent Ladeuil
  • Date: 2010-03-02 10:21:39 UTC
  • mfrom: (4797.2.24 2.1)
  • mto: This revision was merged to the branch mainline in revision 5069.
  • Revision ID: v.ladeuil+lp@free.fr-20100302102139-b5cba7h6xu13mekg
Merge 2.1 into trunk including fixes for #331095, #507557, #185103, #524184 and #369501

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Test commit message editor.
18
18
"""
20
20
import os
21
21
import sys
22
22
 
23
 
import bzrlib
24
23
from bzrlib import (
 
24
    commit,
25
25
    errors,
26
26
    msgeditor,
27
27
    osutils,
 
28
    tests,
 
29
    trace,
28
30
    )
29
31
from bzrlib.branch import Branch
30
32
from bzrlib.config import ensure_config_dir_exists, config_filename
33
35
    edit_commit_message_encoded
34
36
)
35
37
from bzrlib.tests import (
36
 
    probe_bad_non_ascii,
 
38
    TestCaseInTempDir,
37
39
    TestCaseWithTransport,
 
40
    TestNotApplicable,
38
41
    TestSkipped,
 
42
    multiply_tests,
 
43
    probe_bad_non_ascii,
 
44
    split_suite_by_re,
39
45
    )
 
46
from bzrlib.tests.EncodingAdapter import encoding_scenarios
40
47
from bzrlib.trace import mutter
41
48
 
42
49
 
 
50
def load_tests(standard_tests, module, loader):
 
51
    """Parameterize the test for tempfile creation with different encodings."""
 
52
    to_adapt, result = split_suite_by_re(standard_tests,
 
53
        "test__create_temp_file_with_commit_template_in_unicode_dir")
 
54
    return multiply_tests(to_adapt, encoding_scenarios, result)
 
55
 
 
56
 
43
57
class MsgEditorTest(TestCaseWithTransport):
44
58
 
45
59
    def make_uncommitted_tree(self):
54
68
                "filesystem encoding %s" % sys.getfilesystemencoding())
55
69
        working_tree.add(filename)
56
70
        return working_tree
57
 
    
 
71
 
58
72
    def test_commit_template(self):
59
73
        """Test building a commit message template"""
60
74
        working_tree = self.make_uncommitted_tree()
66
80
  hell\u00d8
67
81
""")
68
82
 
 
83
    def make_multiple_pending_tree(self):
 
84
        from bzrlib import config
 
85
        config.GlobalConfig().set_user_option('email',
 
86
                                              'Bilbo Baggins <bb@hobbit.net>')
 
87
        tree = self.make_branch_and_tree('a')
 
88
        tree.commit('Initial checkin.', timestamp=1230912900, timezone=0)
 
89
        tree2 = tree.bzrdir.clone('b').open_workingtree()
 
90
        tree.commit('Minor tweak.', timestamp=1231977840, timezone=0)
 
91
        tree2.commit('Feature X work.', timestamp=1233186240, timezone=0)
 
92
        tree3 = tree2.bzrdir.clone('c').open_workingtree()
 
93
        tree2.commit('Feature X finished.', timestamp=1233187680, timezone=0)
 
94
        tree3.commit('Feature Y, based on initial X work.',
 
95
                     timestamp=1233285960, timezone=0)
 
96
        tree.merge_from_branch(tree2.branch)
 
97
        tree.merge_from_branch(tree3.branch, force=True)
 
98
        return tree
 
99
 
 
100
    def test_commit_template_pending_merges(self):
 
101
        """Test building a commit message template when there are pending
 
102
        merges.  The commit message should show all pending merge revisions,
 
103
        as does 'status -v', not only the merge tips.
 
104
        """
 
105
        working_tree = self.make_multiple_pending_tree()
 
106
        template = msgeditor.make_commit_message_template(working_tree, None)
 
107
        self.assertEqualDiff(template,
 
108
u"""\
 
109
pending merges:
 
110
  Bilbo Baggins 2009-01-29 Feature X finished.
 
111
    Bilbo Baggins 2009-01-28 Feature X work.
 
112
  Bilbo Baggins 2009-01-30 Feature Y, based on initial X work.
 
113
""")
 
114
 
69
115
    def test_commit_template_encoded(self):
70
116
        """Test building a commit message template"""
71
117
        working_tree = self.make_uncommitted_tree()
96
142
  hell\u00d8
97
143
""".encode('utf8') in template)
98
144
 
99
 
    def test_run_editor(self):
 
145
    def make_do_nothing_editor(self):
100
146
        if sys.platform == "win32":
101
147
            f = file('fed.bat', 'w')
102
148
            f.write('@rem dummy fed')
103
149
            f.close()
104
 
            os.environ['BZR_EDITOR'] = 'fed.bat'
 
150
            return 'fed.bat'
105
151
        else:
106
152
            f = file('fed.sh', 'wb')
107
153
            f.write('#!/bin/sh\n')
108
154
            f.close()
109
155
            os.chmod('fed.sh', 0755)
110
 
            os.environ['BZR_EDITOR'] = './fed.sh'
 
156
            return './fed.sh'
111
157
 
 
158
    def test_run_editor(self):
 
159
        os.environ['BZR_EDITOR'] = self.make_do_nothing_editor()
112
160
        self.assertEqual(True, msgeditor._run_editor(''),
113
161
                         'Unable to run dummy fake editor')
114
162
 
203
251
            f.close()
204
252
 
205
253
            editors = list(msgeditor._get_editor())
 
254
            editors = [editor for (editor, cfg_src) in editors]
206
255
 
207
256
            self.assertEqual(['bzr_editor', 'config_editor', 'visual',
208
257
                              'editor'], editors[:4])
228
277
            else:
229
278
                os.environ['EDITOR'] = editor
230
279
 
 
280
    def test__run_editor_EACCES(self):
 
281
        """If running a configured editor raises EACESS, the user is warned."""
 
282
        os.environ['BZR_EDITOR'] = 'eacces.py'
 
283
        f = file('eacces.py', 'wb')
 
284
        f.write('# Not a real editor')
 
285
        f.close()
 
286
        # Make the fake editor unreadable (and unexecutable)
 
287
        os.chmod('eacces.py', 0)
 
288
        # Set $EDITOR so that _run_editor will terminate before trying real
 
289
        # editors.
 
290
        os.environ['EDITOR'] = self.make_do_nothing_editor()
 
291
        # Call _run_editor, capturing mutter.warning calls.
 
292
        warnings = []
 
293
        def warning(*args):
 
294
            if len(args) > 1:
 
295
                warnings.append(args[0] % args[1:])
 
296
            else:
 
297
                warnings.append(args[0])
 
298
        _warning = trace.warning
 
299
        trace.warning = warning
 
300
        try:
 
301
            msgeditor._run_editor('')
 
302
        finally:
 
303
            trace.warning = _warning
 
304
        self.assertStartsWith(warnings[0], 'Could not start editor "eacces.py"')
 
305
 
231
306
    def test__create_temp_file_with_commit_template(self):
232
307
        # check that commit template written properly
233
308
        # and has platform native line-endings (CRLF on win32)
243
318
                                    'infotext'])
244
319
        self.assertFileEqual(expected, msgfilename)
245
320
 
 
321
    def test__create_temp_file_with_commit_template_in_unicode_dir(self):
 
322
        self.requireFeature(tests.UnicodeFilenameFeature)
 
323
        if hasattr(self, 'info'):
 
324
            os.mkdir(self.info['directory'])
 
325
            os.chdir(self.info['directory'])
 
326
            msgeditor._create_temp_file_with_commit_template('infotext')
 
327
        else:
 
328
            raise TestNotApplicable('Test run elsewhere with non-ascii data.')
 
329
 
246
330
    def test__create_temp_file_with_empty_commit_template(self):
247
331
        # empty file
248
332
        create_file = msgeditor._create_temp_file_with_commit_template
257
341
            # LANG env variable has no effect on Windows
258
342
            # but some characters anyway cannot be represented
259
343
            # in default user encoding
260
 
            char = probe_bad_non_ascii(bzrlib.user_encoding)
 
344
            char = probe_bad_non_ascii(osutils.get_user_encoding())
261
345
            if char is None:
262
346
                raise TestSkipped('Cannot find suitable non-ascii character '
263
 
                    'for user_encoding (%s)' % bzrlib.user_encoding)
 
347
                    'for user_encoding (%s)' % osutils.get_user_encoding())
264
348
 
265
349
            self.make_fake_editor(message=char)
266
350
 
269
353
                              msgeditor.edit_commit_message, '')
270
354
        finally:
271
355
            osutils.set_or_unset_env('LANG', old_env)
 
356
 
 
357
    def test_generate_commit_message_template_no_hooks(self):
 
358
        commit_obj = commit.Commit()
 
359
        self.assertIs(None,
 
360
            msgeditor.generate_commit_message_template(commit_obj))
 
361
 
 
362
    def test_generate_commit_message_template_hook(self):
 
363
        msgeditor.hooks.install_named_hook("commit_message_template",
 
364
                lambda commit_obj, msg: "save me some typing\n", None)
 
365
        commit_obj = commit.Commit()
 
366
        self.assertEquals("save me some typing\n",
 
367
            msgeditor.generate_commit_message_template(commit_obj))
 
368
 
 
369
 
 
370
# GZ 2009-11-17: This wants moving to osutils when the errno checking code is
 
371
class TestPlatformErrnoWorkarounds(TestCaseInTempDir):
 
372
    """Ensuring workarounds enshrined in code actually serve a purpose"""
 
373
 
 
374
    def test_subprocess_call_bad_file(self):
 
375
        if sys.platform != "win32":
 
376
            raise TestNotApplicable("Workarounds for windows only")
 
377
        import subprocess, errno
 
378
        ERROR_BAD_EXE_FORMAT = 193
 
379
        file("textfile.txt", "w").close()
 
380
        e = self.assertRaises(WindowsError, subprocess.call, "textfile.txt")
 
381
        # Python2.4 used the 'winerror' as the errno, which confuses a lot of
 
382
        # our error trapping code. Make sure that we understand the mapping
 
383
        # correctly.
 
384
        if sys.version_info >= (2, 5):
 
385
            self.assertEqual(e.errno, errno.ENOEXEC)
 
386
            self.assertEqual(e.winerror, ERROR_BAD_EXE_FORMAT)
 
387
        else:
 
388
            self.assertEqual(e.errno, ERROR_BAD_EXE_FORMAT)