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