~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 08:02:42 UTC
  • mfrom: (5390.3.3 faster-revert-593560)
  • Revision ID: pqm@pqm.ubuntu.com-20100901080242-esg62ody4frwmy66
(spiv) Avoid repeatedly calling self.target.all_file_ids() in
 InterTree.iter_changes. (Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2014 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
17
17
import os
18
18
from cStringIO import StringIO
19
19
import subprocess
 
20
import sys
20
21
import tempfile
21
22
 
22
23
from bzrlib import (
31
32
    tests,
32
33
    transform,
33
34
    )
34
 
from bzrlib.tests import (
35
 
    features,
36
 
    EncodingAdapter,
37
 
)
 
35
from bzrlib.symbol_versioning import deprecated_in
 
36
from bzrlib.tests import features
38
37
from bzrlib.tests.blackbox.test_diff import subst_dates
39
 
from bzrlib.tests.scenarios import load_tests_apply_scenarios
40
 
 
41
 
 
42
 
load_tests = load_tests_apply_scenarios
 
38
 
 
39
 
 
40
class _AttribFeature(tests.Feature):
 
41
 
 
42
    def _probe(self):
 
43
        if (sys.platform not in ('cygwin', 'win32')):
 
44
            return False
 
45
        try:
 
46
            proc = subprocess.Popen(['attrib', '.'], stdout=subprocess.PIPE)
 
47
        except OSError, e:
 
48
            return False
 
49
        return (0 == proc.wait())
 
50
 
 
51
    def feature_name(self):
 
52
        return 'attrib Windows command-line tool'
 
53
 
 
54
AttribFeature = _AttribFeature()
 
55
 
 
56
 
 
57
compiled_patiencediff_feature = tests.ModuleAvailableFeature(
 
58
                                    'bzrlib._patiencediff_c')
43
59
 
44
60
 
45
61
def udiff_lines(old, new, allow_binary=False):
65
81
    return lines
66
82
 
67
83
 
68
 
class TestDiffOptions(tests.TestCase):
69
 
 
70
 
    def test_unified_added(self):
71
 
        """Check for default style '-u' only if no other style specified
72
 
        in 'diff-options'.
73
 
        """
74
 
        # Verify that style defaults to unified, id est '-u' appended
75
 
        # to option list, in the absence of an alternative style.
76
 
        self.assertEqual(['-a', '-u'], diff.default_style_unified(['-a']))
77
 
 
78
 
 
79
 
class TestDiffOptionsScenarios(tests.TestCase):
80
 
 
81
 
    scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
82
 
    style = None # Set by load_tests_apply_scenarios from scenarios
83
 
 
84
 
    def test_unified_not_added(self):
85
 
        # Verify that for all valid style options, '-u' is not
86
 
        # appended to option list.
87
 
        ret_opts = diff.default_style_unified(diff_opts=["%s" % (self.style,)])
88
 
        self.assertEqual(["%s" % (self.style,)], ret_opts)
89
 
 
90
 
 
91
84
class TestDiff(tests.TestCase):
92
85
 
93
86
    def test_add_nl(self):
151
144
        self.check_patch(lines)
152
145
 
153
146
    def test_external_diff_binary_lang_c(self):
 
147
        old_env = {}
154
148
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
155
 
            self.overrideEnv(lang, 'C')
156
 
        lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
157
 
        # Older versions of diffutils say "Binary files", newer
158
 
        # versions just say "Files".
159
 
        self.assertContainsRe(lines[0], '(Binary f|F)iles old and new differ\n')
160
 
        self.assertEquals(lines[1:], ['\n'])
 
149
            old_env[lang] = osutils.set_or_unset_env(lang, 'C')
 
150
        try:
 
151
            lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
 
152
            # Older versions of diffutils say "Binary files", newer
 
153
            # versions just say "Files".
 
154
            self.assertContainsRe(lines[0],
 
155
                                  '(Binary f|F)iles old and new differ\n')
 
156
            self.assertEquals(lines[1:], ['\n'])
 
157
        finally:
 
158
            for lang, old_val in old_env.iteritems():
 
159
                osutils.set_or_unset_env(lang, old_val)
161
160
 
162
161
    def test_no_external_diff(self):
163
162
        """Check that NoDiff is raised when diff is not available"""
164
 
        # Make sure no 'diff' command is available
165
 
        # XXX: Weird, using None instead of '' breaks the test -- vila 20101216
166
 
        self.overrideEnv('PATH', '')
167
 
        self.assertRaises(errors.NoDiff, diff.external_diff,
168
 
                          'old', ['boo\n'], 'new', ['goo\n'],
169
 
                          StringIO(), diff_opts=['-u'])
 
163
        # Use os.environ['PATH'] to make sure no 'diff' command is available
 
164
        orig_path = os.environ['PATH']
 
165
        try:
 
166
            os.environ['PATH'] = ''
 
167
            self.assertRaises(errors.NoDiff, diff.external_diff,
 
168
                              'old', ['boo\n'], 'new', ['goo\n'],
 
169
                              StringIO(), diff_opts=['-u'])
 
170
        finally:
 
171
            os.environ['PATH'] = orig_path
170
172
 
171
173
    def test_internal_diff_default(self):
172
174
        # Default internal diff encoding is utf8
233
235
        output = StringIO.StringIO()
234
236
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
235
237
                            u'new_\xe5', ['new_text\n'], output)
