34
from bzrlib.tests import (
35
from bzrlib.symbol_versioning import deprecated_in
36
from bzrlib.tests import features, EncodingAdapter
38
37
from bzrlib.tests.blackbox.test_diff import subst_dates
39
from bzrlib.tests.scenarios import load_tests_apply_scenarios
42
load_tests = load_tests_apply_scenarios
40
class _AttribFeature(tests.Feature):
43
if (sys.platform not in ('cygwin', 'win32')):
46
proc = subprocess.Popen(['attrib', '.'], stdout=subprocess.PIPE)
49
return (0 == proc.wait())
51
def feature_name(self):
52
return 'attrib Windows command-line tool'
54
AttribFeature = _AttribFeature()
57
compiled_patiencediff_feature = tests.ModuleAvailableFeature(
58
'bzrlib._patiencediff_c')
45
61
def udiff_lines(old, new, allow_binary=False):
68
class TestDiffOptions(tests.TestCase):
70
def test_unified_added(self):
71
"""Check for default style '-u' only if no other style specified
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']))
79
class TestDiffOptionsScenarios(tests.TestCase):
81
scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
82
style = None # Set by load_tests_apply_scenarios from scenarios
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)
91
84
class TestDiff(tests.TestCase):
93
86
def test_add_nl(self):
236
229
self.assertIsInstance(output.getvalue(), str,
237
230
'internal_diff should return bytestrings')
239
def test_internal_diff_default_context(self):
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',
259
def test_internal_diff_no_context(self):
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,
266
lines = output.getvalue().splitlines(True)
267
self.check_patch(lines)
268
self.assertEquals(['--- old\n',
277
def test_internal_diff_more_context(self):
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,
284
lines = output.getvalue().splitlines(True)
285
self.check_patch(lines)
286
self.assertEquals(['--- old\n',
303
233
class TestDiffFiles(tests.TestCaseInTempDir):
308
238
lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
310
240
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')
241
open('old', 'wb').write('\x00foobar\n')
242
open('new', 'wb').write('foo\x00bar\n')
313
243
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
314
244
stdin=subprocess.PIPE)
315
245
out, err = pipe.communicate()
584
514
is a binary file in the diff.
586
516
# See https://bugs.launchpad.net/bugs/110092.
587
self.requireFeature(features.UnicodeFilenameFeature)
517
self.requireFeature(tests.UnicodeFilenameFeature)
589
519
# This bug isn't triggered with cStringIO.
590
520
from StringIO import StringIO
610
540
def test_unicode_filename(self):
611
541
"""Test when the filename are unicode."""
612
self.requireFeature(features.UnicodeFilenameFeature)
542
self.requireFeature(tests.UnicodeFilenameFeature)
614
544
alpha, omega = u'\u03b1', u'\u03c9'
615
545
autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
641
571
"""Test for bug #382699: unicode filenames on Windows should be shown
642
572
in user encoding.
644
self.requireFeature(features.UnicodeFilenameFeature)
574
self.requireFeature(tests.UnicodeFilenameFeature)
645
575
# The word 'test' in Russian
646
576
_russian_test = u'\u0422\u0435\u0441\u0442'
647
577
directory = _russian_test + u'/'
778
708
' \@\@\n-old\n\+new\n\n')
780
710
def test_diff_kind_change(self):
781
self.requireFeature(features.SymlinkFeature)
711
self.requireFeature(tests.SymlinkFeature)
782
712
self.build_tree_contents([('old-tree/olddir/',),
783
713
('old-tree/olddir/oldfile', 'old\n')])
784
714
self.old_tree.add('olddir')
1279
1209
'how are you today?\n']
1280
1210
txt_b = ['hello there\n',
1281
1211
'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)
1212
open('a1', 'wb').writelines(txt_a)
1213
open('b1', 'wb').writelines(txt_b)
1285
1215
unified_diff_files = patiencediff.unified_diff_files
1286
1216
psm = self._PatienceSequenceMatcher
1297
1227
txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
1298
1228
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)
1229
open('a2', 'wb').writelines(txt_a)
1230
open('b2', 'wb').writelines(txt_b)
1302
1232
# This is the result with LongestCommonSubstring matching
1303
1233
self.assertEquals(['--- a2\n',
1350
1280
class TestUsingCompiledIfAvailable(tests.TestCase):
1352
1282
def test_PatienceSequenceMatcher(self):
1353
if features.compiled_patiencediff_feature.available():
1283
if compiled_patiencediff_feature.available():
1354
1284
from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
1355
1285
self.assertIs(PatienceSequenceMatcher_c,
1356
1286
patiencediff.PatienceSequenceMatcher)
1360
1290
patiencediff.PatienceSequenceMatcher)
1362
1292
def test_unique_lcs(self):
1363
if features.compiled_patiencediff_feature.available():
1293
if compiled_patiencediff_feature.available():
1364
1294
from bzrlib._patiencediff_c import unique_lcs_c
1365
1295
self.assertIs(unique_lcs_c,
1366
1296
patiencediff.unique_lcs)
1370
1300
patiencediff.unique_lcs)
1372
1302
def test_recurse_matches(self):
1373
if features.compiled_patiencediff_feature.available():
1303
if compiled_patiencediff_feature.available():
1374
1304
from bzrlib._patiencediff_c import recurse_matches_c
1375
1305
self.assertIs(recurse_matches_c,
1376
1306
patiencediff.recurse_matches)
1416
1346
diff_obj._execute('old', 'new')
1417
1347
self.assertEqual(output.getvalue().rstrip(), 'old new')
1419
def test_execute_missing(self):
1349
def test_excute_missing(self):
1420
1350
diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
1421
1351
None, None, None)
1422
1352
self.addCleanup(diff_obj.finish)
1426
1356
' on this machine', str(e))
1428
1358
def test_prepare_files_creates_paths_readable_by_windows_tool(self):
1429
self.requireFeature(features.AttribFeature)
1359
self.requireFeature(AttribFeature)
1430
1360
output = StringIO()
1431
1361
tree = self.make_branch_and_tree('tree')
1432
1362
self.build_tree_contents([('tree/file', 'content')])
1496
1426
def test_encodable_filename(self):
1497
1427
# Just checks file path for external diff tool.
1498
1428
# We cannot change CPython's internal encoding used by os.exec*.
1499
1430
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1500
1431
None, None, None)
1501
1432
for _, scenario in EncodingAdapter.encoding_scenarios:
1513
1444
self.assert_(fullpath.startswith(diffobj._root + '/safe'))
1515
1446
def test_unencodable_filename(self):
1516
1448
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1517
1449
None, None, None)
1518
1450
for _, scenario in EncodingAdapter.encoding_scenarios:
1538
1470
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1540
1472
def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1541
"""Call get_trees_and_branches_to_diff_locked."""
1473
"""Call get_trees_and_branches_to_diff_locked. Overridden by
1474
TestGetTreesAndBranchesToDiff.
1542
1476
return diff.get_trees_and_branches_to_diff_locked(
1543
1477
path_list, revision_specs, old_url, new_url, self.addCleanup)
1581
1515
self.assertEqual(tree.branch.base, new_branch.base)
1582
1516
self.assertIs(None, specific_files)
1583
1517
self.assertEqual(tree.basedir, extra_trees[0].basedir)
1520
class TestGetTreesAndBranchesToDiff(TestGetTreesAndBranchesToDiffLocked):
1521
"""Apply the tests for get_trees_and_branches_to_diff_locked to the
1522
deprecated get_trees_and_branches_to_diff function.
1525
def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1526
return self.applyDeprecated(
1527
deprecated_in((2, 2, 0)), diff.get_trees_and_branches_to_diff,
1528
path_list, revision_specs, old_url, new_url)