/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_msgeditor.py

  • Committer: Robert Collins
  • Date: 2007-07-15 15:40:37 UTC
  • mto: (2592.3.33 repository)
  • mto: This revision was merged to the branch mainline in revision 2624.
  • Revision ID: robertc@robertcollins.net-20070715154037-3ar8g89decddc9su
Make GraphIndex accept nodes as key, value, references, so that the method
signature is closer to what a simple key->value index delivers. Also
change the behaviour when the reference list count is zero to accept
key, value as nodes, and emit key, value to make it identical in that case
to a simple key->value index. This may not be a good idea, but for now it
seems ok.

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
 
from bzrlib import (
24
 
    commit,
25
 
    errors,
26
 
    msgeditor,
27
 
    osutils,
28
 
    tests,
29
 
    trace,
30
 
    )
31
23
from bzrlib.branch import Branch
32
24
from bzrlib.config import ensure_config_dir_exists, config_filename
33
 
from bzrlib.msgeditor import (
34
 
    make_commit_message_template_encoded,
35
 
    edit_commit_message_encoded
36
 
)
37
 
from bzrlib.tests import (
38
 
    TestCaseInTempDir,
39
 
    TestCaseWithTransport,
40
 
    TestNotApplicable,
41
 
    TestSkipped,
42
 
    multiply_tests,
43
 
    probe_bad_non_ascii,
44
 
    split_suite_by_re,
45
 
    )
46
 
from bzrlib.tests.EncodingAdapter import encoding_scenarios
 
25
import bzrlib.msgeditor 
 
26
from bzrlib.tests import TestCaseWithTransport, TestSkipped
47
27
from bzrlib.trace import mutter
48
28
 
49
29
 
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
 
 
57
30
class MsgEditorTest(TestCaseWithTransport):
58
31
 
59
32
    def make_uncommitted_tree(self):
68
41
                "filesystem encoding %s" % sys.getfilesystemencoding())
69
42
        working_tree.add(filename)
70
43
        return working_tree
71
 
 
 
44
    
72
45
    def test_commit_template(self):
73
46
        """Test building a commit message template"""
74
47
        working_tree = self.make_uncommitted_tree()
75
 
        template = msgeditor.make_commit_message_template(working_tree,
76
 
                                                                 None)
77
 
        self.assertEqualDiff(template,
78
 
u"""\
79
 
added:
80
 
  hell\u00d8
81
 
""")
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
 
 
115
 
    def test_commit_template_encoded(self):
116
 
        """Test building a commit message template"""
117
 
        working_tree = self.make_uncommitted_tree()
118
 
        template = make_commit_message_template_encoded(working_tree,
119
 
                                                        None,
120
 
                                                        output_encoding='utf8')
121
 
        self.assertEqualDiff(template,
122
 
u"""\
123
 
added:
124
 
  hell\u00d8
125
 
""".encode("utf8"))
126
 
 
127
 
 
128
 
    def test_commit_template_and_diff(self):
129
 
        """Test building a commit message template"""
130
 
        working_tree = self.make_uncommitted_tree()
131
 
        template = make_commit_message_template_encoded(working_tree,
132
 
                                                        None,
133
 
                                                        diff=True,
134
 
                                                        output_encoding='utf8')
135
 
 
136
 
        self.assertTrue("""\
137
 
@@ -0,0 +1,1 @@
138
 
+contents of hello
139
 
""" in template)
140
 
        self.assertTrue(u"""\
141
 
added:
142
 
  hell\u00d8
143
 
""".encode('utf8') in template)
144
 
 
145
 
    def make_do_nothing_editor(self):
 
48
        template = bzrlib.msgeditor.make_commit_message_template(working_tree, None)
 
49
        self.assertEqualDiff(template,
 
50
u"""\
 
51
added:
 
52
  hell\u00d8
 
53
""")
 
54
 
 
55
    def setUp(self):
 
56
        super(MsgEditorTest, self).setUp()
 
57
        self._bzr_editor = os.environ.get('BZR_EDITOR', None)
 
58
 
 
59
    def tearDown(self):
 
60
        if self._bzr_editor is not None:
 
61
            os.environ['BZR_EDITOR'] = self._bzr_editor
 
62
        else:
 
63
            if os.environ.get('BZR_EDITOR', None) is not None:
 
64
                del os.environ['BZR_EDITOR']
 
65
        super(MsgEditorTest, self).tearDown()
 
66
 
 
67
    def test_run_editor(self):
146
68
        if sys.platform == "win32":
147
69
            f = file('fed.bat', 'w')
148
70
            f.write('@rem dummy fed')
149
71
            f.close()
150
 
            return 'fed.bat'
 
72
            os.environ['BZR_EDITOR'] = 'fed.bat'
151
73
        else:
152
74
            f = file('fed.sh', 'wb')
153
75
            f.write('#!/bin/sh\n')
154
76
            f.close()
155
77
            os.chmod('fed.sh', 0755)
156
 
            return './fed.sh'
 
78
            os.environ['BZR_EDITOR'] = './fed.sh'
157
79
 
158
 
    def test_run_editor(self):
159
 
        os.environ['BZR_EDITOR'] = self.make_do_nothing_editor()