236
 
        self.assertIsInstance(output.getvalue(), str,
 
238
        self.failUnless(isinstance(output.getvalue(), str),
237
239
            'internal_diff should return bytestrings')
238
240
 
239
 
    def test_internal_diff_default_context(self):
240
 
        output = StringIO()
241
 
        diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
242
 
                           'same_text\n','same_text\n','old_text\n'],
243
 
                           'new', ['same_text\n','same_text\n','same_text\n',
244
 
                           'same_text\n','same_text\n','new_text\n'], output)
245
 
        lines = output.getvalue().splitlines(True)
246
 
        self.check_patch(lines)
247
 
        self.assertEquals(['--- old\n',
248
 
                           '+++ new\n',
249
 
                           '@@ -3,4 +3,4 @@\n',
250
 
                           ' same_text\n',
251
 
                           ' same_text\n',
252
 
                           ' same_text\n',
253
 
                           '-old_text\n',
254
 
                           '+new_text\n',
255
 
                           '\n',
256
 
                          ]
257
 
                          , lines)
258
 
 
259
 
    def test_internal_diff_no_context(self):
260
 
        output = StringIO()
261
 
        diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
262
 
                           'same_text\n','same_text\n','old_text\n'],
263
 
                           'new', ['same_text\n','same_text\n','same_text\n',
264
 
                           'same_text\n','same_text\n','new_text\n'], output,
265
 
                           context_lines=0)
266
 
        lines = output.getvalue().splitlines(True)
267
 
        self.check_patch(lines)
268
 
        self.assertEquals(['--- old\n',
269
 
                           '+++ new\n',
270
 
                           '@@ -6,1 +6,1 @@\n',
271
 
                           '-old_text\n',
272
 
                           '+new_text\n',
273
 
                           '\n',
274
 
                          ]
275
 
                          , lines)
276
 
 
277
 
    def test_internal_diff_more_context(self):
278
 
        output = StringIO()
279
 
        diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
280
 
                           'same_text\n','same_text\n','old_text\n'],
281
 
                           'new', ['same_text\n','same_text\n','same_text\n',
282
 
                           'same_text\n','same_text\n','new_text\n'], output,
283
 
                           context_lines=4)
284
 
        lines = output.getvalue().splitlines(True)
285
 
        self.check_patch(lines)
286
 
        self.assertEquals(['--- old\n',
287
 
                           '+++ new\n',
288
 
                           '@@ -2,5 +2,5 @@\n',
289
 
                           ' same_text\n',
290
 
                           ' same_text\n',
291
 
                           ' same_text\n',
292
 
                           ' same_text\n',
293
 
                           '-old_text\n',
294
 
                           '+new_text\n',
295
 
                           '\n',
296
 
                          ]
297
 
                          , lines)
298
 
 
299
 
 
300
 
 
301
 
 
302
241
 
303
242
class TestDiffFiles(tests.TestCaseInTempDir):
304
243
 
308
247
        lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
309
248
 
310
249
        cmd = ['diff', '-u', '--binary', 'old', 'new']
