144
144
self.check_patch(lines)
146
146
def test_external_diff_binary_lang_c(self):
148
147
for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
149
old_env[lang] = osutils.set_or_unset_env(lang, 'C')
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'])
158
for lang, old_val in old_env.iteritems():
159
osutils.set_or_unset_env(lang, old_val)
148
self.overrideEnv(lang, 'C')
149
lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
150
# Older versions of diffutils say "Binary files", newer
151
# versions just say "Files".
152
self.assertContainsRe(lines[0], '(Binary f|F)iles old and new differ\n')
153
self.assertEquals(lines[1:], ['\n'])
161
155
def test_no_external_diff(self):
162
156
"""Check that NoDiff is raised when diff is not available"""
163
# Use os.environ['PATH'] to make sure no 'diff' command is available
164
orig_path = os.environ['PATH']
166
os.environ['PATH'] = ''
167
self.assertRaises(errors.NoDiff, diff.external_diff,
168
'old', ['boo\n'], 'new', ['goo\n'],
169
StringIO(), diff_opts=['-u'])
171
os.environ['PATH'] = orig_path
157
# Make sure no 'diff' command is available
158
# XXX: Weird, using None instead of '' breaks the test -- vila 20101216
159
self.overrideEnv('PATH', '')
160
self.assertRaises(errors.NoDiff, diff.external_diff,
161
'old', ['boo\n'], 'new', ['goo\n'],
162
StringIO(), diff_opts=['-u'])
173
164
def test_internal_diff_default(self):
174
165
# Default internal diff encoding is utf8
235
226
output = StringIO.StringIO()
236
227
diff.internal_diff(u'old_\xb5', ['old_text\n'],
237
228
u'new_\xe5', ['new_text\n'], output)
238
self.failUnless(isinstance(output.getvalue(), str),
229
self.assertIsInstance(output.getvalue(), str,
239
230
'internal_diff should return bytestrings')
258
249
self.assertEqual(out.splitlines(True) + ['\n'], lines)
261
class TestShowDiffTreesHelper(tests.TestCaseWithTransport):
262
"""Has a helper for running show_diff_trees"""
264
def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
266
if working_tree is not None:
267
extra_trees = (working_tree,)
270
diff.show_diff_trees(tree1, tree2, output,
271
specific_files=specific_files,
272
extra_trees=extra_trees, old_label='old/',
274
return output.getvalue()
277
class TestDiffDates(TestShowDiffTreesHelper):
252
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
254
if working_tree is not None:
255
extra_trees = (working_tree,)
258
diff.show_diff_trees(tree1, tree2, output,
259
specific_files=specific_files,
260
extra_trees=extra_trees, old_label='old/',
262
return output.getvalue()
265
class TestDiffDates(tests.TestCaseWithTransport):
280
268
super(TestDiffDates, self).setUp()
315
303
os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
317
305
def test_diff_rev_tree_working_tree(self):
318
output = self.get_diff(self.wt.basis_tree(), self.wt)
306
output = get_diff_as_string(self.wt.basis_tree(), self.wt)
319
307
# note that the date for old/file1 is from rev 2 rather than from
320
308
# the basis revision (rev 4)
321
309
self.assertEqualDiff(output, '''\
331
319
def test_diff_rev_tree_rev_tree(self):
332
320
tree1 = self.b.repository.revision_tree('rev-2')
333
321
tree2 = self.b.repository.revision_tree('rev-3')
334
output = self.get_diff(tree1, tree2)
322
output = get_diff_as_string(tree1, tree2)
335
323
self.assertEqualDiff(output, '''\
336
324
=== modified file 'file2'
337
325
--- old/file2\t2006-04-01 00:00:00 +0000
345
333
def test_diff_add_files(self):
346
334
tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
347
335
tree2 = self.b.repository.revision_tree('rev-1')
348
output = self.get_diff(tree1, tree2)
336
output = get_diff_as_string(tree1, tree2)
349
337
# the files have the epoch time stamp for the tree in which
350
338
# they don't exist.
351
339
self.assertEqualDiff(output, '''\
366
354
def test_diff_remove_files(self):
367
355
tree1 = self.b.repository.revision_tree('rev-3')
368
356
tree2 = self.b.repository.revision_tree('rev-4')
369
output = self.get_diff(tree1, tree2)
357
output = get_diff_as_string(tree1, tree2)
370
358
# the file has the epoch time stamp for the tree in which
371
359
# it doesn't exist.
372
360
self.assertEqualDiff(output, '''\
383
371
self.wt.rename_one('file1', 'file1b')
384
372
old_tree = self.b.repository.revision_tree('rev-1')
385
373
new_tree = self.b.repository.revision_tree('rev-4')
386
out = self.get_diff(old_tree, new_tree, specific_files=['file1b'],
374
out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
387
375
working_tree=self.wt)
388
376
self.assertContainsRe(out, 'file1\t')
395
383
self.wt.rename_one('file1', 'dir1/file1')
396
384
old_tree = self.b.repository.revision_tree('rev-1')
397
385
new_tree = self.b.repository.revision_tree('rev-4')
398
out = self.get_diff(old_tree, new_tree, specific_files=['dir1'],
386
out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
399
387
working_tree=self.wt)
400
388
self.assertContainsRe(out, 'file1\t')
401
out = self.get_diff(old_tree, new_tree, specific_files=['dir2'],
389
out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
402
390
working_tree=self.wt)
403
391
self.assertNotContainsRe(out, 'file1\t')
407
class TestShowDiffTrees(TestShowDiffTreesHelper):
394
class TestShowDiffTrees(tests.TestCaseWithTransport):
408
395
"""Direct tests for show_diff_trees"""
410
397
def test_modified_file(self):
415
402
tree.commit('one', rev_id='rev-1')
417
404
self.build_tree_contents([('tree/file', 'new contents\n')])
418
d = self.get_diff(tree.basis_tree(), tree)
405
d = get_diff_as_string(tree.basis_tree(), tree)
419
406
self.assertContainsRe(d, "=== modified file 'file'\n")
420
407
self.assertContainsRe(d, '--- old/file\t')
421
408
self.assertContainsRe(d, '\\+\\+\\+ new/file\t')
433
420
tree.rename_one('dir', 'other')
434
421
self.build_tree_contents([('tree/other/file', 'new contents\n')])
435
d = self.get_diff(tree.basis_tree(), tree)
422
d = get_diff_as_string(tree.basis_tree(), tree)
436
423
self.assertContainsRe(d, "=== renamed directory 'dir' => 'other'\n")
437
424
self.assertContainsRe(d, "=== modified file 'other/file'\n")
438
425
# XXX: This is technically incorrect, because it used to be at another
451
438
tree.commit('one', rev_id='rev-1')
453
440
tree.rename_one('dir', 'newdir')
454
d = self.get_diff(tree.basis_tree(), tree)
441
d = get_diff_as_string(tree.basis_tree(), tree)
455
442
# Renaming a directory should be a single "you renamed this dir" even
456
443
# when there are files inside.
457
444
self.assertEqual(d, "=== renamed directory 'dir' => 'newdir'\n")
464
451
tree.commit('one', rev_id='rev-1')
466
453
tree.rename_one('file', 'newname')
467
d = self.get_diff(tree.basis_tree(), tree)
454
d = get_diff_as_string(tree.basis_tree(), tree)
468
455
self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
469
456
# We shouldn't have a --- or +++ line, because there is no content
480
467
tree.rename_one('file', 'newname')
481
468
self.build_tree_contents([('tree/newname', 'new contents\n')])
482
d = self.get_diff(tree.basis_tree(), tree)
469
d = get_diff_as_string(tree.basis_tree(), tree)
483
470
self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
484
471
self.assertContainsRe(d, '--- old/file\t')
485
472
self.assertContainsRe(d, '\\+\\+\\+ new/newname\t')
509
496
tree.rename_one('c', 'new-c')
510
497
tree.rename_one('d', 'new-d')
512
d = self.get_diff(tree.basis_tree(), tree)
499
d = get_diff_as_string(tree.basis_tree(), tree)
514
501
self.assertContainsRe(d, r"file 'a'.*\(properties changed:"
515
502
".*\+x to -x.*\)")
573
560
tree.add(['add_'+alpha], ['file-id'])
574
561
self.build_tree_contents([('tree/mod_'+alpha, 'contents_mod\n')])
576
d = self.get_diff(tree.basis_tree(), tree)
563
d = get_diff_as_string(tree.basis_tree(), tree)
577
564
self.assertContainsRe(d,
578
565
"=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
579
566
self.assertContainsRe(d, "=== added file 'add_%s'"%autf8)
1434
1421
diff_obj._prepare_files('file2-id', 'oldname2', 'newname2')
1424
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
1426
def test_encodable_filename(self):
1427
# Just checks file path for external diff tool.
1428
# We cannot change CPython's internal encoding used by os.exec*.
1430
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1432
for _, scenario in EncodingAdapter.encoding_scenarios:
1433
encoding = scenario['encoding']
1434
dirname = scenario['info']['directory']
1435
filename = scenario['info']['filename']
1437
self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1438
relpath = dirname + u'/' + filename
1439
fullpath = diffobj._safe_filename('safe', relpath)
1442
fullpath.encode(encoding).decode(encoding)
1444
self.assert_(fullpath.startswith(diffobj._root + '/safe'))
1446
def test_unencodable_filename(self):
1448
diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
1450
for _, scenario in EncodingAdapter.encoding_scenarios:
1451
encoding = scenario['encoding']
1452
dirname = scenario['info']['directory']
1453
filename = scenario['info']['filename']
1455
if encoding == 'iso-8859-1':
1456
encoding = 'iso-8859-2'
1458
encoding = 'iso-8859-1'
1460
self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1461
relpath = dirname + u'/' + filename
1462
fullpath = diffobj._safe_filename('safe', relpath)
1465
fullpath.encode(encoding).decode(encoding)
1467
self.assert_(fullpath.startswith(diffobj._root + '/safe'))
1437
1470
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1439
1472
def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1493
1526
return self.applyDeprecated(
1494
1527
deprecated_in((2, 2, 0)), diff.get_trees_and_branches_to_diff,
1495
1528
path_list, revision_specs, old_url, new_url)