/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6619.2.1 by Vincent Ladeuil
Fix test failure for recent versions of diff
1
# Copyright (C) 2005-2012, 2014, 2016, 2017 Canonical Ltd
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
12
#
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
16
1740.2.5 by Aaron Bentley
Merge from bzr.dev
17
import os
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
18
import re
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
19
import subprocess
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
20
import sys
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
21
import tempfile
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
22
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
23
from .. import (
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
24
    diff,
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
25
    errors,
26
    osutils,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
27
    patiencediff,
28
    _patiencediff_py,
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
29
    revision as _mod_revision,
30
    revisionspec,
31
    revisiontree,
32
    tests,
33
    transform,
34
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
35
from ..sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
36
    BytesIO,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
37
    unichr,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
38
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from ..tests import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
40
    features,
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
41
    EncodingAdapter,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
42
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
43
from ..tests.scenarios import load_tests_apply_scenarios
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
44
45
46
load_tests = load_tests_apply_scenarios
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
47
48
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
49
def subst_dates(string):
50
    """Replace date strings with constant values."""
51
    return re.sub(br'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
52
                  b'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
53
54
1558.15.11 by Aaron Bentley
Apply merge review suggestions
55
def udiff_lines(old, new, allow_binary=False):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
56
    output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
57
    diff.internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
58
    output.seek(0, 0)
59
    return output.readlines()
60
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
61
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
62
def external_udiff_lines(old, new, use_stringio=False):
63
    if use_stringio:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
64
        # BytesIO has no fileno, so it tests a different codepath
65
        output = BytesIO()
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
66
    else:
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
67
        output = tempfile.TemporaryFile()
1692.8.7 by James Henstridge
changes suggested by John Meinel
68
    try:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
69
        diff.external_diff('old', old, 'new', new, output, diff_opts=['-u'])
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
70
    except errors.NoDiff:
71
        raise tests.TestSkipped('external "diff" not present to test')
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
72
    output.seek(0, 0)
73
    lines = output.readlines()
74
    output.close()
75
    return lines
76
77
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
78
class StubO(object):
79
    """Simple file-like object that allows writes with any type and records."""
80
81
    def __init__(self):
82
        self.write_record = []
83
84
    def write(self, data):
85
        self.write_record.append(data)
86
87
    def check_types(self, testcase, expected_type):
88
        testcase.assertFalse(
89
            any(not isinstance(o, expected_type) for o in self.write_record),
90
            "Not all writes of type %s: %r" % (
91
                expected_type.__name__, self.write_record))
92
93
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
94
class TestDiffOptions(tests.TestCase):
95
96
    def test_unified_added(self):
97
        """Check for default style '-u' only if no other style specified
98
        in 'diff-options'.
99
        """
100
        # Verify that style defaults to unified, id est '-u' appended
101
        # to option list, in the absence of an alternative style.
102
        self.assertEqual(['-a', '-u'], diff.default_style_unified(['-a']))
103
104
105
class TestDiffOptionsScenarios(tests.TestCase):
106
107
    scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
7143.15.2 by Jelmer Vernooij
Run autopep8.
108
    style = None  # Set by load_tests_apply_scenarios from scenarios
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
109
110
    def test_unified_not_added(self):
111
        # Verify that for all valid style options, '-u' is not
112
        # appended to option list.
113
        ret_opts = diff.default_style_unified(diff_opts=["%s" % (self.style,)])
114
        self.assertEqual(["%s" % (self.style,)], ret_opts)
115
116
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
117
class TestDiff(tests.TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
118
1102 by Martin Pool
- merge test refactoring from robertc
119
    def test_add_nl(self):
120
        """diff generates a valid diff for patches that add a newline"""
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
121
        lines = udiff_lines([b'boo'], [b'boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
122
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
123
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
124
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
125
1102 by Martin Pool
- merge test refactoring from robertc
126
    def test_add_nl_2(self):
127
        """diff generates a valid diff for patches that change last line and
128
        add a newline.
129
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
130
        lines = udiff_lines([b'boo'], [b'goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
131
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
132
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
133
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
134
1102 by Martin Pool
- merge test refactoring from robertc
135
    def test_remove_nl(self):
136
        """diff generates a valid diff for patches that change last line and
137
        add a newline.
138
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
139
        lines = udiff_lines([b'boo\n'], [b'boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
140
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
141
        self.assertEqual(lines[5], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
142
        ## "expected no-nl, got %r" % lines[5]
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
143
144
    def check_patch(self, lines):
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
145
        self.assertTrue(len(lines) > 1)
7143.15.2 by Jelmer Vernooij
Run autopep8.
146
        ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
147
        self.assertTrue(lines[0].startswith(b'---'))
148
        ## 'No orig line for patch:\n%s' % "".join(lines)
149
        self.assertTrue(lines[1].startswith(b'+++'))
150
        ## 'No mod line for patch:\n%s' % "".join(lines)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
151
        self.assertTrue(len(lines) > 2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
152
        ## "No hunks for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
153
        self.assertTrue(lines[2].startswith(b'@@'))
7143.15.2 by Jelmer Vernooij
Run autopep8.
154
        ## "No hunk header for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
155
        self.assertTrue(b'@@' in lines[2][2:])
7143.15.2 by Jelmer Vernooij
Run autopep8.
156
        ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
157
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
158
    def test_binary_lines(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
159
        empty = []
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
160
        uni_lines = [1023 * b'a' + b'\x00']
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
161
        self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines, empty)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
162
        self.assertRaises(errors.BinaryFile, udiff_lines, empty, uni_lines)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
163
        udiff_lines(uni_lines, empty, allow_binary=True)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
164
        udiff_lines(empty, uni_lines, allow_binary=True)
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
165
166
    def test_external_diff(self):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
167
        lines = external_udiff_lines([b'boo\n'], [b'goo\n'])
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
168
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
169
        self.assertEqual(b'\n', lines[-1])
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
170
171
    def test_external_diff_no_fileno(self):
172
        # Make sure that we can handle not having a fileno, even
173
        # if the diff is large
7143.15.2 by Jelmer Vernooij
Run autopep8.
174
        lines = external_udiff_lines([b'boo\n'] * 10000,
175
                                     [b'goo\n'] * 10000,
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
176
                                     use_stringio=True)
177
        self.check_patch(lines)
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
178
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
179
    def test_external_diff_binary_lang_c(self):
2321.2.5 by Alexander Belchenko
external diff: no need for special code path for win32 (suggested by John Meinel)
180
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
181
            self.overrideEnv(lang, 'C')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
182
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
183
        # Older versions of diffutils say "Binary files", newer
184
        # versions just say "Files".
7143.15.2 by Jelmer Vernooij
Run autopep8.
185
        self.assertContainsRe(
186
            lines[0], b'(Binary f|F)iles old and new differ\n')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
187
        self.assertEqual(lines[1:], [b'\n'])
1899.1.4 by John Arbash Meinel
Just swallow a return code of 2
188
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
189
    def test_no_external_diff(self):
190
        """Check that NoDiff is raised when diff is not available"""
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
191
        # Make sure no 'diff' command is available
192
        # XXX: Weird, using None instead of '' breaks the test -- vila 20101216
193
        self.overrideEnv('PATH', '')
194
        self.assertRaises(errors.NoDiff, diff.external_diff,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
195
                          b'old', [b'boo\n'], b'new', [b'goo\n'],
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
196
                          BytesIO(), diff_opts=['-u'])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
197
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
198
    def test_internal_diff_default(self):
199
        # Default internal diff encoding is utf8
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
200
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
201
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
202
                           u'new_\xe5', [b'new_text\n'], output)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
203
        lines = output.getvalue().splitlines(True)
204
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
205
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
206
                          b'+++ new_\xc3\xa5\n',
207
                          b'@@ -1,1 +1,1 @@\n',
208
                          b'-old_text\n',
209
                          b'+new_text\n',
210
                          b'\n',
211
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
212
213
    def test_internal_diff_utf8(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
214
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
215
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
216
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
217
                           path_encoding='utf8')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
218
        lines = output.getvalue().splitlines(True)
219
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
220
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
221
                          b'+++ new_\xc3\xa5\n',
222
                          b'@@ -1,1 +1,1 @@\n',
223
                          b'-old_text\n',
224
                          b'+new_text\n',
225
                          b'\n',
226
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
227
228
    def test_internal_diff_iso_8859_1(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
229
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
230
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
231
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
232
                           path_encoding='iso-8859-1')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
233
        lines = output.getvalue().splitlines(True)
234
        self.check_patch(lines)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
235
        self.assertEqual([b'--- old_\xb5\n',
236
                          b'+++ new_\xe5\n',
237
                          b'@@ -1,1 +1,1 @@\n',
238
                          b'-old_text\n',
239
                          b'+new_text\n',
240
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
241
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
242
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
243
    def test_internal_diff_no_content(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
244
        output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
245
        diff.internal_diff(u'old', [], u'new', [], output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
246
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
247
248
    def test_internal_diff_no_changes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
249
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
250
        diff.internal_diff(u'old', [b'text\n', b'contents\n'],
251
                           u'new', [b'text\n', b'contents\n'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
252
                           output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
253
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
254
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
255
    def test_internal_diff_returns_bytes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
256
        output = StubO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
257
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
258
                           u'new_\xe5', [b'new_text\n'], output)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
259
        output.check_types(self, bytes)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
260
6524.5.5 by Paul Nixon
Added tests of configurable context
261
    def test_internal_diff_default_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
262
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
263
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
264
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
265
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
266
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output)
6524.5.5 by Paul Nixon
Added tests of configurable context
267
        lines = output.getvalue().splitlines(True)
268
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
269
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
270
                          b'+++ new\n',
271
                          b'@@ -3,4 +3,4 @@\n',
272
                          b' same_text\n',
273
                          b' same_text\n',
274
                          b' same_text\n',
275
                          b'-old_text\n',
276
                          b'+new_text\n',
277
                          b'\n',
278
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
279
280
    def test_internal_diff_no_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
281
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
282
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
283
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
284
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
285
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
6524.5.5 by Paul Nixon
Added tests of configurable context
286
                           context_lines=0)
287
        lines = output.getvalue().splitlines(True)
288
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
289
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
290
                          b'+++ new\n',
291
                          b'@@ -6,1 +6,1 @@\n',
292
                          b'-old_text\n',
293
                          b'+new_text\n',
294
                          b'\n',
295
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
296
297
    def test_internal_diff_more_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
298
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
299
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
300
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
301
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
302
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
6524.5.5 by Paul Nixon
Added tests of configurable context
303
                           context_lines=4)
304
        lines = output.getvalue().splitlines(True)
305
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
306
        self.assertEqual([b'--- old\n',
307
                          b'+++ new\n',
308
                          b'@@ -2,5 +2,5 @@\n',
309
                          b' same_text\n',
310
                          b' same_text\n',
311
                          b' same_text\n',
312
                          b' same_text\n',
313
                          b'-old_text\n',
314
                          b'+new_text\n',
315
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
316
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
317
318
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
319
class TestDiffFiles(tests.TestCaseInTempDir):
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
320
321
    def test_external_diff_binary(self):
322
        """The output when using external diff should use diff's i18n error"""
6792.1.2 by Jelmer Vernooij
Alternative approach.
323
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
324
            self.overrideEnv(lang, 'C')
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
325
        # Make sure external_diff doesn't fail in the current LANG
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
326
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
327
2240.1.1 by Alexander Belchenko
test_external_diff_binary: run external diff with --binary flag
328
        cmd = ['diff', '-u', '--binary', 'old', 'new']
7143.15.2 by Jelmer Vernooij
Run autopep8.
329
        with open('old', 'wb') as f:
330
            f.write(b'\x00foobar\n')
331
        with open('new', 'wb') as f:
332
            f.write(b'foo\x00bar\n')
6792.1.3 by Jelmer Vernooij
Alternative approach.
333
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
7143.15.2 by Jelmer Vernooij
Run autopep8.
334
                                stdin=subprocess.PIPE)
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
335
        out, err = pipe.communicate()
336
        # We should output whatever diff tells us, plus a trailing newline
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
337
        self.assertEqual(out.splitlines(True) + [b'\n'], lines)
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
338
339
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
340
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
341
    output = BytesIO()
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
342
    if working_tree is not None:
343
        extra_trees = (working_tree,)
344
    else:
345
        extra_trees = ()
346
    diff.show_diff_trees(tree1, tree2, output,
7143.15.2 by Jelmer Vernooij
Run autopep8.
347
                         specific_files=specific_files,
348
                         extra_trees=extra_trees, old_label='old/',
349
                         new_label='new/')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
350
    return output.getvalue()
351
352
353
class TestDiffDates(tests.TestCaseWithTransport):
1740.2.5 by Aaron Bentley
Merge from bzr.dev
354
355
    def setUp(self):
356
        super(TestDiffDates, self).setUp()
357
        self.wt = self.make_branch_and_tree('.')
358
        self.b = self.wt.branch
359
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
360
            ('file1', b'file1 contents at rev 1\n'),
361
            ('file2', b'file2 contents at rev 1\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
362
            ])
363
        self.wt.add(['file1', 'file2'])
364
        self.wt.commit(
365
            message='Revision 1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
366
            timestamp=1143849600,  # 2006-04-01 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
367
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
368
            rev_id=b'rev-1')
369
        self.build_tree_contents([('file1', b'file1 contents at rev 2\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
370
        self.wt.commit(
371
            message='Revision 2',
7143.15.2 by Jelmer Vernooij
Run autopep8.
372
            timestamp=1143936000,  # 2006-04-02 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
373
            timezone=28800,
6855.4.1 by Jelmer Vernooij
Yet more bees.
374
            rev_id=b'rev-2')
375
        self.build_tree_contents([('file2', b'file2 contents at rev 3\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
376
        self.wt.commit(
377
            message='Revision 3',
7143.15.2 by Jelmer Vernooij
Run autopep8.
378
            timestamp=1144022400,  # 2006-04-03 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
379
            timezone=-3600,
6855.4.1 by Jelmer Vernooij
Yet more bees.
380
            rev_id=b'rev-3')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
381
        self.wt.remove(['file2'])
382
        self.wt.commit(
383
            message='Revision 4',
7143.15.2 by Jelmer Vernooij
Run autopep8.
384
            timestamp=1144108800,  # 2006-04-04 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
385
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
386
            rev_id=b'rev-4')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
387
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
388
            ('file1', b'file1 contents in working tree\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
389
            ])
390
        # set the date stamps for files in the working tree to known values
7143.15.2 by Jelmer Vernooij
Run autopep8.
391
        os.utime('file1', (1144195200, 1144195200))  # 2006-04-05 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
392
393
    def test_diff_rev_tree_working_tree(self):
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
394
        output = get_diff_as_string(self.wt.basis_tree(), self.wt)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
395
        # note that the date for old/file1 is from rev 2 rather than from
396
        # the basis revision (rev 4)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
397
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
398
=== modified file 'file1'
399
--- old/file1\t2006-04-02 00:00:00 +0000
400
+++ new/file1\t2006-04-05 00:00:00 +0000
401
@@ -1,1 +1,1 @@
402
-file1 contents at rev 2
403
+file1 contents in working tree
404
405
''')
406
407
    def test_diff_rev_tree_rev_tree(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
408
        tree1 = self.b.repository.revision_tree(b'rev-2')
409
        tree2 = self.b.repository.revision_tree(b'rev-3')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
410
        output = get_diff_as_string(tree1, tree2)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
411
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
412
=== modified file 'file2'
413
--- old/file2\t2006-04-01 00:00:00 +0000
414
+++ new/file2\t2006-04-03 00:00:00 +0000
415
@@ -1,1 +1,1 @@
416
-file2 contents at rev 1
417
+file2 contents at rev 3
418
419
''')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
420
1740.2.5 by Aaron Bentley
Merge from bzr.dev
421
    def test_diff_add_files(self):
3668.5.1 by Jelmer Vernooij
Use NULL_REVISION rather than None for Repository.revision_tree().
422
        tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
6973.5.2 by Jelmer Vernooij
Add more bees.
423
        tree2 = self.b.repository.revision_tree(b'rev-1')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
424
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
425
        # the files have the epoch time stamp for the tree in which
426
        # they don't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
427
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
428
=== added file 'file1'
429
--- old/file1\t1970-01-01 00:00:00 +0000
430
+++ new/file1\t2006-04-01 00:00:00 +0000
431
@@ -0,0 +1,1 @@
432
+file1 contents at rev 1
433
434
=== added file 'file2'
435
--- old/file2\t1970-01-01 00:00:00 +0000
436
+++ new/file2\t2006-04-01 00:00:00 +0000
437
@@ -0,0 +1,1 @@
438
+file2 contents at rev 1
439
440
''')
441
442
    def test_diff_remove_files(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
443
        tree1 = self.b.repository.revision_tree(b'rev-3')
444
        tree2 = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
445
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
446
        # the file has the epoch time stamp for the tree in which
447
        # it doesn't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
448
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
449
=== removed file 'file2'
450
--- old/file2\t2006-04-03 00:00:00 +0000
451
+++ new/file2\t1970-01-01 00:00:00 +0000
452
@@ -1,1 +0,0 @@
453
-file2 contents at rev 3
454
455
''')
456
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
457
    def test_show_diff_specified(self):
1551.7.22 by Aaron Bentley
Changes from review
458
        """A working tree filename can be used to identify a file"""
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
459
        self.wt.rename_one('file1', 'file1b')
6973.5.2 by Jelmer Vernooij
Add more bees.
460
        old_tree = self.b.repository.revision_tree(b'rev-1')
461
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
462
        out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
463
                                 working_tree=self.wt)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
464
        self.assertContainsRe(out, b'file1\t')
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
465
1551.7.22 by Aaron Bentley
Changes from review
466
    def test_recursive_diff(self):
467
        """Children of directories are matched"""
468
        os.mkdir('dir1')
469
        os.mkdir('dir2')
470
        self.wt.add(['dir1', 'dir2'])
471
        self.wt.rename_one('file1', 'dir1/file1')
6973.5.2 by Jelmer Vernooij
Add more bees.
472
        old_tree = self.b.repository.revision_tree(b'rev-1')
473
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
474
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
475
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
476
        self.assertContainsRe(out, b'file1\t')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
477
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
478
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
479
        self.assertNotContainsRe(out, b'file1\t')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
480
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
481
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
482
class TestShowDiffTrees(tests.TestCaseWithTransport):
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
483
    """Direct tests for show_diff_trees"""
484
485
    def test_modified_file(self):
486
        """Test when a file is modified."""
487
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
488
        self.build_tree_contents([('tree/file', b'contents\n')])
489
        tree.add(['file'], [b'file-id'])
490
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
491
6855.4.1 by Jelmer Vernooij
Yet more bees.
492
        self.build_tree_contents([('tree/file', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
493
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
494
        self.assertContainsRe(d, b"=== modified file 'file'\n")
495
        self.assertContainsRe(d, b'--- old/file\t')
496
        self.assertContainsRe(d, b'\\+\\+\\+ new/file\t')
497
        self.assertContainsRe(d, b'-contents\n'
498
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
499
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
500
    def test_modified_file_in_renamed_dir(self):
501
        """Test when a file is modified in a renamed directory."""
502
        tree = self.make_branch_and_tree('tree')
503
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
504
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
505
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
506
        tree.commit('one', rev_id=b'rev-1')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
507
508
        tree.rename_one('dir', 'other')
6855.4.1 by Jelmer Vernooij
Yet more bees.
509
        self.build_tree_contents([('tree/other/file', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
510
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
511
        self.assertContainsRe(d, b"=== renamed directory 'dir' => 'other'\n")
512
        self.assertContainsRe(d, b"=== modified file 'other/file'\n")
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
513
        # XXX: This is technically incorrect, because it used to be at another
514
        # location. What to do?
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
515
        self.assertContainsRe(d, b'--- old/dir/file\t')
516
        self.assertContainsRe(d, b'\\+\\+\\+ new/other/file\t')
517
        self.assertContainsRe(d, b'-contents\n'
518
                                 b'\\+new contents\n')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
519
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
520
    def test_renamed_directory(self):
521
        """Test when only a directory is only renamed."""
522
        tree = self.make_branch_and_tree('tree')
523
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
524
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
525
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
526
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
527
528
        tree.rename_one('dir', 'newdir')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
529
        d = get_diff_as_string(tree.basis_tree(), tree)
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
530
        # Renaming a directory should be a single "you renamed this dir" even
531
        # when there are files inside.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
532
        self.assertEqual(d, b"=== renamed directory 'dir' => 'newdir'\n")
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
533
534
    def test_renamed_file(self):
535
        """Test when a file is only renamed."""
536
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
537
        self.build_tree_contents([('tree/file', b'contents\n')])
538
        tree.add(['file'], [b'file-id'])
539
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
540
541
        tree.rename_one('file', 'newname')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
542
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
543
        self.assertContainsRe(d, b"=== renamed file 'file' => 'newname'\n")
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
544
        # We shouldn't have a --- or +++ line, because there is no content
545
        # change
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
546
        self.assertNotContainsRe(d, b'---')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
547
548
    def test_renamed_and_modified_file(self):
549
        """Test when a file is only renamed."""
550
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
551
        self.build_tree_contents([('tree/file', b'contents\n')])
552
        tree.add(['file'], [b'file-id'])
553
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
554
555
        tree.rename_one('file', 'newname')
6855.4.1 by Jelmer Vernooij
Yet more bees.
556
        self.build_tree_contents([('tree/newname', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
557
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
558
        self.assertContainsRe(d, b"=== renamed file 'file' => 'newname'\n")
559
        self.assertContainsRe(d, b'--- old/file\t')
560
        self.assertContainsRe(d, b'\\+\\+\\+ new/newname\t')
561
        self.assertContainsRe(d, b'-contents\n'
562
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
563
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
564
    def test_internal_diff_exec_property(self):
565
        tree = self.make_branch_and_tree('tree')
566
567
        tt = transform.TreeTransform(tree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
568
        tt.new_file('a', tt.root, [b'contents\n'], b'a-id', True)
569
        tt.new_file('b', tt.root, [b'contents\n'], b'b-id', False)
570
        tt.new_file('c', tt.root, [b'contents\n'], b'c-id', True)
571
        tt.new_file('d', tt.root, [b'contents\n'], b'd-id', False)
572
        tt.new_file('e', tt.root, [b'contents\n'], b'control-e-id', True)
573
        tt.new_file('f', tt.root, [b'contents\n'], b'control-f-id', False)
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
574
        tt.apply()
6855.4.1 by Jelmer Vernooij
Yet more bees.
575
        tree.commit('one', rev_id=b'rev-1')
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
576
577
        tt = transform.TreeTransform(tree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
578
        tt.set_executability(False, tt.trans_id_file_id(b'a-id'))
579
        tt.set_executability(True, tt.trans_id_file_id(b'b-id'))
580
        tt.set_executability(False, tt.trans_id_file_id(b'c-id'))
581
        tt.set_executability(True, tt.trans_id_file_id(b'd-id'))
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
582
        tt.apply()
583
        tree.rename_one('c', 'new-c')
584
        tree.rename_one('d', 'new-d')
585
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
586
        d = get_diff_as_string(tree.basis_tree(), tree)
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
587
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
588
        self.assertContainsRe(d, br"file 'a'.*\(properties changed:"
589
                                 br".*\+x to -x.*\)")
590
        self.assertContainsRe(d, br"file 'b'.*\(properties changed:"
591
                                 br".*-x to \+x.*\)")
592
        self.assertContainsRe(d, br"file 'c'.*\(properties changed:"
593
                                 br".*\+x to -x.*\)")
594
        self.assertContainsRe(d, br"file 'd'.*\(properties changed:"
595
                                 br".*-x to \+x.*\)")
596
        self.assertNotContainsRe(d, br"file 'e'")
597
        self.assertNotContainsRe(d, br"file 'f'")
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
598
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
599
    def test_binary_unicode_filenames(self):
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
600
        """Test that contents of files are *not* encoded in UTF-8 when there
601
        is a binary file in the diff.
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
602
        """
603
        # See https://bugs.launchpad.net/bugs/110092.
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
604
        self.requireFeature(features.UnicodeFilenameFeature)
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
605
606
        tree = self.make_branch_and_tree('tree')
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
607
        alpha, omega = u'\u03b1', u'\u03c9'
608
        alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
609
        self.build_tree_contents(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
610
            [('tree/' + alpha, b'\0'),
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
611
             ('tree/' + omega,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
612
              (b'The %s and the %s\n' % (alpha_utf8, omega_utf8)))])
6855.4.1 by Jelmer Vernooij
Yet more bees.
613
        tree.add([alpha], [b'file-id'])
614
        tree.add([omega], [b'file-id-2'])
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
615
        diff_content = StubO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
616
        diff.show_diff_trees(tree.basis_tree(), tree, diff_content)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
617
        diff_content.check_types(self, bytes)
618
        d = b''.join(diff_content.write_record)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
619
        self.assertContainsRe(d, br"=== added file '%s'" % alpha_utf8)
620
        self.assertContainsRe(d, b"Binary files a/%s.*and b/%s.* differ\n"
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
621
                              % (alpha_utf8, alpha_utf8))
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
622
        self.assertContainsRe(d, br"=== added file '%s'" % omega_utf8)
623
        self.assertContainsRe(d, br"--- a/%s" % (omega_utf8,))
624
        self.assertContainsRe(d, br"\+\+\+ b/%s" % (omega_utf8,))
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
625
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
626
    def test_unicode_filename(self):
627
        """Test when the filename are unicode."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
628
        self.requireFeature(features.UnicodeFilenameFeature)
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
629
630
        alpha, omega = u'\u03b1', u'\u03c9'
631
        autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
632
633
        tree = self.make_branch_and_tree('tree')
7143.15.2 by Jelmer Vernooij
Run autopep8.
634
        self.build_tree_contents([('tree/ren_' + alpha, b'contents\n')])
635
        tree.add(['ren_' + alpha], [b'file-id-2'])
636
        self.build_tree_contents([('tree/del_' + alpha, b'contents\n')])
637
        tree.add(['del_' + alpha], [b'file-id-3'])
638
        self.build_tree_contents([('tree/mod_' + alpha, b'contents\n')])
639
        tree.add(['mod_' + alpha], [b'file-id-4'])
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
640
6855.4.1 by Jelmer Vernooij
Yet more bees.
641
        tree.commit('one', rev_id=b'rev-1')
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
642
7143.15.2 by Jelmer Vernooij
Run autopep8.
643
        tree.rename_one('ren_' + alpha, 'ren_' + omega)
644
        tree.remove('del_' + alpha)
645
        self.build_tree_contents([('tree/add_' + alpha, b'contents\n')])
646
        tree.add(['add_' + alpha], [b'file-id'])
647
        self.build_tree_contents([('tree/mod_' + alpha, b'contents_mod\n')])
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
648
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
649
        d = get_diff_as_string(tree.basis_tree(), tree)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
650
        self.assertContainsRe(d,
7143.15.2 by Jelmer Vernooij
Run autopep8.
651
                              b"=== renamed file 'ren_%s' => 'ren_%s'\n" % (autf8, outf8))
652
        self.assertContainsRe(d, b"=== added file 'add_%s'" % autf8)
653
        self.assertContainsRe(d, b"=== modified file 'mod_%s'" % autf8)
654
        self.assertContainsRe(d, b"=== removed file 'del_%s'" % autf8)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
655
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
656
    def test_unicode_filename_path_encoding(self):
657
        """Test for bug #382699: unicode filenames on Windows should be shown
658
        in user encoding.
659
        """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
660
        self.requireFeature(features.UnicodeFilenameFeature)
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
661
        # The word 'test' in Russian
662
        _russian_test = u'\u0422\u0435\u0441\u0442'
663
        directory = _russian_test + u'/'
664
        test_txt = _russian_test + u'.txt'
665
        u1234 = u'\u1234.txt'
666
667
        tree = self.make_branch_and_tree('.')
668
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
669
            (test_txt, b'foo\n'),
670
            (u1234, b'foo\n'),
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
671
            (directory, None),
672
            ])
673
        tree.add([test_txt, u1234, directory])
674
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
675
        sio = BytesIO()
5258.1.1 by Alexander Belchenko
merge diff header work from my 2.1 branch
676
        diff.show_diff_trees(tree.basis_tree(), tree, sio,
7143.15.2 by Jelmer Vernooij
Run autopep8.
677
                             path_encoding='cp1251')
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
678
679
        output = subst_dates(sio.getvalue())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
680
        shouldbe = (b'''\
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
681
=== added directory '%(directory)s'
682
=== added file '%(test_txt)s'
683
--- a/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
684
+++ b/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
685
@@ -0,0 +1,1 @@
686
+foo
687
688
=== added file '?.txt'
689
--- a/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
690
+++ b/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
691
@@ -0,0 +1,1 @@
692
+foo
693
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
694
''' % {b'directory': _russian_test.encode('cp1251'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
695
            b'test_txt': test_txt.encode('cp1251'),
696
       })
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
697
        self.assertEqualDiff(output, shouldbe)
698
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
699
700
class DiffWasIs(diff.DiffPath):
3009.2.15 by Aaron Bentley
Test differ registration
701
702
    def diff(self, file_id, old_path, new_path, old_kind, new_kind):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
703
        self.to_file.write(b'was: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
704
        self.to_file.write(self.old_tree.get_file(old_path).read())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
705
        self.to_file.write(b'is: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
706
        self.to_file.write(self.new_tree.get_file(new_path).read())
3009.2.15 by Aaron Bentley
Test differ registration
707
708
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
709
class TestDiffTree(tests.TestCaseWithTransport):
3009.2.9 by Aaron Bentley
Add tests for Differ
710
711
    def setUp(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
712
        super(TestDiffTree, self).setUp()
3009.2.9 by Aaron Bentley
Add tests for Differ
713
        self.old_tree = self.make_branch_and_tree('old-tree')
714
        self.old_tree.lock_write()
715
        self.addCleanup(self.old_tree.unlock)
716
        self.new_tree = self.make_branch_and_tree('new-tree')
717
        self.new_tree.lock_write()
718
        self.addCleanup(self.new_tree.unlock)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
719
        self.differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.9 by Aaron Bentley
Add tests for Differ
720
721
    def test_diff_text(self):
722
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
723
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
724
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
725
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
726
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
727
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
728
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
729
        self.new_tree.add('newdir/newfile', b'file-id')
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
730
        differ = diff.DiffText(self.old_tree, self.new_tree, BytesIO())
6809.4.9 by Jelmer Vernooij
Fix some more tests.
731
        differ.diff_text('olddir/oldfile', None, 'old label',
6855.4.1 by Jelmer Vernooij
Yet more bees.
732
                         'new label', b'file-id', None)
3009.2.9 by Aaron Bentley
Add tests for Differ
733
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
734
            b'--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
735
            differ.to_file.getvalue())
736
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
737
        differ.diff_text(None, 'newdir/newfile',
6855.4.1 by Jelmer Vernooij
Yet more bees.
738
                         'old label', 'new label', None, b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
739
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
740
            b'--- old label\n+++ new label\n@@ -0,0 +1,1 @@\n+new\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
741
            differ.to_file.getvalue())
742
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
743
        differ.diff_text('olddir/oldfile', 'newdir/newfile',
6855.4.1 by Jelmer Vernooij
Yet more bees.
744
                         'old label', 'new label', b'file-id', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
745
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
746
            b'--- old label\n+++ new label\n@@ -1,1 +1,1 @@\n-old\n+new\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
747
            differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
748
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
749
    def test_diff_deletion(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
750
        self.build_tree_contents([('old-tree/file', b'contents'),
751
                                  ('new-tree/file', b'contents')])
752
        self.old_tree.add('file', b'file-id')
753
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
754
        os.unlink('new-tree/file')
755
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
756
        self.assertContainsRe(self.differ.to_file.getvalue(), b'-contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
757
758
    def test_diff_creation(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
759
        self.build_tree_contents([('old-tree/file', b'contents'),
760
                                  ('new-tree/file', b'contents')])
761
        self.old_tree.add('file', b'file-id')
762
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
763
        os.unlink('old-tree/file')
764
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
765
        self.assertContainsRe(self.differ.to_file.getvalue(), br'\+contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
766
3009.2.9 by Aaron Bentley
Add tests for Differ
767
    def test_diff_symlink(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
768
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
769
        differ.diff_symlink('old target', None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
770
        self.assertEqual(b"=== target was 'old target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
771
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
772
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
773
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
774
        differ.diff_symlink(None, 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
775
        self.assertEqual(b"=== target is 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
776
                         differ.to_file.getvalue())
777
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
778
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
779
        differ.diff_symlink('old target', 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
780
        self.assertEqual(b"=== target changed 'old target' => 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
781
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
782
783
    def test_diff(self):
784
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
785
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
786
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
787
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
788
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
789
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
790
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
791
        self.new_tree.add('newdir/newfile', b'file-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
792
        self.differ.diff(b'file-id', 'olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
793
        self.assertContainsRe(
794
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
795
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
796
            br' \@\@\n-old\n\+new\n\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
797
798
    def test_diff_kind_change(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
799
        self.requireFeature(features.SymlinkFeature)
3009.2.9 by Aaron Bentley
Add tests for Differ
800
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
801
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
802
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
803
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
804
        self.build_tree(['new-tree/newdir/'])
805
        os.symlink('new', 'new-tree/newdir/newfile')
806
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
807
        self.new_tree.add('newdir/newfile', b'file-id')
6973.13.2 by Jelmer Vernooij
Fix some more tests.
808
        self.differ.diff(b'file-id', 'olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
809
        self.assertContainsRe(
810
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
811
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+0,0'
812
            br' \@\@\n-old\n\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
813
        self.assertContainsRe(self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
814
                              b"=== target is 'new'\n")
3009.2.9 by Aaron Bentley
Add tests for Differ
815
3009.2.19 by Aaron Bentley
Implement directory diffing
816
    def test_diff_directory(self):
817
        self.build_tree(['new-tree/new-dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
818
        self.new_tree.add('new-dir', b'new-dir-id')
819
        self.differ.diff(b'new-dir-id', None, 'new-dir')
6973.12.3 by Jelmer Vernooij
Fixes.
820
        self.assertEqual(self.differ.to_file.getvalue(), b'')
3009.2.19 by Aaron Bentley
Implement directory diffing
821
3009.2.16 by Aaron Bentley
Test support for extra differs
822
    def create_old_new(self):
823
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
824
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
825
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
826
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
827
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
828
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
829
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
830
        self.new_tree.add('newdir/newfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
831
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
832
    def test_register_diff(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
833
        self.create_old_new()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
834
        old_diff_factories = diff.DiffTree.diff_factories
7143.15.2 by Jelmer Vernooij
Run autopep8.
835
        diff.DiffTree.diff_factories = old_diff_factories[:]
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
836
        diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
3009.2.16 by Aaron Bentley
Test support for extra differs
837
        try:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
838
            differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.16 by Aaron Bentley
Test support for extra differs
839
        finally:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
840
            diff.DiffTree.diff_factories = old_diff_factories
6973.13.2 by Jelmer Vernooij
Fix some more tests.
841
        differ.diff(b'file-id', 'olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
842
        self.assertNotContainsRe(
843
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
844
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
845
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
846
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
847
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
848
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
849
    def test_extra_factories(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
850
        self.create_old_new()
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
851
        differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO(),
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
852
                               extra_factories=[DiffWasIs.from_diff_tree])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
853
        differ.diff(b'file-id', 'olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
854
        self.assertNotContainsRe(
855
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
856
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
857
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
858
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
859
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
860
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
861
    def test_alphabetical_order(self):
862
        self.build_tree(['new-tree/a-file'])
863
        self.new_tree.add('a-file')
864
        self.build_tree(['old-tree/b-file'])
865
        self.old_tree.add('b-file')
866
        self.differ.show_diff(None)
867
        self.assertContainsRe(self.differ.to_file.getvalue(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
868
                              b'.*a-file(.|\n)*b-file')
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
869
3009.2.9 by Aaron Bentley
Add tests for Differ
870
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
871
class TestPatienceDiffLib(tests.TestCase):
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
872
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
873
    def setUp(self):
874
        super(TestPatienceDiffLib, self).setUp()
5168.1.3 by Vincent Ladeuil
Even more import fixes.
875
        self._unique_lcs = _patiencediff_py.unique_lcs_py
876
        self._recurse_matches = _patiencediff_py.recurse_matches_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
877
        self._PatienceSequenceMatcher = \
5168.1.3 by Vincent Ladeuil
Even more import fixes.
878
            _patiencediff_py.PatienceSequenceMatcher_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
879
3628.1.3 by Lukáš Lalinský
Add a test
880
    def test_diff_unicode_string(self):
881
        a = ''.join([unichr(i) for i in range(4000, 4500, 3)])
882
        b = ''.join([unichr(i) for i in range(4300, 4800, 2)])
883
        sm = self._PatienceSequenceMatcher(None, a, b)
884
        mb = sm.get_matching_blocks()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
885
        self.assertEqual(35, len(mb))
3628.1.3 by Lukáš Lalinský
Add a test
886
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
887
    def test_unique_lcs(self):
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
888
        unique_lcs = self._unique_lcs
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
889
        self.assertEqual(unique_lcs('', ''), [])
890
        self.assertEqual(unique_lcs('', 'a'), [])
891
        self.assertEqual(unique_lcs('a', ''), [])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
892
        self.assertEqual(unique_lcs('a', 'a'), [(0, 0)])
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
893
        self.assertEqual(unique_lcs('a', 'b'), [])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
894
        self.assertEqual(unique_lcs('ab', 'ab'), [(0, 0), (1, 1)])
7143.15.2 by Jelmer Vernooij
Run autopep8.
895
        self.assertEqual(unique_lcs('abcde', 'cdeab'),
896
                         [(2, 0), (3, 1), (4, 2)])
897
        self.assertEqual(unique_lcs('cdeab', 'abcde'),
898
                         [(0, 2), (1, 3), (2, 4)])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
899
        self.assertEqual(unique_lcs('abXde', 'abYde'), [(0, 0), (1, 1),
7143.15.2 by Jelmer Vernooij
Run autopep8.
900
                                                        (3, 3), (4, 4)])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
901
        self.assertEqual(unique_lcs('acbac', 'abc'), [(2, 1)])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
902
903
    def test_recurse_matches(self):
904
        def test_one(a, b, matches):
905
            test_matches = []
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
906
            self._recurse_matches(
907
                a, b, 0, 0, len(a), len(b), test_matches, 10)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
908
            self.assertEqual(test_matches, matches)
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
909
1711.2.17 by John Arbash Meinel
Small cleanups to patience_diff code.
910
        test_one(['a', '', 'b', '', 'c'], ['a', 'a', 'b', 'c', 'c'],
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
911
                 [(0, 0), (2, 2), (4, 4)])
912
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
913
                 [(0, 0), (2, 1), (4, 2)])
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
914
        # Even though 'bc' is not unique globally, and is surrounded by
915
        # non-matching lines, we should still match, because they are locally
916
        # unique
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
917
        test_one('abcdbce', 'afbcgdbce', [(0, 0), (1, 2), (2, 3), (3, 5),
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
918
                                          (4, 6), (5, 7), (6, 8)])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
919
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
920
        # recurse_matches doesn't match non-unique
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
921
        # lines surrounded by bogus text.
1185.81.24 by Aaron Bentley
Reoganize patience-related code
922
        # The update has been done in patiencediff.SequenceMatcher instead
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
923
924
        # This is what it could be
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
925
        #test_one('aBccDe', 'abccde', [(0,0), (2,2), (3,3), (5,5)])
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
926
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
927
        # This is what it currently gives:
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
928
        test_one('aBccDe', 'abccde', [(0, 0), (5, 5)])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
929
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
930
    def assertDiffBlocks(self, a, b, expected_blocks):
931
        """Check that the sequence matcher returns the correct blocks.
932
933
        :param a: A sequence to match
934
        :param b: Another sequence to match
935
        :param expected_blocks: The expected output, not including the final
936
            matching block (len(a), len(b), 0)
937
        """
938
        matcher = self._PatienceSequenceMatcher(None, a, b)
939
        blocks = matcher.get_matching_blocks()
940
        last = blocks.pop()
941
        self.assertEqual((len(a), len(b), 0), last)
942
        self.assertEqual(expected_blocks, blocks)
943
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
944
    def test_matching_blocks(self):
1185.81.2 by John Arbash Meinel
A couple small tests.
945
        # Some basic matching tests
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
946
        self.assertDiffBlocks('', '', [])
947
        self.assertDiffBlocks([], [], [])
948
        self.assertDiffBlocks('abc', '', [])
949
        self.assertDiffBlocks('', 'abc', [])
950
        self.assertDiffBlocks('abcd', 'abcd', [(0, 0, 4)])
951
        self.assertDiffBlocks('abcd', 'abce', [(0, 0, 3)])
952
        self.assertDiffBlocks('eabc', 'abce', [(1, 0, 3)])
953
        self.assertDiffBlocks('eabce', 'abce', [(1, 0, 4)])
954
        self.assertDiffBlocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
955
        self.assertDiffBlocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
956
        self.assertDiffBlocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
957
        # This may check too much, but it checks to see that
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
958
        # a copied block stays attached to the previous section,
959
        # not the later one.
960
        # difflib would tend to grab the trailing longest match
961
        # which would make the diff not look right
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
962
        self.assertDiffBlocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
963
                              [(0, 0, 6), (6, 11, 10)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
964
1185.81.2 by John Arbash Meinel
A couple small tests.
965
        # make sure it supports passing in lists
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
966
        self.assertDiffBlocks(
7143.15.2 by Jelmer Vernooij
Run autopep8.
967
            ['hello there\n',
968
             'world\n',
969
             'how are you today?\n'],
970
            ['hello there\n',
971
             'how are you today?\n'],
972
            [(0, 0, 1), (2, 1, 1)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
973
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
974
        # non unique lines surrounded by non-matching lines
975
        # won't be found
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
976
        self.assertDiffBlocks('aBccDe', 'abccde', [(0, 0, 1), (5, 5, 1)])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
977
978
        # But they only need to be locally unique
7143.15.2 by Jelmer Vernooij
Run autopep8.
979
        self.assertDiffBlocks('aBcDec', 'abcdec', [
980
                              (0, 0, 1), (2, 2, 1), (4, 4, 2)])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
981
982
        # non unique blocks won't be matched
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
983
        self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0, 0, 1), (8, 8, 1)])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
984
985
        # but locally unique ones will
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
986
        self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0, 0, 1), (2, 2, 2),
7143.15.2 by Jelmer Vernooij
Run autopep8.
987
                                                           (5, 4, 1), (7, 5, 2), (10, 8, 1)])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
988
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
989
        self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7, 7, 1)])
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
990
        self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
991
        self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
992
3074.2.1 by John Arbash Meinel
Change the C PatienceDiff implementation to support arbitrary objects.
993
    def test_matching_blocks_tuples(self):
994
        # Some basic matching tests
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
995
        self.assertDiffBlocks([], [], [])
996
        self.assertDiffBlocks([('a',), ('b',), ('c,')], [], [])
997
        self.assertDiffBlocks([], [('a',), ('b',), ('c,')], [])
998
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
999
                              [('a',), ('b',), ('c,')],
1000
                              [(0, 0, 3)])
1001
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
1002
                              [('a',), ('b',), ('d,')],
1003
                              [(0, 0, 2)])
1004
        self.assertDiffBlocks([('d',), ('b',), ('c,')],
1005
                              [('a',), ('b',), ('c,')],
1006
                              [(1, 1, 2)])
1007
        self.assertDiffBlocks([('d',), ('a',), ('b',), ('c,')],
1008
                              [('a',), ('b',), ('c,')],
1009
                              [(1, 0, 3)])
1010
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
1011
                              [('a', 'b'), ('c', 'X'), ('e', 'f')],
1012
                              [(0, 0, 1), (2, 2, 1)])
1013
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
1014
                              [('a', 'b'), ('c', 'dX'), ('e', 'f')],
1015
                              [(0, 0, 1), (2, 2, 1)])
3074.2.1 by John Arbash Meinel
Change the C PatienceDiff implementation to support arbitrary objects.
1016
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
1017
    def test_opcodes(self):
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
1018
        def chk_ops(a, b, expected_codes):
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1019
            s = self._PatienceSequenceMatcher(None, a, b)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1020
            self.assertEqual(expected_codes, s.get_opcodes())
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
1021
1022
        chk_ops('', '', [])
1023
        chk_ops([], [], [])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1024
        chk_ops('abc', '', [('delete', 0, 3, 0, 0)])
1025
        chk_ops('', 'abc', [('insert', 0, 0, 0, 3)])
7143.15.2 by Jelmer Vernooij
Run autopep8.
1026
        chk_ops('abcd', 'abcd', [('equal', 0, 4, 0, 4)])
1027
        chk_ops('abcd', 'abce', [('equal', 0, 3, 0, 3),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1028
                                 ('replace', 3, 4, 3, 4)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1029
                                 ])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1030
        chk_ops('eabc', 'abce', [('delete', 0, 1, 0, 0),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1031
                                 ('equal', 1, 4, 0, 3),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1032
                                 ('insert', 4, 4, 3, 4)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1033
                                 ])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1034
        chk_ops('eabce', 'abce', [('delete', 0, 1, 0, 0),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1035
                                  ('equal', 1, 5, 0, 4)
1036
                                  ])
1037
        chk_ops('abcde', 'abXde', [('equal', 0, 2, 0, 2),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1038
                                   ('replace', 2, 3, 2, 3),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1039
                                   ('equal', 3, 5, 3, 5)
1040
                                   ])
1041
        chk_ops('abcde', 'abXYZde', [('equal', 0, 2, 0, 2),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1042
                                     ('replace', 2, 3, 2, 5),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1043
                                     ('equal', 3, 5, 5, 7)
1044
                                     ])
1045
        chk_ops('abde', 'abXYZde', [('equal', 0, 2, 0, 2),
1046
                                    ('insert', 2, 2, 2, 5),
1047
                                    ('equal', 2, 4, 5, 7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
1048
                                    ])
1049
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1050
                [('equal', 0, 6, 0, 6),
1051
                 ('insert', 6, 6, 6, 11),
1052
                 ('equal', 6, 16, 11, 21)
1053
                 ])
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
1054
        chk_ops(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1055
            ['hello there\n', 'world\n', 'how are you today?\n'],
1056
            ['hello there\n', 'how are you today?\n'],
1057
            [('equal', 0, 1, 0, 1),
1058
             ('delete', 1, 2, 1, 1),
1059
             ('equal', 2, 3, 1, 2),
1060
             ])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1061
        chk_ops('aBccDe', 'abccde',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1062
                [('equal', 0, 1, 0, 1),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1063
                 ('replace', 1, 5, 1, 5),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1064
                 ('equal', 5, 6, 5, 6),
1065
                 ])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1066
        chk_ops('aBcDec', 'abcdec',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1067
                [('equal', 0, 1, 0, 1),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1068
                 ('replace', 1, 2, 1, 2),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1069
                 ('equal', 2, 3, 2, 3),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1070
                 ('replace', 3, 4, 3, 4),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1071
                 ('equal', 4, 6, 4, 6),
1072
                 ])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1073
        chk_ops('aBcdEcdFg', 'abcdecdfg',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1074
                [('equal', 0, 1, 0, 1),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1075
                 ('replace', 1, 8, 1, 8),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1076
                 ('equal', 8, 9, 8, 9)
1077
                 ])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1078
        chk_ops('aBcdEeXcdFg', 'abcdecdfg',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1079
                [('equal', 0, 1, 0, 1),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1080
                 ('replace', 1, 2, 1, 2),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1081
                 ('equal', 2, 4, 2, 4),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1082
                 ('delete', 4, 5, 4, 4),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1083
                 ('equal', 5, 6, 4, 5),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1084
                 ('delete', 6, 7, 5, 5),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1085
                 ('equal', 7, 9, 5, 7),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1086
                 ('replace', 9, 10, 7, 8),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1087
                 ('equal', 10, 11, 8, 9)
1088
                 ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
1089
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1090
    def test_grouped_opcodes(self):
1091
        def chk_ops(a, b, expected_codes, n=3):
1092
            s = self._PatienceSequenceMatcher(None, a, b)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1093
            self.assertEqual(expected_codes, list(s.get_grouped_opcodes(n)))
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1094
1095
        chk_ops('', '', [])
1096
        chk_ops([], [], [])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1097
        chk_ops('abc', '', [[('delete', 0, 3, 0, 0)]])
1098
        chk_ops('', 'abc', [[('insert', 0, 0, 0, 3)]])
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1099
        chk_ops('abcd', 'abcd', [])
7143.15.2 by Jelmer Vernooij
Run autopep8.
1100
        chk_ops('abcd', 'abce', [[('equal', 0, 3, 0, 3),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1101
                                  ('replace', 3, 4, 3, 4)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1102
                                  ]])
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1103
        chk_ops('eabc', 'abce', [[('delete', 0, 1, 0, 0),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1104
                                  ('equal', 1, 4, 0, 3),
1105
                                  ('insert', 4, 4, 3, 4)
1106
                                  ]])
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1107
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1108
                [[('equal', 3, 6, 3, 6),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1109
                  ('insert', 6, 6, 6, 11),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1110
                  ('equal', 6, 9, 11, 14)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1111
                  ]])
1112
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1113
                [[('equal', 2, 6, 2, 6),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1114
                  ('insert', 6, 6, 6, 11),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1115
                  ('equal', 6, 10, 11, 15)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1116
                  ]], 4)
1117
        chk_ops('Xabcdef', 'abcdef',
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1118
                [[('delete', 0, 1, 0, 0),
7143.15.2 by Jelmer Vernooij
Run autopep8.
1119
                  ('equal', 1, 4, 0, 3)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1120
                  ]])
1121
        chk_ops('abcdef', 'abcdefX',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1122
                [[('equal', 3, 6, 3, 6),
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1123
                  ('insert', 6, 6, 6, 7)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1124
                  ]])
1125
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
1126
    def test_multiple_ranges(self):
1127
        # There was an earlier bug where we used a bad set of ranges,
1128
        # this triggers that specific bug, to make sure it doesn't regress
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
1129
        self.assertDiffBlocks('abcdefghijklmnop',
1130
                              'abcXghiYZQRSTUVWXYZijklmnop',
1131
                              [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
1132
1133
        self.assertDiffBlocks('ABCd efghIjk  L',
1134
                              'AxyzBCn mo pqrstuvwI1 2  L',
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
1135
                              [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
1136
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
1137
        # These are rot13 code snippets.
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
1138
        self.assertDiffBlocks('''\
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
1139
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
1140
    """
1141
    gnxrf_netf = ['svyr*']
1142
    gnxrf_bcgvbaf = ['ab-erphefr']
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1143
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
1144
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr):
1145
        sebz omeyvo.nqq vzcbeg fzneg_nqq, nqq_ercbegre_cevag, nqq_ercbegre_ahyy
1146
        vs vf_dhvrg():
1147
            ercbegre = nqq_ercbegre_ahyy
1148
        ryfr:
1149
            ercbegre = nqq_ercbegre_cevag
1150
        fzneg_nqq(svyr_yvfg, abg ab_erphefr, ercbegre)
1151
1152
1153
pynff pzq_zxqve(Pbzznaq):
1154
'''.splitlines(True), '''\
1155
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
1156
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1157
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
1158
    nqq gurz.
1159
    """
1160
    gnxrf_netf = ['svyr*']
1161
    gnxrf_bcgvbaf = ['ab-erphefr', 'qel-eha']
1162
1163
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr, qel_eha=Snyfr):
1164
        vzcbeg omeyvo.nqq
1165
1166
        vs qel_eha:
1167
            vs vf_dhvrg():
1168
                # Guvf vf cbvagyrff, ohg V'q engure abg envfr na reebe
1169
                npgvba = omeyvo.nqq.nqq_npgvba_ahyy
1170
            ryfr:
1171
  npgvba = omeyvo.nqq.nqq_npgvba_cevag
1172
        ryvs vf_dhvrg():
1173
            npgvba = omeyvo.nqq.nqq_npgvba_nqq
1174
        ryfr:
1175
       npgvba = omeyvo.nqq.nqq_npgvba_nqq_naq_cevag
1176
1177
        omeyvo.nqq.fzneg_nqq(svyr_yvfg, abg ab_erphefr, npgvba)
1178
1179
1180
pynff pzq_zxqve(Pbzznaq):
7143.15.2 by Jelmer Vernooij
Run autopep8.
1181
'''.splitlines(True), [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
1182
1711.2.9 by John Arbash Meinel
Rename cdv => patience
1183
    def test_patience_unified_diff(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
1184
        txt_a = ['hello there\n',
1185
                 'world\n',
1186
                 'how are you today?\n']
1187
        txt_b = ['hello there\n',
1188
                 'how are you today?\n']
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1189
        unified_diff = patiencediff.unified_diff
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1190
        psm = self._PatienceSequenceMatcher
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1191
        self.assertEqual(['--- \n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1192
                          '+++ \n',
1193
                          '@@ -1,3 +1,2 @@\n',
1194
                          ' hello there\n',
1195
                          '-world\n',
1196
                          ' how are you today?\n'
1197
                          ], list(unified_diff(txt_a, txt_b,
1198
                                               sequencematcher=psm)))
1199
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
1200
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1201
        # This is the result with LongestCommonSubstring matching
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1202
        self.assertEqual(['--- \n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1203
                          '+++ \n',
1204
                          '@@ -1,6 +1,11 @@\n',
1205
                          ' a\n',
1206
                          ' b\n',
1207
                          ' c\n',
1208
                          '+d\n',
1209
                          '+e\n',
1210
                          '+f\n',
1211
                          '+x\n',
1212
                          '+y\n',
1213
                          ' d\n',
1214
                          ' e\n',
1215
                          ' f\n'], list(unified_diff(txt_a, txt_b)))
1711.2.9 by John Arbash Meinel
Rename cdv => patience
1216
        # And the patience diff
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1217
        self.assertEqual(['--- \n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1218
                          '+++ \n',
1219
                          '@@ -4,6 +4,11 @@\n',
1220
                          ' d\n',
1221
                          ' e\n',
1222
                          ' f\n',
1223
                          '+x\n',
1224
                          '+y\n',
1225
                          '+d\n',
1226
                          '+e\n',
1227
                          '+f\n',
1228
                          ' g\n',
1229
                          ' h\n',
1230
                          ' i\n',
1231
                          ], list(unified_diff(txt_a, txt_b,
1232
                                               sequencematcher=psm)))
1185.81.25 by Aaron Bentley
Clean up test_diff
1233
3922.1.2 by John Arbash Meinel
Update the test cases for the new patience diff code.
1234
    def test_patience_unified_diff_with_dates(self):
1235
        txt_a = ['hello there\n',
1236
                 'world\n',
1237
                 'how are you today?\n']
1238
        txt_b = ['hello there\n',
1239
                 'how are you today?\n']
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1240
        unified_diff = patiencediff.unified_diff
3922.1.2 by John Arbash Meinel
Update the test cases for the new patience diff code.
1241
        psm = self._PatienceSequenceMatcher
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1242
        self.assertEqual(['--- a\t2008-08-08\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1243
                          '+++ b\t2008-09-09\n',
1244
                          '@@ -1,3 +1,2 @@\n',
1245
                          ' hello there\n',
1246
                          '-world\n',
1247
                          ' how are you today?\n'
1248
                          ], list(unified_diff(txt_a, txt_b,
1249
                                               fromfile='a', tofile='b',
1250
                                               fromfiledate='2008-08-08',
1251
                                               tofiledate='2008-09-09',
1252
                                               sequencematcher=psm)))
3922.1.2 by John Arbash Meinel
Update the test cases for the new patience diff code.
1253
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1254
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1255
class TestPatienceDiffLib_c(TestPatienceDiffLib):
1256
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1257
    _test_needs_features = [features.compiled_patiencediff_feature]
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1258
1259
    def setUp(self):
1260
        super(TestPatienceDiffLib_c, self).setUp()
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1261
        from breezy import _patiencediff_c
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1262
        self._unique_lcs = _patiencediff_c.unique_lcs_c
1263
        self._recurse_matches = _patiencediff_c.recurse_matches_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1264
        self._PatienceSequenceMatcher = \
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1265
            _patiencediff_c.PatienceSequenceMatcher_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1266
3074.2.3 by John Arbash Meinel
Enable some error checking, and small amount of code cleanup.
1267
    def test_unhashable(self):
1268
        """We should get a proper exception here."""
3074.2.10 by John Arbash Meinel
Cleanup the test cases (Andrew)
1269
        # We need to be able to hash items in the sequence, lists are
1270
        # unhashable, and thus cannot be diffed
3074.2.3 by John Arbash Meinel
Enable some error checking, and small amount of code cleanup.
1271
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1272
                              None, [[]], [])
1273
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1274
                              None, ['valid', []], [])
1275
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1276
                              None, ['valid'], [[]])
1277
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1278
                              None, ['valid'], ['valid', []])
3074.2.3 by John Arbash Meinel
Enable some error checking, and small amount of code cleanup.
1279
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1280
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1281
class TestPatienceDiffLibFiles(tests.TestCaseInTempDir):
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1282
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1283
    def setUp(self):
1284
        super(TestPatienceDiffLibFiles, self).setUp()
1285
        self._PatienceSequenceMatcher = \
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1286
            _patiencediff_py.PatienceSequenceMatcher_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1287
1711.2.9 by John Arbash Meinel
Rename cdv => patience
1288
    def test_patience_unified_diff_files(self):
6973.12.3 by Jelmer Vernooij
Fixes.
1289
        txt_a = [b'hello there\n',
1290
                 b'world\n',
1291
                 b'how are you today?\n']
1292
        txt_b = [b'hello there\n',
1293
                 b'how are you today?\n']
7143.15.2 by Jelmer Vernooij
Run autopep8.
1294
        with open('a1', 'wb') as f:
1295
            f.writelines(txt_a)
1296
        with open('b1', 'wb') as f:
1297
            f.writelines(txt_b)
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1298
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1299
        unified_diff_files = patiencediff.unified_diff_files
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1300
        psm = self._PatienceSequenceMatcher
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
1301
        self.assertEqual([b'--- a1\n',
1302
                          b'+++ b1\n',
1303
                          b'@@ -1,3 +1,2 @@\n',
1304
                          b' hello there\n',
1305
                          b'-world\n',
1306
                          b' how are you today?\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1307
                          ], list(unified_diff_files(b'a1', b'b1',
1308
                                                     sequencematcher=psm)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1309
7143.15.2 by Jelmer Vernooij
Run autopep8.
1310
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
1311
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
1312
        with open('a2', 'wt') as f:
1313
            f.writelines(txt_a)
1314
        with open('b2', 'wt') as f:
1315
            f.writelines(txt_b)
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1316
1317
        # This is the result with LongestCommonSubstring matching
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
1318
        self.assertEqual([b'--- a2\n',
1319
                          b'+++ b2\n',
1320
                          b'@@ -1,6 +1,11 @@\n',
1321
                          b' a\n',
1322
                          b' b\n',
1323
                          b' c\n',
1324
                          b'+d\n',
1325
                          b'+e\n',
1326
                          b'+f\n',
1327
                          b'+x\n',
1328
                          b'+y\n',
1329
                          b' d\n',
1330
                          b' e\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
1331
                          b' f\n'], list(unified_diff_files(b'a2', b'b2')))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
1332
1711.2.9 by John Arbash Meinel
Rename cdv => patience
1333
        # And the patience diff
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
1334
        self.assertEqual([b'--- a2\n',
1335
                          b'+++ b2\n',
1336
                          b'@@ -4,6 +4,11 @@\n',
1337
                          b' d\n',
1338
                          b' e\n',
1339
                          b' f\n',
1340
                          b'+x\n',
1341
                          b'+y\n',
1342
                          b'+d\n',
1343
                          b'+e\n',
1344
                          b'+f\n',
1345
                          b' g\n',
1346
                          b' h\n',
1347
                          b' i\n'],
1348
                         list(unified_diff_files(b'a2', b'b2',
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1349
                                                 sequencematcher=psm)))
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1350
1351
1352
class TestPatienceDiffLibFiles_c(TestPatienceDiffLibFiles):
1353
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1354
    _test_needs_features = [features.compiled_patiencediff_feature]
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1355
1356
    def setUp(self):
1357
        super(TestPatienceDiffLibFiles_c, self).setUp()
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1358
        from breezy import _patiencediff_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1359
        self._PatienceSequenceMatcher = \
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1360
            _patiencediff_c.PatienceSequenceMatcher_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1361
1362
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1363
class TestUsingCompiledIfAvailable(tests.TestCase):
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1364
1365
    def test_PatienceSequenceMatcher(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1366
        if features.compiled_patiencediff_feature.available():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1367
            from breezy._patiencediff_c import PatienceSequenceMatcher_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1368
            self.assertIs(PatienceSequenceMatcher_c,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1369
                          patiencediff.PatienceSequenceMatcher)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1370
        else:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1371
            from breezy._patiencediff_py import PatienceSequenceMatcher_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1372
            self.assertIs(PatienceSequenceMatcher_py,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1373
                          patiencediff.PatienceSequenceMatcher)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1374
1375
    def test_unique_lcs(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1376
        if features.compiled_patiencediff_feature.available():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1377
            from breezy._patiencediff_c import unique_lcs_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1378
            self.assertIs(unique_lcs_c,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1379
                          patiencediff.unique_lcs)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1380
        else:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1381
            from breezy._patiencediff_py import unique_lcs_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1382
            self.assertIs(unique_lcs_py,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1383
                          patiencediff.unique_lcs)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1384
1385
    def test_recurse_matches(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1386
        if features.compiled_patiencediff_feature.available():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1387
            from breezy._patiencediff_c import recurse_matches_c
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1388
            self.assertIs(recurse_matches_c,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1389
                          patiencediff.recurse_matches)
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1390
        else:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1391
            from breezy._patiencediff_py import recurse_matches_py
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
1392
            self.assertIs(recurse_matches_py,
5168.1.3 by Vincent Ladeuil
Even more import fixes.
1393
                          patiencediff.recurse_matches)
3123.6.2 by Aaron Bentley
Implement diff --using natively
1394
1395
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1396
class TestDiffFromTool(tests.TestCaseWithTransport):
3123.6.2 by Aaron Bentley
Implement diff --using natively
1397
1398
    def test_from_string(self):
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1399
        diff_obj = diff.DiffFromTool.from_string('diff', None, None, None)
3123.6.2 by Aaron Bentley
Implement diff --using natively
1400
        self.addCleanup(diff_obj.finish)
4603.1.20 by Aaron Bentley
Use string.Template substitution with @ as delimiter.
1401
        self.assertEqual(['diff', '@old_path', '@new_path'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
1402
                         diff_obj.command_template)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
1403
1404
    def test_from_string_u5(self):
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1405
        diff_obj = diff.DiffFromTool.from_string('diff "-u 5"',
1406
                                                 None, None, None)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
1407
        self.addCleanup(diff_obj.finish)
4603.1.20 by Aaron Bentley
Use string.Template substitution with @ as delimiter.
1408
        self.assertEqual(['diff', '-u 5', '@old_path', '@new_path'],
3123.6.2 by Aaron Bentley
Implement diff --using natively
1409
                         diff_obj.command_template)
1410
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
1411
                         diff_obj._get_command('old-path', 'new-path'))
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1412
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
1413
    def test_from_string_path_with_backslashes(self):
5241.2.2 by Robert Collins
Missed one test.
1414
        self.requireFeature(features.backslashdir_feature)
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
1415
        tool = 'C:\\Tools\\Diff.exe'
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1416
        diff_obj = diff.DiffFromTool.from_string(tool, None, None, None)
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
1417
        self.addCleanup(diff_obj.finish)
1418
        self.assertEqual(['C:\\Tools\\Diff.exe', '@old_path', '@new_path'],
1419
                         diff_obj.command_template)
1420
        self.assertEqual(['C:\\Tools\\Diff.exe', 'old-path', 'new-path'],
1421
                         diff_obj._get_command('old-path', 'new-path'))
3123.6.2 by Aaron Bentley
Implement diff --using natively
1422
1423
    def test_execute(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1424
        output = BytesIO()
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
1425
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7019.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.TestDiffFromTool.test_execute when default python is python3.
1426
                                      'print("@old_path @new_path")'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1427
                                     None, None, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
1428
        self.addCleanup(diff_obj.finish)
1429
        diff_obj._execute('old', 'new')
6973.12.3 by Jelmer Vernooij
Fixes.
1430
        self.assertEqual(output.getvalue().rstrip(), b'old new')
3123.6.2 by Aaron Bentley
Implement diff --using natively
1431
6597.2.1 by Richard Wilbur
Split diff format option parser into a separate function, update to include all format options for GNU diff v3.2, and test parser.
1432
    def test_execute_missing(self):
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1433
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
1434
                                     None, None, None)
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
1435
        self.addCleanup(diff_obj.finish)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1436
        e = self.assertRaises(errors.ExecutableMissing, diff_obj._execute,
1437
                              'old', 'new')
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
1438
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
1439
                         ' on this machine', str(e))
1440
3287.18.22 by Matt McClure
Reverts to prior decomposition of exercise and verification, as suggested
1441
    def test_prepare_files_creates_paths_readable_by_windows_tool(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1442
        self.requireFeature(features.AttribFeature)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1443
        output = BytesIO()
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
1444
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1445
        self.build_tree_contents([('tree/file', b'content')])
1446
        tree.add('file', b'file-id')
3287.18.11 by Matt McClure
Removed unnecessary timestamp parameter.
1447
        tree.commit('old tree')
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
1448
        tree.lock_read()
1449
        self.addCleanup(tree.unlock)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
1450
        basis_tree = tree.basis_tree()
1451
        basis_tree.lock_read()
1452
        self.addCleanup(basis_tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
1453
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1454
                                      'print "@old_path @new_path"'],
1455
                                     basis_tree, tree, output)
6855.4.1 by Jelmer Vernooij
Yet more bees.
1456
        diff_obj._prepare_files('file', 'file', file_id=b'file-id')
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
1457
        # The old content should be readonly
1458
        self.assertReadableByAttrib(diff_obj._root, 'old\\file',
1459
                                    r'R.*old\\file$')
1460
        # The new content should use the tree object, not a 'new' file anymore
1461
        self.assertEndsWith(tree.basedir, 'work/tree')
1462
        self.assertReadableByAttrib(tree.basedir, 'file', r'work\\tree\\file$')
3287.18.22 by Matt McClure
Reverts to prior decomposition of exercise and verification, as suggested
1463
1464
    def assertReadableByAttrib(self, cwd, relpath, regex):
1465
        proc = subprocess.Popen(['attrib', relpath],
1466
                                stdout=subprocess.PIPE,
1467
                                cwd=cwd)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
1468
        (result, err) = proc.communicate()
1469
        self.assertContainsRe(result.replace('\r\n', '\n'), regex)
3287.18.9 by Matt McClure
Adds a test asserting that a Windows tool that understands forward slashes
1470
3123.6.2 by Aaron Bentley
Implement diff --using natively
1471
    def test_prepare_files(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
1472
        output = BytesIO()
3123.6.2 by Aaron Bentley
Implement diff --using natively
1473
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1474
        self.build_tree_contents([('tree/oldname', b'oldcontent')])
1475
        self.build_tree_contents([('tree/oldname2', b'oldcontent2')])
1476
        tree.add('oldname', b'file-id')
1477
        tree.add('oldname2', b'file2-id')
5151.3.1 by Martin
Fix os.utime test failures, three on FAT filesystems and one with readonly files
1478
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
1479
        tree.commit('old tree', timestamp=315532800)
3123.6.5 by Aaron Bentley
Symlink to real files if possible
1480
        tree.rename_one('oldname', 'newname')
3287.18.23 by Matt McClure
Adds comments that document my understanding of
1481
        tree.rename_one('oldname2', 'newname2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1482
        self.build_tree_contents([('tree/newname', b'newcontent')])
1483
        self.build_tree_contents([('tree/newname2', b'newcontent2')])
3123.6.2 by Aaron Bentley
Implement diff --using natively
1484
        old_tree = tree.basis_tree()
1485
        old_tree.lock_read()
1486
        self.addCleanup(old_tree.unlock)
3123.6.4 by Aaron Bentley
Set mtime (and atime) on files for --using
1487
        tree.lock_read()
1488
        self.addCleanup(tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
1489
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1490
                                      'print "@old_path @new_path"'],
1491
                                     old_tree, tree, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
1492
        self.addCleanup(diff_obj.finish)
6681.2.10 by Jelmer Vernooij
Fix failures.
1493
        self.assertContainsRe(diff_obj._root, 'brz-diff-[^/]*')
6809.4.15 by Jelmer Vernooij
Fix some more tests.
1494
        old_path, new_path = diff_obj._prepare_files(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1495
            'oldname', 'newname', file_id=b'file-id')
3123.6.2 by Aaron Bentley
Implement diff --using natively
1496
        self.assertContainsRe(old_path, 'old/oldname$')
5151.3.1 by Martin
Fix os.utime test failures, three on FAT filesystems and one with readonly files
1497
        self.assertEqual(315532800, os.stat(old_path).st_mtime)
4845.2.1 by Gary van der Merwe
When launching an external diff app, don't write temporary files for a working tree.
1498
        self.assertContainsRe(new_path, 'tree/newname$')
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1499
        self.assertFileEqual(b'oldcontent', old_path)
1500
        self.assertFileEqual(b'newcontent', new_path)
3287.18.14 by Matt McClure
Extracted a host_os_dereferences_symlinks method.
1501
        if osutils.host_os_dereferences_symlinks():
3123.6.5 by Aaron Bentley
Symlink to real files if possible
1502
            self.assertTrue(os.path.samefile('tree/newname', new_path))
3123.6.2 by Aaron Bentley
Implement diff --using natively
1503
        # make sure we can create files with the same parent directories
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
1504
        diff_obj._prepare_files('oldname2', 'newname2', file_id=b'file2-id')
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1505
1506
5074.5.4 by INADA Naoki
fix easy bug.
1507
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
5074.5.2 by INADA Naoki
Add test for encoded filenames
1508
1509
    def test_encodable_filename(self):
5074.5.9 by INADA Naoki
Make additional comments to clarify
1510
        # Just checks file path for external diff tool.
1511
        # We cannot change CPython's internal encoding used by os.exec*.
1512
        diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1513
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
1514
        for _, scenario in EncodingAdapter.encoding_scenarios:
1515
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1516
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
1517
            filename = scenario['info']['filename']
5074.5.6 by INADA Naoki
Change directry name for each check.
1518
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
1519
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1520
            relpath = dirname + u'/' + filename
1521
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1522
            self.assertEqual(fullpath,
1523
                             fullpath.encode(encoding).decode(encoding))
1524
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1525
1526
    def test_unencodable_filename(self):
5074.5.9 by INADA Naoki
Make additional comments to clarify
1527
        diffobj = diff.DiffFromTool(['dummy', '@old_path', '@new_path'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1528
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
1529
        for _, scenario in EncodingAdapter.encoding_scenarios:
1530
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1531
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
1532
            filename = scenario['info']['filename']
1533
1534
            if encoding == 'iso-8859-1':
1535
                encoding = 'iso-8859-2'
1536
            else:
1537
                encoding = 'iso-8859-1'
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1538
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
1539
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1540
            relpath = dirname + u'/' + filename
1541
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1542
            self.assertEqual(fullpath,
1543
                             fullpath.encode(encoding).decode(encoding))
1544
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1545
1546
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1547
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
5147.3.7 by Andrew Bennetts
Expect DeprecationWarnings for get_trees_and_branches_to_diff in test_diff, and add corresponding test coverage for get_trees_and_branches_to_diff_locked.
1548
1549
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
6027.1.4 by Vincent Ladeuil
Remove ``diff.get_trees_and_branches_to_diff`` deprecated in 2.2.0 and the corrsponding tests.
1550
        """Call get_trees_and_branches_to_diff_locked."""
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1551
        return diff.get_trees_and_branches_to_diff_locked(
5147.3.7 by Andrew Bennetts
Expect DeprecationWarnings for get_trees_and_branches_to_diff in test_diff, and add corresponding test coverage for get_trees_and_branches_to_diff_locked.
1552
            path_list, revision_specs, old_url, new_url, self.addCleanup)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1553
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1554
    def test_basic(self):
1555
        tree = self.make_branch_and_tree('tree')
1556
        (old_tree, new_tree,
1557
         old_branch, new_branch,
5147.3.7 by Andrew Bennetts
Expect DeprecationWarnings for get_trees_and_branches_to_diff in test_diff, and add corresponding test coverage for get_trees_and_branches_to_diff_locked.
1558
         specific_files, extra_trees) = self.call_gtabtd(
1559
             ['tree'], None, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1560
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1561
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1562
        self.assertEqual(_mod_revision.NULL_REVISION,
1563
                         old_tree.get_revision_id())
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1564
        self.assertEqual(tree.basedir, new_tree.basedir)
1565
        self.assertEqual(tree.branch.base, old_branch.base)
1566
        self.assertEqual(tree.branch.base, new_branch.base)
1567
        self.assertIs(None, specific_files)
1568
        self.assertIs(None, extra_trees)
1569
1570
    def test_with_rev_specs(self):
1571
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1572
        self.build_tree_contents([('tree/file', b'oldcontent')])
1573
        tree.add('file', b'file-id')
1574
        tree.commit('old tree', timestamp=0, rev_id=b"old-id")
1575
        self.build_tree_contents([('tree/file', b'newcontent')])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1576
        tree.commit('new tree', timestamp=0, rev_id=b"new-id")
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1577
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1578
        revisions = [revisionspec.RevisionSpec.from_string('1'),
1579
                     revisionspec.RevisionSpec.from_string('2')]
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1580
        (old_tree, new_tree,
1581
         old_branch, new_branch,
5147.3.7 by Andrew Bennetts
Expect DeprecationWarnings for get_trees_and_branches_to_diff in test_diff, and add corresponding test coverage for get_trees_and_branches_to_diff_locked.
1582
         specific_files, extra_trees) = self.call_gtabtd(
1583
            ['tree'], revisions, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1584
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1585
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1586
        self.assertEqual(b"old-id", old_tree.get_revision_id())
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1587
        self.assertIsInstance(new_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1588
        self.assertEqual(b"new-id", new_tree.get_revision_id())
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1589
        self.assertEqual(tree.branch.base, old_branch.base)
1590
        self.assertEqual(tree.branch.base, new_branch.base)
1591
        self.assertIs(None, specific_files)
4705.1.4 by Gary van der Merwe
Add newline to end of test_diff.py
1592
        self.assertEqual(tree.basedir, extra_trees[0].basedir)