311
 
        with open('old', 'wb') as f: f.write('\x00foobar\n')
312
 
        with open('new', 'wb') as f: f.write('foo\x00bar\n')
 
250
        open('old', 'wb').write('\x00foobar\n')
 
251
        open('new', 'wb').write('foo\x00bar\n')
313
252
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
314
253
                                     stdin=subprocess.PIPE)
315
254
        out, err = pipe.communicate()
319
258
        self.assertEqual(out.splitlines(True) + ['\n'], lines)
320
259
 
321
260
 
322
 
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
323
 
    output = StringIO()
324
 
    if working_tree is not None:
325
 
        extra_trees = (working_tree,)
326
 
    else:
327
 
        extra_trees = ()
328
 
    diff.show_diff_trees(tree1, tree2, output,
329
 
        specific_files=specific_files,
330
 
        extra_trees=extra_trees, old_label='old/',
331
 
        new_label='new/')
332
 
    return output.getvalue()
333
 
 
334
 
 
335
 
class TestDiffDates(tests.TestCaseWithTransport):
 
261
class TestShowDiffTreesHelper(tests.TestCaseWithTransport):
 
262
    """Has a helper for running show_diff_trees"""
 
263
 
 
264
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
 
265
        output = StringIO()
 
266
        if working_tree is not None:
 
267
            extra_trees = (working_tree,)
 
268
        else:
 
269
            extra_trees = ()
 
270
        diff.show_diff_trees(tree1, tree2, output,
 
271
                             specific_files=specific_files,
 
272
                             extra_trees=extra_trees, old_label='old/',
 
273
                             new_label='new/')
 
274
        return output.getvalue()
 
275
 
 
276
 
 
277
class TestDiffDates(TestShowDiffTreesHelper):
336
278
 
337
279
    def setUp(self):
338
280
        super(TestDiffDates, self).setUp()
373
315
        os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
374
316
 
375
317
    def test_diff_rev_tree_working_tree(self):
376
 
        output = get_diff_as_string(self.wt.basis_tree(), self.wt)
 
318
        output = self.get_diff(self.wt.basis_tree(), self.wt)
377
319
        # note that the date for old/file1 is from rev 2 rather than from
378
320
        # the basis revision (rev 4)
