~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Alexander Belchenko
  • Date: 2007-01-04 23:36:44 UTC
  • mfrom: (2224 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2225.
  • Revision ID: bialix@ukr.net-20070104233644-7znkxoj9b0y7ev28
merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
from bzrlib.diff import internal_diff, external_diff, show_diff_trees
24
24
from bzrlib.errors import BinaryFile, NoDiff
25
 
import bzrlib.osutils as osutils
26
25
import bzrlib.patiencediff
27
 
from bzrlib.tests import (Feature, TestCase, TestCaseWithTransport,
 
26
from bzrlib.tests import (TestCase, TestCaseWithTransport,
28
27
                          TestCaseInTempDir, TestSkipped)
29
28
 
30
29
 
31
 
class _UnicodeFilename(Feature):
32
 
    """Does the filesystem support Unicode filenames?"""
33
 
 
34
 
    def _probe(self):
35
 
        try:
36
 
            os.stat(u'\u03b1')
37
 
        except UnicodeEncodeError:
38
 
            return False
39
 
        except (IOError, OSError):
40
 
            # The filesystem allows the Unicode filename but the file doesn't
41
 
            # exist.
42
 
            return True
43
 
        else:
44
 
            # The filesystem allows the Unicode filename and the file exists,
45
 
            # for some reason.
46
 
            return True
47
 
 
48
 
UnicodeFilename = _UnicodeFilename()
49
 
 
50
 
 
51
 
class TestUnicodeFilename(TestCase):
52
 
 
53
 
    def test_probe_passes(self):
54
 
        """UnicodeFilename._probe passes."""
55
 
        # We can't test much more than that because the behaviour depends
56
 
        # on the platform.
57
 
        UnicodeFilename._probe()
58
 
        
59
 
 
60
30
def udiff_lines(old, new, allow_binary=False):
61
31
    output = StringIO()
62
32
    internal_diff('old', old, 'new', new, output, allow_binary)
141
111
        self.check_patch(lines)
142
112
 
143
113
    def test_external_diff_binary_lang_c(self):
144
 
        old_env = {}
145
 
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
146
 
            old_env[lang] = osutils.set_or_unset_env(lang, 'C')
 
114
        orig_lang = os.environ.get('LANG')
 
115
        orig_lc_all = os.environ.get('LC_ALL')
147
116
        try:
 
117
            os.environ['LANG'] = 'C'
 
118
            os.environ['LC_ALL'] = 'C'
148
119
            lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
149
120
            # Older versions of diffutils say "Binary files", newer
150
121
            # versions just say "Files".
152
123
                                  '(Binary f|F)iles old and new differ\n')
153
124
            self.assertEquals(lines[1:], ['\n'])
154
125
        finally:
155
 
            for lang, old_val in old_env.iteritems():
156
 
                osutils.set_or_unset_env(lang, old_val)
 
126
            for name, value in [('LANG', orig_lang), ('LC_ALL', orig_lc_all)]:
 
127
                if value is None:
 
128
                    del os.environ[name]
 
129
                else:
 
130
                    os.environ[name] = value
157
131
 
158
132
    def test_no_external_diff(self):
159
133
        """Check that NoDiff is raised when diff is not available"""
231
205
        # Make sure external_diff doesn't fail in the current LANG
232
206
        lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
233
207
 
234
 
        cmd = ['diff', '-u', '--binary', 'old', 'new']
 
208
        cmd = ['diff', '-u', 'old', 'new']
235
209
        open('old', 'wb').write('\x00foobar\n')
236
210
        open('new', 'wb').write('foo\x00bar\n')
237
211
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
243
217
        self.assertEqual(out.splitlines(True) + ['\n'], lines)
244
218
 
245
219
 
246
 
class TestShowDiffTreesHelper(TestCaseWithTransport):
247
 
    """Has a helper for running show_diff_trees"""
248
 
 
249
 
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
250
 
        output = StringIO()
251
 
        if working_tree is not None:
252
 
            extra_trees = (working_tree,)
253
 
        else:
254
 
            extra_trees = ()
255
 
        show_diff_trees(tree1, tree2, output, specific_files=specific_files,
256
 
                        extra_trees=extra_trees, old_label='old/',
257
 
                        new_label='new/')
258
 
        return output.getvalue()
259
 
 
260
 
 
261
 
class TestDiffDates(TestShowDiffTreesHelper):
 
220
class TestDiffDates(TestCaseWithTransport):
262
221
 
263
222
    def setUp(self):
264
223
        super(TestDiffDates, self).setUp()
298
257
        # set the date stamps for files in the working tree to known values
299
258
        os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
300
259
 
 
260
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
 
261
        output = StringIO()
 
262
        if working_tree is not None:
 
263
            extra_trees = (working_tree,)
 
264
        else:
 
265
            extra_trees = ()
 
266
        show_diff_trees(tree1, tree2, output, specific_files=specific_files,
 
267
                        extra_trees=extra_trees, old_label='old/', 
 
268
                        new_label='new/')
 
269
        return output.getvalue()
 
270
 
301
271
    def test_diff_rev_tree_working_tree(self):
302
272
        output = self.get_diff(self.wt.basis_tree(), self.wt)
303
273
        # note that the date for old/file1 is from rev 2 rather than from
387
357
        self.assertNotContainsRe(out, 'file1\t')
388
358
 
389
359
 
390
 
 
391
 
class TestShowDiffTrees(TestShowDiffTreesHelper):
392
 
    """Direct tests for show_diff_trees"""
393
 
 
394
 
    def test_modified_file(self):
395
 
        """Test when a file is modified."""
396
 
        tree = self.make_branch_and_tree('tree')
397
 
        self.build_tree_contents([('tree/file', 'contents\n')])
398
 
        tree.add(['file'], ['file-id'])
399
 
        tree.commit('one', rev_id='rev-1')
400
 
 
401
 
        self.build_tree_contents([('tree/file', 'new contents\n')])
402
 
        diff = self.get_diff(tree.basis_tree(), tree)
403
 
        self.assertContainsRe(diff, "=== modified file 'file'\n")
404
 
        self.assertContainsRe(diff, '--- old/file\t')
405
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/file\t')
406
 
        self.assertContainsRe(diff, '-contents\n'
407
 
                                    '\\+new contents\n')
408
 
 
409
 
    def test_modified_file_in_renamed_dir(self):
410
 
        """Test when a file is modified in a renamed directory."""
411
 
        tree = self.make_branch_and_tree('tree')
412
 
        self.build_tree(['tree/dir/'])
413
 
        self.build_tree_contents([('tree/dir/file', 'contents\n')])
414
 
        tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
415
 
        tree.commit('one', rev_id='rev-1')
416
 
 
417
 
        tree.rename_one('dir', 'other')
418
 
        self.build_tree_contents([('tree/other/file', 'new contents\n')])
419
 
        diff = self.get_diff(tree.basis_tree(), tree)
420
 
        self.assertContainsRe(diff, "=== renamed directory 'dir' => 'other'\n")
421
 
        self.assertContainsRe(diff, "=== modified file 'other/file'\n")
422
 
        # XXX: This is technically incorrect, because it used to be at another
423
 
        # location. What to do?
424
 
        self.assertContainsRe(diff, '--- old/dir/file\t')
425
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/other/file\t')
426
 
        self.assertContainsRe(diff, '-contents\n'
427
 
                                    '\\+new contents\n')
428
 
 
429
 
    def test_renamed_directory(self):
430
 
        """Test when only a directory is only renamed."""
431
 
        tree = self.make_branch_and_tree('tree')
432
 
        self.build_tree(['tree/dir/'])
433
 
        self.build_tree_contents([('tree/dir/file', 'contents\n')])
434
 
        tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
435
 
        tree.commit('one', rev_id='rev-1')
436
 
 
437
 
        tree.rename_one('dir', 'newdir')
438
 
        diff = self.get_diff(tree.basis_tree(), tree)
439
 
        # Renaming a directory should be a single "you renamed this dir" even
440
 
        # when there are files inside.
441
 
        self.assertEqual("=== renamed directory 'dir' => 'newdir'\n", diff)
442
 
 
443
 
    def test_renamed_file(self):
444
 
        """Test when a file is only renamed."""
445
 
        tree = self.make_branch_and_tree('tree')
446
 
        self.build_tree_contents([('tree/file', 'contents\n')])
447
 
        tree.add(['file'], ['file-id'])
448
 
        tree.commit('one', rev_id='rev-1')
449
 
 
450
 
        tree.rename_one('file', 'newname')
451
 
        diff = self.get_diff(tree.basis_tree(), tree)
452
 
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
453
 
        # We shouldn't have a --- or +++ line, because there is no content
454
 
        # change
455
 
        self.assertNotContainsRe(diff, '---')
456
 
 
457
 
    def test_renamed_and_modified_file(self):
458
 
        """Test when a file is only renamed."""
459
 
        tree = self.make_branch_and_tree('tree')
460
 
        self.build_tree_contents([('tree/file', 'contents\n')])
461
 
        tree.add(['file'], ['file-id'])
462
 
        tree.commit('one', rev_id='rev-1')
463
 
 
464
 
        tree.rename_one('file', 'newname')
465
 
        self.build_tree_contents([('tree/newname', 'new contents\n')])
466
 
        diff = self.get_diff(tree.basis_tree(), tree)
467
 
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
468
 
        self.assertContainsRe(diff, '--- old/file\t')
469
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/newname\t')
470
 
        self.assertContainsRe(diff, '-contents\n'
471
 
                                    '\\+new contents\n')
472
 
 
473
 
    def test_binary_unicode_filenames(self):
474
 
        """Test that contents of files are *not* encoded in UTF-8 when there
475
 
        is a binary file in the diff.
476
 
        """
477
 
        # See https://bugs.launchpad.net/bugs/110092.
478
 
        self.requireFeature(UnicodeFilename)
479
 
 
480
 
        # This bug isn't triggered with cStringIO.
481
 
        from StringIO import StringIO
482
 
        tree = self.make_branch_and_tree('tree')
483
 
        alpha, omega = u'\u03b1', u'\u03c9'
484
 
        alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
485
 
        self.build_tree_contents(
486
 
            [('tree/' + alpha, chr(0)),
487
 
             ('tree/' + omega,
488
 
              ('The %s and the %s\n' % (alpha_utf8, omega_utf8)))])
489
 
        tree.add([alpha], ['file-id'])
490
 
        tree.add([omega], ['file-id-2'])
491
 
        diff_content = StringIO()
492
 
        show_diff_trees(tree.basis_tree(), tree, diff_content)
493
 
        diff = diff_content.getvalue()
494
 
        self.assertContainsRe(diff, r"=== added file '%s'" % alpha_utf8)
495
 
        self.assertContainsRe(
496
 
            diff, "Binary files a/%s.*and b/%s.* differ\n" % (alpha_utf8, alpha_utf8))
497
 
        self.assertContainsRe(diff, r"=== added file '%s'" % omega_utf8)
498
 
        self.assertContainsRe(diff, r"--- a/%s" % (omega_utf8,))
499
 
        self.assertContainsRe(diff, r"\+\+\+ b/%s" % (omega_utf8,))
500
 
 
501
 
 
502
360
class TestPatienceDiffLib(TestCase):
503
361
 
504
362
    def test_unique_lcs(self):