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