379
321
        self.assertEqualDiff(output, '''\
389
331
    def test_diff_rev_tree_rev_tree(self):
390
332
        tree1 = self.b.repository.revision_tree('rev-2')
391
333
        tree2 = self.b.repository.revision_tree('rev-3')
392
 
        output = get_diff_as_string(tree1, tree2)
 
334
        output = self.get_diff(tree1, tree2)
393
335
        self.assertEqualDiff(output, '''\
394
336
=== modified file 'file2'
395
337
--- old/file2\t2006-04-01 00:00:00 +0000
403
345
    def test_diff_add_files(self):
404
346
        tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
405
347
        tree2 = self.b.repository.revision_tree('rev-1')
406
 
        output = get_diff_as_string(tree1, tree2)
 
348
        output = self.get_diff(tree1, tree2)
407
349
        # the files have the epoch time stamp for the tree in which
408
350
        # they don't exist.
409
351
        self.assertEqualDiff(output, '''\
424
366
    def test_diff_remove_files(self):
425
367
        tree1 = self.b.repository.revision_tree('rev-3')
426
368
        tree2 = self.b.repository.revision_tree('rev-4')
427
 
        output = get_diff_as_string(tree1, tree2)
 
369
        output = self.get_diff(tree1, tree2)
428
370
        # the file has the epoch time stamp for the tree in which
429
371
        # it doesn't exist.
430
372
        self.assertEqualDiff(output, '''\
441
383
        self.wt.rename_one('file1', 'file1b')
442
384
        old_tree = self.b.repository.revision_tree('rev-1')
443
385
        new_tree = self.b.repository.revision_tree('rev-4')
444
 
        out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
 
386
        out = self.get_diff(old_tree, new_tree, specific_files=['file1b'],
445
387
                            working_tree=self.wt)
446
388
        self.assertContainsRe(out, 'file1\t')
447
389
 
453
395
        self.wt.rename_one('file1', 'dir1/file1')
454
396
        old_tree = self.b.repository.revision_tree('rev-1')
455
397
        new_tree = self.b.repository.revision_tree('rev-4')
456
 
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
 
398
        out = self.get_diff(old_tree, new_tree, specific_files=['dir1'],
457
399
                            working_tree=self.wt)
458
400
        self.assertContainsRe(out, 'file1\t')
459
 
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
 
401
        out = self.get_diff(old_tree, new_tree, specific_files=['dir2'],
460
402
                            working_tree=self.wt)
461
403
        self.assertNotContainsRe(out, 'file1\t')
462
404
 
463
405
 
464
 
class TestShowDiffTrees(tests.TestCaseWithTransport):
 
406
 
 
407
class TestShowDiffTrees(TestShowDiffTreesHelper):
465
408
    """Direct tests for show_diff_trees"""
466
409
 
467
410
    def test_modified_file(self):
472
415
        tree.commit('one', rev_id='rev-1')
473
416
 
474
417
        self.build_tree_contents([('tree/file', 'new contents\n')])
475
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
418
        d = self.get_diff(tree.basis_tree(), tree)
476
419
        self.assertContainsRe(d, "=== modified file 'file'\n")
477
420
        self.assertContainsRe(d, '--- old/file\t')
478
421
        self.assertContainsRe(d, '\\+\\+\\+ new/file\t')
489
432
 
490
433
        tree.rename_one('dir', 'other')
491
434
        self.build_tree_contents([('tree/other/file', 'new contents\n')])
492
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
435
        d = self.get_diff(tree.basis_tree(), tree)
493
436
        self.assertContainsRe(d, "=== renamed directory 'dir' => 'other'\n")
494
437
        self.assertContainsRe(d, "=== modified file 'other/file'\n")
495
438
        # XXX: This is technically incorrect, because it used to be at another
508
451
        tree.commit('one', rev_id='rev-1')
509
452
 
510
453
        tree.rename_one('dir', 'newdir')
511
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
454
        d = self.get_diff(tree.basis_tree(), tree)
512
455
        # Renaming a directory should be a single "you renamed this dir" even
513
456
        # when there are files inside.
514
457
        self.assertEqual(d, "=== renamed directory 'dir' => 'newdir'\n")
521
464
        tree.commit('one', rev_id='rev-1')
522
465
 
523
466
        tree.rename_one('file', 'newname')
524
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
467
        d = self.get_diff(tree.basis_tree(), tree)
525
468
        self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
526
469
        # We shouldn't have a --- or +++ line, because there is no content
527
470
        # change
536
479
 
537
480
        tree.rename_one('file', 'newname')
538
481
        self.build_tree_contents([('tree/newname', 'new contents\n')])
539
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
482
        d = self.get_diff(tree.basis_tree(), tree)
540
483
        self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
541
484
        self.assertContainsRe(d, '--- old/file\t')
542
485
        self.assertContainsRe(d, '\\+\\+\\+ new/newname\t')
566
509
        tree.rename_one('c', 'new-c')
567
510
        tree.rename_one('d', 'new-d')
568
511
 
569
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
512
        d = self.get_diff(tree.basis_tree(), tree)
570
513
 
571
514
        self.assertContainsRe(d, r"file 'a'.*\(properties changed:"
572
515
                                  ".*\+x to -x.*\)")
584
527
        is a binary file in the diff.
585
528
        """
586
529
        # See https://bugs.launchpad.net/bugs/110092.
587
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
530
        self.requireFeature(tests.UnicodeFilenameFeature)
588
531
 
589
532
        # This bug isn't triggered with cStringIO.
590
533
        from StringIO import StringIO
609
552
 
610
553
    def test_unicode_filename(self):
611
554
        """Test when the filename are unicode."""
612
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
555
        self.requireFeature(tests.UnicodeFilenameFeature)
613
556
 
614
557
        alpha, omega = u'\u03b1', u'\u03c9'
615
558
        autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
630
573
        tree.add(['add_'+alpha], ['file-id'])
631
574
        self.build_tree_contents([('tree/mod_'+alpha, 'contents_mod\n')])
632
575
 
633
 
        d = get_diff_as_string(tree.basis_tree(), tree)
 
576
        d = self.get_diff(tree.basis_tree(), tree)
634
577
        self.assertContainsRe(d,
635
578
                "=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
636
579
        self.assertContainsRe(d, "=== added file 'add_%s'"%autf8)
641
584
        """Test for bug #382699: unicode filenames on Windows should be shown
642
585
        in user encoding.
643
586
        """
644
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
587
        self.requireFeature(tests.UnicodeFilenameFeature)
645
588
        # The word 'test' in Russian
646
589
        _russian_test = u'\u0422\u0435\u0441\u0442'
647
590
        directory = _russian_test + u'/'
778
721
             ' \@\@\n-old\n\+new\n\n')
779
722
 
780
723
    def test_diff_kind_change(self):
781
 
        self.requireFeature(features.SymlinkFeature)
 
724
        self.requireFeature(tests.SymlinkFeature)
782
725
        self.build_tree_contents([('old-tree/olddir/',),
783
726
                                  ('old-tree/olddir/oldfile', 'old\n')])
784
727
        self.old_tree.add('olddir')
1242
1185
 
1243
1186
class TestPatienceDiffLib_c(TestPatienceDiffLib):
1244
1187
 
1245
 
    _test_needs_features = [features.compiled_patiencediff_feature]
 
1188
    _test_needs_features = [compiled_patiencediff_feature]
1246
1189
 
1247
1190
    def setUp(self):
1248
1191
        super(TestPatienceDiffLib_c, self).setUp()
1279
1222
                 'how are you today?\n']
1280
1223
        txt_b = ['hello there\n',
1281
1224
                 'how are you today?\n']
1282
 
        with open('a1', 'wb') as f: f.writelines(txt_a)
1283
 
        with open('b1', 'wb') as f: f.writelines(txt_b)
 
1225
        open('a1', 'wb').writelines(txt_a)
 
1226
        open('b1', 'wb').writelines(txt_b)
1284
1227
 
1285
1228
        unified_diff_files = patiencediff.unified_diff_files
1286
1229
        psm = self._PatienceSequenceMatcher
1296
1239
 
1297
1240
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
1298
1241
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
1299
 
        with open('a2', 'wb') as f: f.writelines(txt_a)
1300
 
        with open('b2', 'wb') as f: f.writelines(txt_b)
 
1242
        open('a2', 'wb').writelines(txt_a)
 
1243
        open('b2', 'wb').writelines(txt_b)
1301
1244
 
1302
1245
        # This is the result with LongestCommonSubstring matching
1303
1246
        self.assertEquals(['--- a2\n',
1338
1281
 
1339
1282
class TestPatienceDiffLibFiles_c(TestPatienceDiffLibFiles):
1340
1283
 
1341
 
    _test_needs_features = [features.compiled_patiencediff_feature]
 
1284
    _test_needs_features = [compiled_patiencediff_feature]
1342
1285
 
1343
1286
    def setUp(self):
1344
1287
        super(TestPatienceDiffLibFiles_c, self).setUp()
1350
1293
class TestUsingCompiledIfAvailable(tests.TestCase):
1351
1294
 
1352
1295
    def test_PatienceSequenceMatcher(self):
1353
 
        if features.compiled_patiencediff_feature.available():
 
1296
        if compiled_patiencediff_feature.available():
1354
1297
            from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
1355
1298
            self.assertIs(PatienceSequenceMatcher_c,
1356
1299
                          patiencediff.PatienceSequenceMatcher)
1360
1303
                          patiencediff.PatienceSequenceMatcher)
1361
1304
 
1362
1305
    def test_unique_lcs(self):
1363
 
        if features.compiled_patiencediff_feature.available():
 
1306
        if compiled_patiencediff_feature.available():
1364
1307
            from bzrlib._patiencediff_c import unique_lcs_c
1365
1308
            self.assertIs(unique_lcs_c,
1366
1309
                          patiencediff.unique_lcs)
1370
1313
                          patiencediff.unique_lcs)
1371
1314
 
1372
1315
    def test_recurse_matches(self):
1373
 
        if features.compiled_patiencediff_feature.available():
 
1316
        if compiled_patiencediff_feature.available():
1374
1317
            from bzrlib._patiencediff_c import recurse_matches_c
1375
1318
            self.assertIs(recurse_matches_c,
1376
1319
                          patiencediff.recurse_matches)
1416
1359
        diff_obj._execute('old', 'new')
1417
1360
        self.assertEqual(output.getvalue().rstrip(), 'old new')
1418
1361
 
1419
 
    def test_execute_missing(self):
 
1362
    def test_excute_missing(self):
1420
1363
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
1421
1364
                                     None, None, None)
1422
1365
        self.addCleanup(diff_obj.finish)
1426
1369
                         ' on this machine', str(e))
1427
1370
 
1428
1371
    def test_prepare_files_creates_paths_readable_by_windows_tool(self):
1429
 
        self.requireFeature(features.AttribFeature)
 
1372
        self.requireFeature(AttribFeature)
1430
1373
        output = StringIO()
1431
1374
        tree = self.make_branch_and_tree('tree')
1432
1375
        self.build_tree_contents([('tree/file', 'content')])
1491
1434
        diff_obj._prepare_files('file2-id', 'oldname2', 'newname2')
1492
1435
 
1493
1436
 
1494
 
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
1495
 
 
1496
 
    def test_encodable_filename(self):
1497
 
        # Just checks file path for external diff tool.
1498
 
        # We cannot change CPython's internal encoding used by os.exec*.
1499
 
        diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1500
 
                                    None, None, None)
1501
 
        for _, scenario in EncodingAdapter.encoding_scenarios:
1502
 
            encoding = scenario['encoding']
1503
 
            dirname  = scenario['info']['directory']
1504
 
            filename = scenario['info']['filename']
1505
 
 
1506
 
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1507
 
            relpath = dirname + u'/' + filename
1508
 
            fullpath = diffobj._safe_filename('safe', relpath)
1509
 
            self.assertEqual(
1510
 
                    fullpath,
1511
 
                    fullpath.encode(encoding).decode(encoding)
1512
 
                    )
1513
 
            self.assert_(fullpath.startswith(diffobj._root + '/safe'))
1514
 
 
1515
 
    def test_unencodable_filename(self):
1516
 
        diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1517
 
                                    None, None, None)
1518
 
        for _, scenario in EncodingAdapter.encoding_scenarios:
1519
 
            encoding = scenario['encoding']
1520
 
            dirname  = scenario['info']['directory']
1521
 
            filename = scenario['info']['filename']
1522
 
 
1523
 
            if encoding == 'iso-8859-1':
1524
 
                encoding = 'iso-8859-2'
1525
 
            else:
1526
 
                encoding = 'iso-8859-1'
1527
 
 
1528
 
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1529
 
            relpath = dirname + u'/' + filename
1530
 
            fullpath = diffobj._safe_filename('safe', relpath)
1531
 
            self.assertEqual(
1532
 
                    fullpath,
1533
 
                    fullpath.encode(encoding).decode(encoding)
1534
 
                    )
1535
 
            self.assert_(fullpath.startswith(diffobj._root + '/safe'))
1536
 
 
1537
 
 
1538
1437
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1539
1438
 
1540
1439
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1541
 
        """Call get_trees_and_branches_to_diff_locked."""
 
1440
        """Call get_trees_and_branches_to_diff_locked.  Overridden by
 
1441
        TestGetTreesAndBranchesToDiff.
 
1442
        """
1542
1443
        return diff.get_trees_and_branches_to_diff_locked(
1543
1444
            path_list, revision_specs, old_url, new_url, self.addCleanup)
1544
1445
 
1581
1482
        self.assertEqual(tree.branch.base, new_branch.base)
1582
1483
        self.assertIs(None, specific_files)
1583
1484
        self.assertEqual(tree.basedir, extra_trees[0].basedir)
 
1485
 
 
1486
 
 
1487
class TestGetTreesAndBranchesToDiff(TestGetTreesAndBranchesToDiffLocked):
 
1488
    """Apply the tests for get_trees_and_branches_to_diff_locked to the
 
1489
    deprecated get_trees_and_branches_to_diff function.
 
1490
    """
 
1491
 
 
1492
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
 
1493
        return self.applyDeprecated(
 
1494
            deprecated_in((2, 2, 0)), diff.get_trees_and_branches_to_diff,
 
1495
            path_list, revision_specs, old_url, new_url)
 
1496