15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
from cStringIO import StringIO
34
from breezy.tests import (
33
from ..sixish import (
38
from breezy.tests.blackbox.test_diff import subst_dates
39
from breezy.tests.scenarios import load_tests_apply_scenarios
40
from ..tests.blackbox.test_diff import subst_dates
41
from ..tests.scenarios import load_tests_apply_scenarios
42
44
load_tests = load_tests_apply_scenarios
45
47
def udiff_lines(old, new, allow_binary=False):
47
49
diff.internal_diff('old', old, 'new', new, output, allow_binary)
49
51
return output.readlines()
52
54
def external_udiff_lines(old, new, use_stringio=False):
54
# StringIO has no fileno, so it tests a different codepath
56
# BytesIO has no fileno, so it tests a different codepath
57
59
output = tempfile.TemporaryFile()
71
"""Simple file-like object that allows writes with any type and records."""
74
self.write_record = []
76
def write(self, data):
77
self.write_record.append(data)
79
def check_types(self, testcase, expected_type):
81
any(not isinstance(o, expected_type) for o in self.write_record),
82
"Not all writes of type %s: %r" % (
83
expected_type.__name__, self.write_record))
68
86
class TestDiffOptions(tests.TestCase):
70
88
def test_unified_added(self):
166
184
self.overrideEnv('PATH', '')
167
185
self.assertRaises(errors.NoDiff, diff.external_diff,
168
186
'old', ['boo\n'], 'new', ['goo\n'],
169
StringIO(), diff_opts=['-u'])
187
BytesIO(), diff_opts=['-u'])
171
189
def test_internal_diff_default(self):
172
190
# Default internal diff encoding is utf8
174
192
diff.internal_diff(u'old_\xb5', ['old_text\n'],
175
193
u'new_\xe5', ['new_text\n'], output)
176
194
lines = output.getvalue().splitlines(True)
187
205
def test_internal_diff_utf8(self):
189
207
diff.internal_diff(u'old_\xb5', ['old_text\n'],
190
208
u'new_\xe5', ['new_text\n'], output,
191
209
path_encoding='utf8')
203
221
def test_internal_diff_iso_8859_1(self):
205
223
diff.internal_diff(u'old_\xb5', ['old_text\n'],
206
224
u'new_\xe5', ['new_text\n'], output,
207
225
path_encoding='iso-8859-1')
219
237
def test_internal_diff_no_content(self):
221
239
diff.internal_diff(u'old', [], u'new', [], output)
222
240
self.assertEqual('', output.getvalue())
224
242
def test_internal_diff_no_changes(self):
226
244
diff.internal_diff(u'old', ['text\n', 'contents\n'],
227
245
u'new', ['text\n', 'contents\n'],
229
247
self.assertEqual('', output.getvalue())
231
249
def test_internal_diff_returns_bytes(self):
233
output = StringIO.StringIO()
234
251
diff.internal_diff(u'old_\xb5', ['old_text\n'],
235
252
u'new_\xe5', ['new_text\n'], output)
236
self.assertIsInstance(output.getvalue(), str,
237
'internal_diff should return bytestrings')
253
output.check_types(self, bytes)
239
255
def test_internal_diff_default_context(self):
241
257
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
242
258
'same_text\n','same_text\n','old_text\n'],
243
259
'new', ['same_text\n','same_text\n','same_text\n',
259
275
def test_internal_diff_no_context(self):
261
277
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
262
278
'same_text\n','same_text\n','old_text\n'],
263
279
'new', ['same_text\n','same_text\n','same_text\n',
277
293
def test_internal_diff_more_context(self):
279
295
diff.internal_diff('old', ['same_text\n','same_text\n','same_text\n',
280
296
'same_text\n','same_text\n','old_text\n'],
281
297
'new', ['same_text\n','same_text\n','same_text\n',
320
336
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
322
338
if working_tree is not None:
323
339
extra_trees = (working_tree,)
584
600
# See https://bugs.launchpad.net/bugs/110092.
585
601
self.requireFeature(features.UnicodeFilenameFeature)
587
# This bug isn't triggered with cStringIO.
588
from StringIO import StringIO
589
603
tree = self.make_branch_and_tree('tree')
590
604
alpha, omega = u'\u03b1', u'\u03c9'
591
605
alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
595
609
('The %s and the %s\n' % (alpha_utf8, omega_utf8)))])
596
610
tree.add([alpha], ['file-id'])
597
611
tree.add([omega], ['file-id-2'])
598
diff_content = StringIO()
612
diff_content = StubO()
599
613
diff.show_diff_trees(tree.basis_tree(), tree, diff_content)
600
d = diff_content.getvalue()
614
diff_content.check_types(self, bytes)
615
d = b''.join(diff_content.write_record)
601
616
self.assertContainsRe(d, r"=== added file '%s'" % alpha_utf8)
602
617
self.assertContainsRe(d, "Binary files a/%s.*and b/%s.* differ\n"
603
618
% (alpha_utf8, alpha_utf8))
699
714
self.new_tree = self.make_branch_and_tree('new-tree')
700
715
self.new_tree.lock_write()
701
716
self.addCleanup(self.new_tree.unlock)
702
self.differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
717
self.differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
704
719
def test_diff_text(self):
705
720
self.build_tree_contents([('old-tree/olddir/',),
710
725
('new-tree/newdir/newfile', 'new\n')])
711
726
self.new_tree.add('newdir')
712
727
self.new_tree.add('newdir/newfile', 'file-id')
713
differ = diff.DiffText(self.old_tree, self.new_tree, StringIO())
728
differ = diff.DiffText(self.old_tree, self.new_tree, BytesIO())
714
729
differ.diff_text('file-id', None, 'old label', 'new label')
715
730
self.assertEqual(
716
731
'--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
745
760
self.assertContainsRe(self.differ.to_file.getvalue(), '\+contents')
747
762
def test_diff_symlink(self):
748
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
763
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
749
764
differ.diff_symlink('old target', None)
750
765
self.assertEqual("=== target was 'old target'\n",
751
766
differ.to_file.getvalue())
753
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
768
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
754
769
differ.diff_symlink(None, 'new target')
755
770
self.assertEqual("=== target is 'new target'\n",
756
771
differ.to_file.getvalue())
758
differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
773
differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
759
774
differ.diff_symlink('old target', 'new target')
760
775
self.assertEqual("=== target changed 'old target' => 'new target'\n",
761
776
differ.to_file.getvalue())
815
830
diff.DiffTree.diff_factories=old_diff_factories[:]
816
831
diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
818
differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
833
differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
820
835
diff.DiffTree.diff_factories = old_diff_factories
821
836
differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
829
844
def test_extra_factories(self):
830
845
self.create_old_new()
831
differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO(),
846
differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO(),
832
847
extra_factories=[DiffWasIs.from_diff_tree])
833
848
differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
834
849
self.assertNotContainsRe(
1405
1420
diff_obj._get_command('old-path', 'new-path'))
1407
1422
def test_execute(self):
1409
1424
diff_obj = diff.DiffFromTool(['python', '-c',
1410
1425
'print "@old_path @new_path"'],
1411
1426
None, None, output)
1425
1440
def test_prepare_files_creates_paths_readable_by_windows_tool(self):
1426
1441
self.requireFeature(features.AttribFeature)
1428
1443
tree = self.make_branch_and_tree('tree')
1429
1444
self.build_tree_contents([('tree/file', 'content')])
1430
1445
tree.add('file', 'file-id')
1453
1468
self.assertContainsRe(result.replace('\r\n', '\n'), regex)
1455
1470
def test_prepare_files(self):
1457
1472
tree = self.make_branch_and_tree('tree')
1458
1473
self.build_tree_contents([('tree/oldname', 'oldcontent')])
1459
1474
self.build_tree_contents([('tree/oldname2', 'oldcontent2')])