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