160
 
        self.assertEqual(True, msgeditor._run_editor(''),
 
80
        self.assertEqual(True, bzrlib.msgeditor._run_editor(''),
161
81
                         'Unable to run dummy fake editor')
162
82
 
163
 
    def make_fake_editor(self, message='test message from fed\\n'):
 
83
    def make_fake_editor(self):
164
84
        """Set up environment so that an editor will be a known script.
165
85
 
166
86
        Sets up BZR_EDITOR so that if an editor is spawned it will run a
169
89
        f = file('fed.py', 'wb')
170
90
        f.write('#!%s\n' % sys.executable)
171
91
        f.write("""\
172
 
# coding=utf-8
173
92
import sys
174
93
if len(sys.argv) == 2:
175
94
    fn = sys.argv[1]
177
96
    s = f.read()
178
97
    f.close()
179
98
    f = file(fn, 'wb')
180
 
    f.write('%s')
 
99
    f.write('test message from fed\\n')
181
100
    f.write(s)
182
101
    f.close()
183
 
""" % (message, ))
 
102
""")
184
103
        f.close()
185
104
        if sys.platform == "win32":
186
105
            # [win32] make batch file and set BZR_EDITOR
202
121
 
203
122
        mutter('edit_commit_message without infotext')
204
123
        self.assertEqual('test message from fed\n',
205
 
                         msgeditor.edit_commit_message(''))
206
 
 
207
 
        mutter('edit_commit_message with ascii string infotext')
208
 
        self.assertEqual('test message from fed\n',
209
 
                         msgeditor.edit_commit_message('spam'))
 
124
                         bzrlib.msgeditor.edit_commit_message(''))
210
125
 
211
126
        mutter('edit_commit_message with unicode infotext')
212
127
        self.assertEqual('test message from fed\n',
213
 
                         msgeditor.edit_commit_message(u'\u1234'))
214
 
 
215
 
        tmpl = edit_commit_message_encoded(u'\u1234'.encode("utf8"))
216
 
        self.assertEqual('test message from fed\n', tmpl)
 
128
                         bzrlib.msgeditor.edit_commit_message(u'\u1234'))
217
129
 
218
130
    def test_start_message(self):
219
131
        self.make_uncommitted_tree()
220
132
        self.make_fake_editor()
221
133
        self.assertEqual('test message from fed\nstart message\n',
222
 
                         msgeditor.edit_commit_message('',
 
134
                         bzrlib.msgeditor.edit_commit_message('',
223
135
                                              start_message='start message\n'))
224
136
        self.assertEqual('test message from fed\n',
225
 
                         msgeditor.edit_commit_message('',
 
137
                         bzrlib.msgeditor.edit_commit_message('',
226
138
                                              start_message=''))
227
139
 
228
140
    def test_deleted_commit_message(self):
233
145
        else:
234
146
            os.environ['BZR_EDITOR'] = 'rm'
235
147
 
236
 
        self.assertRaises((IOError, OSError), msgeditor.edit_commit_message, '')
 
148
        self.assertRaises((IOError, OSError), bzrlib.msgeditor.edit_commit_message, '')
237
149
 
238
150
    def test__get_editor(self):
239
151
        # Test that _get_editor can return a decent list of items
250
162
            f.write('editor = config_editor\n')
251
163
            f.close()
252
164
 
253
 
            editors = list(msgeditor._get_editor())
254
 
            editors = [editor for (editor, cfg_src) in editors]
 
165
            editors = list(bzrlib.msgeditor._get_editor())
255
166
 
256
167
            self.assertEqual(['bzr_editor', 'config_editor', 'visual',
257
168
                              'editor'], editors[:4])
277
188
            else:
278
189
                os.environ['EDITOR'] = editor
279
190
 
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
 
 
306
191
    def test__create_temp_file_with_commit_template(self):
307
192
        # check that commit template written properly
308
193
        # and has platform native line-endings (CRLF on win32)
309
 
        create_file = msgeditor._create_temp_file_with_commit_template
 
194
        create_file = bzrlib.msgeditor._create_temp_file_with_commit_template
310
195
        msgfilename, hasinfo = create_file('infotext','----','start message')
311
196
        self.assertNotEqual(None, msgfilename)
312
197
        self.assertTrue(hasinfo)
318
203
                                    'infotext'])
319
204
        self.assertFileEqual(expected, msgfilename)
320
205
 
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
 
 
330
206
    def test__create_temp_file_with_empty_commit_template(self):
331
207
        # empty file
332
 
        create_file = msgeditor._create_temp_file_with_commit_template
 
208
        create_file = bzrlib.msgeditor._create_temp_file_with_commit_template
333
209
        msgfilename, hasinfo = create_file('')
334
210
        self.assertNotEqual(None, msgfilename)
335
211
        self.assertFalse(hasinfo)
336
212
        self.assertFileEqual('', msgfilename)
337
 
 
338
 
    def test_unsupported_encoding_commit_message(self):
339
 
        old_env = osutils.set_or_unset_env('LANG', 'C')
340
 
        try:
341
 
            # LANG env variable has no effect on Windows
342
 
            # but some characters anyway cannot be represented
343
 
            # in default user encoding
344
 
            char = probe_bad_non_ascii(osutils.get_user_encoding())
345
 
            if char is None:
346
 
                raise TestSkipped('Cannot find suitable non-ascii character '
347
 
                    'for user_encoding (%s)' % osutils.get_user_encoding())
348
 
 
349
 
            self.make_fake_editor(message=char)
350
 
 
351
 
            working_tree = self.make_uncommitted_tree()
352
 
            self.assertRaises(errors.BadCommitMessageEncoding,
353
 
                              msgeditor.edit_commit_message, '')
354
 
        finally:
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)