/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
7479.2.1 by Jelmer Vernooij
Drop python2 support.
17
import contextlib
18
from io import BytesIO
1740.2.5 by Aaron Bentley
Merge from bzr.dev
19
import os
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
20
import re
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
21
import subprocess
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
22
import sys
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
23
import tempfile
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
24
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
25
from .. import (
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
26
    diff,
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
27
    errors,
28
    osutils,
29
    revision as _mod_revision,
30
    revisionspec,
31
    revisiontree,
32
    tests,
33
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
34
from ..tests import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
35
    features,
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
36
    EncodingAdapter,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
37
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
38
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.
39
40
41
load_tests = load_tests_apply_scenarios
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
42
43
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
44
def subst_dates(string):
45
    """Replace date strings with constant values."""
46
    return re.sub(br'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
47
                  b'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
48
49
1558.15.11 by Aaron Bentley
Apply merge review suggestions
50
def udiff_lines(old, new, allow_binary=False):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
51
    output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
52
    diff.internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
53
    output.seek(0, 0)
54
    return output.readlines()
55
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
56
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
57
def external_udiff_lines(old, new, use_stringio=False):
58
    if use_stringio:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
59
        # BytesIO has no fileno, so it tests a different codepath
60
        output = BytesIO()
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
61
    else:
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
62
        output = tempfile.TemporaryFile()
1692.8.7 by James Henstridge
changes suggested by John Meinel
63
    try:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
64
        diff.external_diff('old', old, 'new', new, output, diff_opts=['-u'])
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
65
    except errors.NoDiff:
66
        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
67
    output.seek(0, 0)
68
    lines = output.readlines()
69
    output.close()
70
    return lines
71
72
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
73
class StubO(object):
74
    """Simple file-like object that allows writes with any type and records."""
75
76
    def __init__(self):
77
        self.write_record = []
78
79
    def write(self, data):
80
        self.write_record.append(data)
81
82
    def check_types(self, testcase, expected_type):
83
        testcase.assertFalse(
84
            any(not isinstance(o, expected_type) for o in self.write_record),
85
            "Not all writes of type %s: %r" % (
86
                expected_type.__name__, self.write_record))
87
88
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
89
class TestDiffOptions(tests.TestCase):
90
91
    def test_unified_added(self):
92
        """Check for default style '-u' only if no other style specified
93
        in 'diff-options'.
94
        """
95
        # Verify that style defaults to unified, id est '-u' appended
96
        # to option list, in the absence of an alternative style.
97
        self.assertEqual(['-a', '-u'], diff.default_style_unified(['-a']))
98
99
100
class TestDiffOptionsScenarios(tests.TestCase):
101
102
    scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
7143.15.2 by Jelmer Vernooij
Run autopep8.
103
    style = None  # Set by load_tests_apply_scenarios from scenarios
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
104
105
    def test_unified_not_added(self):
106
        # Verify that for all valid style options, '-u' is not
107
        # appended to option list.
108
        ret_opts = diff.default_style_unified(diff_opts=["%s" % (self.style,)])
109
        self.assertEqual(["%s" % (self.style,)], ret_opts)
110
111
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
112
class TestDiff(tests.TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
113
1102 by Martin Pool
- merge test refactoring from robertc
114
    def test_add_nl(self):
115
        """diff generates a valid diff for patches that add a newline"""
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
116
        lines = udiff_lines([b'boo'], [b'boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
117
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
118
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
119
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
120
1102 by Martin Pool
- merge test refactoring from robertc
121
    def test_add_nl_2(self):
122
        """diff generates a valid diff for patches that change last line and
123
        add a newline.
124
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
125
        lines = udiff_lines([b'boo'], [b'goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
126
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
127
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
128
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
129
1102 by Martin Pool
- merge test refactoring from robertc
130
    def test_remove_nl(self):
131
        """diff generates a valid diff for patches that change last line and
132
        add a newline.
133
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
134
        lines = udiff_lines([b'boo\n'], [b'boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
135
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
136
        self.assertEqual(lines[5], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
137
        ## "expected no-nl, got %r" % lines[5]
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
138
139
    def check_patch(self, lines):
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
140
        self.assertTrue(len(lines) > 1)
7143.15.2 by Jelmer Vernooij
Run autopep8.
141
        ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
142
        self.assertTrue(lines[0].startswith(b'---'))
143
        ## 'No orig line for patch:\n%s' % "".join(lines)
144
        self.assertTrue(lines[1].startswith(b'+++'))
145
        ## 'No mod line for patch:\n%s' % "".join(lines)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
146
        self.assertTrue(len(lines) > 2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
147
        ## "No hunks for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
148
        self.assertTrue(lines[2].startswith(b'@@'))
7143.15.2 by Jelmer Vernooij
Run autopep8.
149
        ## "No hunk header for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
150
        self.assertTrue(b'@@' in lines[2][2:])
7143.15.2 by Jelmer Vernooij
Run autopep8.
151
        ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
152
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
153
    def test_binary_lines(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
154
        empty = []
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
155
        uni_lines = [1023 * b'a' + b'\x00']
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
156
        self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines, empty)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
157
        self.assertRaises(errors.BinaryFile, udiff_lines, empty, uni_lines)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
158
        udiff_lines(uni_lines, empty, allow_binary=True)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
159
        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
160
161
    def test_external_diff(self):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
162
        lines = external_udiff_lines([b'boo\n'], [b'goo\n'])
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
163
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
164
        self.assertEqual(b'\n', lines[-1])
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
165
166
    def test_external_diff_no_fileno(self):
167
        # Make sure that we can handle not having a fileno, even
168
        # if the diff is large
7143.15.2 by Jelmer Vernooij
Run autopep8.
169
        lines = external_udiff_lines([b'boo\n'] * 10000,
170
                                     [b'goo\n'] * 10000,
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
171
                                     use_stringio=True)
172
        self.check_patch(lines)
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
173
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
174
    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)
175
        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.
176
            self.overrideEnv(lang, 'C')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
177
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
178
        # Older versions of diffutils say "Binary files", newer
179
        # versions just say "Files".
7143.15.2 by Jelmer Vernooij
Run autopep8.
180
        self.assertContainsRe(
181
            lines[0], b'(Binary f|F)iles old and new differ\n')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
182
        self.assertEqual(lines[1:], [b'\n'])
1899.1.4 by John Arbash Meinel
Just swallow a return code of 2
183
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
184
    def test_no_external_diff(self):
185
        """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.
186
        # Make sure no 'diff' command is available
187
        # XXX: Weird, using None instead of '' breaks the test -- vila 20101216
188
        self.overrideEnv('PATH', '')
189
        self.assertRaises(errors.NoDiff, diff.external_diff,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
190
                          b'old', [b'boo\n'], b'new', [b'goo\n'],
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
191
                          BytesIO(), diff_opts=['-u'])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
192
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
193
    def test_internal_diff_default(self):
194
        # Default internal diff encoding is utf8
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
195
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
196
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
197
                           u'new_\xe5', [b'new_text\n'], output)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
198
        lines = output.getvalue().splitlines(True)
199
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
200
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
201
                          b'+++ new_\xc3\xa5\n',
202
                          b'@@ -1,1 +1,1 @@\n',
203
                          b'-old_text\n',
204
                          b'+new_text\n',
205
                          b'\n',
206
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
207
208
    def test_internal_diff_utf8(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
209
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
210
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
211
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
212
                           path_encoding='utf8')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
213
        lines = output.getvalue().splitlines(True)
214
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
215
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
216
                          b'+++ new_\xc3\xa5\n',
217
                          b'@@ -1,1 +1,1 @@\n',
218
                          b'-old_text\n',
219
                          b'+new_text\n',
220
                          b'\n',
221
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
222
223
    def test_internal_diff_iso_8859_1(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
224
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
225
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
226
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
227
                           path_encoding='iso-8859-1')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
228
        lines = output.getvalue().splitlines(True)
229
        self.check_patch(lines)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
230
        self.assertEqual([b'--- old_\xb5\n',
231
                          b'+++ new_\xe5\n',
232
                          b'@@ -1,1 +1,1 @@\n',
233
                          b'-old_text\n',
234
                          b'+new_text\n',
235
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
236
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
237
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
238
    def test_internal_diff_no_content(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
239
        output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
240
        diff.internal_diff(u'old', [], u'new', [], output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
241
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
242
243
    def test_internal_diff_no_changes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
244
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
245
        diff.internal_diff(u'old', [b'text\n', b'contents\n'],
246
                           u'new', [b'text\n', b'contents\n'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
247
                           output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
248
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
249
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
250
    def test_internal_diff_returns_bytes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
251
        output = StubO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
252
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
253
                           u'new_\xe5', [b'new_text\n'], output)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
254
        output.check_types(self, bytes)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
255
6524.5.5 by Paul Nixon
Added tests of configurable context
256
    def test_internal_diff_default_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
257
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
258
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
259
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
260
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
261
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output)
6524.5.5 by Paul Nixon
Added tests of configurable context
262
        lines = output.getvalue().splitlines(True)
263
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
264
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
265
                          b'+++ new\n',
266
                          b'@@ -3,4 +3,4 @@\n',
267
                          b' same_text\n',
268
                          b' same_text\n',
269
                          b' same_text\n',
270
                          b'-old_text\n',
271
                          b'+new_text\n',
272
                          b'\n',
273
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
274
275
    def test_internal_diff_no_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
276
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
277
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
278
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
279
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
280
                                   b'same_text\n', b'same_text\n', b'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)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
284
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
285
                          b'+++ new\n',
286
                          b'@@ -6,1 +6,1 @@\n',
287
                          b'-old_text\n',
288
                          b'+new_text\n',
289
                          b'\n',
290
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
291
292
    def test_internal_diff_more_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
293
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
294
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
295
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
296
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
297
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
6524.5.5 by Paul Nixon
Added tests of configurable context
298
                           context_lines=4)
299
        lines = output.getvalue().splitlines(True)
300
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
301
        self.assertEqual([b'--- old\n',
302
                          b'+++ new\n',
303
                          b'@@ -2,5 +2,5 @@\n',
304
                          b' same_text\n',
305
                          b' same_text\n',
306
                          b' same_text\n',
307
                          b' same_text\n',
308
                          b'-old_text\n',
309
                          b'+new_text\n',
310
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
311
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
312
313
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
314
class TestDiffFiles(tests.TestCaseInTempDir):
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
315
316
    def test_external_diff_binary(self):
317
        """The output when using external diff should use diff's i18n error"""
6792.1.2 by Jelmer Vernooij
Alternative approach.
318
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
319
            self.overrideEnv(lang, 'C')
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
320
        # Make sure external_diff doesn't fail in the current LANG
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
321
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
322
2240.1.1 by Alexander Belchenko
test_external_diff_binary: run external diff with --binary flag
323
        cmd = ['diff', '-u', '--binary', 'old', 'new']
7143.15.2 by Jelmer Vernooij
Run autopep8.
324
        with open('old', 'wb') as f:
325
            f.write(b'\x00foobar\n')
326
        with open('new', 'wb') as f:
327
            f.write(b'foo\x00bar\n')
6792.1.3 by Jelmer Vernooij
Alternative approach.
328
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
7143.15.2 by Jelmer Vernooij
Run autopep8.
329
                                stdin=subprocess.PIPE)
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
330
        out, err = pipe.communicate()
331
        # We should output whatever diff tells us, plus a trailing newline
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
332
        self.assertEqual(out.splitlines(True) + [b'\n'], lines)
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
333
334
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
335
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
336
    output = BytesIO()
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
337
    if working_tree is not None:
338
        extra_trees = (working_tree,)
339
    else:
340
        extra_trees = ()
341
    diff.show_diff_trees(tree1, tree2, output,
7143.15.2 by Jelmer Vernooij
Run autopep8.
342
                         specific_files=specific_files,
343
                         extra_trees=extra_trees, old_label='old/',
344
                         new_label='new/')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
345
    return output.getvalue()
346
347
348
class TestDiffDates(tests.TestCaseWithTransport):
1740.2.5 by Aaron Bentley
Merge from bzr.dev
349
350
    def setUp(self):
351
        super(TestDiffDates, self).setUp()
352
        self.wt = self.make_branch_and_tree('.')
353
        self.b = self.wt.branch
354
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
355
            ('file1', b'file1 contents at rev 1\n'),
356
            ('file2', b'file2 contents at rev 1\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
357
            ])
358
        self.wt.add(['file1', 'file2'])
359
        self.wt.commit(
360
            message='Revision 1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
361
            timestamp=1143849600,  # 2006-04-01 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
362
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
363
            rev_id=b'rev-1')
364
        self.build_tree_contents([('file1', b'file1 contents at rev 2\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
365
        self.wt.commit(
366
            message='Revision 2',
7143.15.2 by Jelmer Vernooij
Run autopep8.
367
            timestamp=1143936000,  # 2006-04-02 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
368
            timezone=28800,
6855.4.1 by Jelmer Vernooij
Yet more bees.
369
            rev_id=b'rev-2')
370
        self.build_tree_contents([('file2', b'file2 contents at rev 3\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
371
        self.wt.commit(
372
            message='Revision 3',
7143.15.2 by Jelmer Vernooij
Run autopep8.
373
            timestamp=1144022400,  # 2006-04-03 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
374
            timezone=-3600,
6855.4.1 by Jelmer Vernooij
Yet more bees.
375
            rev_id=b'rev-3')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
376
        self.wt.remove(['file2'])
377
        self.wt.commit(
378
            message='Revision 4',
7143.15.2 by Jelmer Vernooij
Run autopep8.
379
            timestamp=1144108800,  # 2006-04-04 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
380
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
381
            rev_id=b'rev-4')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
382
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
383
            ('file1', b'file1 contents in working tree\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
384
            ])
385
        # set the date stamps for files in the working tree to known values
7143.15.2 by Jelmer Vernooij
Run autopep8.
386
        os.utime('file1', (1144195200, 1144195200))  # 2006-04-05 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
387
388
    def test_diff_rev_tree_working_tree(self):
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
389
        output = get_diff_as_string(self.wt.basis_tree(), self.wt)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
390
        # note that the date for old/file1 is from rev 2 rather than from
391
        # the basis revision (rev 4)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
392
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
393
=== modified file 'file1'
394
--- old/file1\t2006-04-02 00:00:00 +0000
395
+++ new/file1\t2006-04-05 00:00:00 +0000
396
@@ -1,1 +1,1 @@
397
-file1 contents at rev 2
398
+file1 contents in working tree
399
400
''')
401
402
    def test_diff_rev_tree_rev_tree(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
403
        tree1 = self.b.repository.revision_tree(b'rev-2')
404
        tree2 = self.b.repository.revision_tree(b'rev-3')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
405
        output = get_diff_as_string(tree1, tree2)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
406
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
407
=== modified file 'file2'
408
--- old/file2\t2006-04-01 00:00:00 +0000
409
+++ new/file2\t2006-04-03 00:00:00 +0000
410
@@ -1,1 +1,1 @@
411
-file2 contents at rev 1
412
+file2 contents at rev 3
413
414
''')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
415
1740.2.5 by Aaron Bentley
Merge from bzr.dev
416
    def test_diff_add_files(self):
3668.5.1 by Jelmer Vernooij
Use NULL_REVISION rather than None for Repository.revision_tree().
417
        tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
6973.5.2 by Jelmer Vernooij
Add more bees.
418
        tree2 = self.b.repository.revision_tree(b'rev-1')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
419
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
420
        # the files have the epoch time stamp for the tree in which
421
        # they don't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
422
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
423
=== added file 'file1'
424
--- old/file1\t1970-01-01 00:00:00 +0000
425
+++ new/file1\t2006-04-01 00:00:00 +0000
426
@@ -0,0 +1,1 @@
427
+file1 contents at rev 1
428
429
=== added file 'file2'
430
--- old/file2\t1970-01-01 00:00:00 +0000
431
+++ new/file2\t2006-04-01 00:00:00 +0000
432
@@ -0,0 +1,1 @@
433
+file2 contents at rev 1
434
435
''')
436
437
    def test_diff_remove_files(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
438
        tree1 = self.b.repository.revision_tree(b'rev-3')
439
        tree2 = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
440
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
441
        # the file has the epoch time stamp for the tree in which
442
        # it doesn't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
443
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
444
=== removed file 'file2'
445
--- old/file2\t2006-04-03 00:00:00 +0000
446
+++ new/file2\t1970-01-01 00:00:00 +0000
447
@@ -1,1 +0,0 @@
448
-file2 contents at rev 3
449
450
''')
451
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
452
    def test_show_diff_specified(self):
1551.7.22 by Aaron Bentley
Changes from review
453
        """A working tree filename can be used to identify a file"""
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
454
        self.wt.rename_one('file1', 'file1b')
6973.5.2 by Jelmer Vernooij
Add more bees.
455
        old_tree = self.b.repository.revision_tree(b'rev-1')
456
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
457
        out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
458
                                 working_tree=self.wt)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
459
        self.assertContainsRe(out, b'file1\t')
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
460
1551.7.22 by Aaron Bentley
Changes from review
461
    def test_recursive_diff(self):
462
        """Children of directories are matched"""
463
        os.mkdir('dir1')
464
        os.mkdir('dir2')
465
        self.wt.add(['dir1', 'dir2'])
466
        self.wt.rename_one('file1', 'dir1/file1')
6973.5.2 by Jelmer Vernooij
Add more bees.
467
        old_tree = self.b.repository.revision_tree(b'rev-1')
468
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
469
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
470
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
471
        self.assertContainsRe(out, b'file1\t')
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=['dir2'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
473
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
474
        self.assertNotContainsRe(out, b'file1\t')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
475
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
476
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
477
class TestShowDiffTrees(tests.TestCaseWithTransport):
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
478
    """Direct tests for show_diff_trees"""
479
480
    def test_modified_file(self):
481
        """Test when a file is modified."""
482
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
483
        self.build_tree_contents([('tree/file', b'contents\n')])
484
        tree.add(['file'], [b'file-id'])
485
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
486
6855.4.1 by Jelmer Vernooij
Yet more bees.
487
        self.build_tree_contents([('tree/file', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
488
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
489
        self.assertContainsRe(d, b"=== modified file 'file'\n")
490
        self.assertContainsRe(d, b'--- old/file\t')
491
        self.assertContainsRe(d, b'\\+\\+\\+ new/file\t')
492
        self.assertContainsRe(d, b'-contents\n'
493
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
494
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
495
    def test_modified_file_in_renamed_dir(self):
496
        """Test when a file is modified in a renamed directory."""
497
        tree = self.make_branch_and_tree('tree')
498
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
499
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
500
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
501
        tree.commit('one', rev_id=b'rev-1')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
502
503
        tree.rename_one('dir', 'other')
6855.4.1 by Jelmer Vernooij
Yet more bees.
504
        self.build_tree_contents([('tree/other/file', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
505
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
506
        self.assertContainsRe(d, b"=== renamed directory 'dir' => 'other'\n")
507
        self.assertContainsRe(d, b"=== modified file 'other/file'\n")
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
508
        # XXX: This is technically incorrect, because it used to be at another
509
        # location. What to do?
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
510
        self.assertContainsRe(d, b'--- old/dir/file\t')
511
        self.assertContainsRe(d, b'\\+\\+\\+ new/other/file\t')
512
        self.assertContainsRe(d, b'-contents\n'
513
                                 b'\\+new contents\n')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
514
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
515
    def test_renamed_directory(self):
516
        """Test when only a directory is only renamed."""
517
        tree = self.make_branch_and_tree('tree')
518
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
519
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
520
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
521
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
522
523
        tree.rename_one('dir', 'newdir')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
524
        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'
525
        # Renaming a directory should be a single "you renamed this dir" even
526
        # when there are files inside.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
527
        self.assertEqual(d, b"=== renamed directory 'dir' => 'newdir'\n")
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
528
529
    def test_renamed_file(self):
530
        """Test when a file is only renamed."""
531
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
532
        self.build_tree_contents([('tree/file', b'contents\n')])
533
        tree.add(['file'], [b'file-id'])
534
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
535
536
        tree.rename_one('file', 'newname')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
537
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
538
        self.assertContainsRe(d, b"=== renamed file 'file' => 'newname'\n")
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
539
        # We shouldn't have a --- or +++ line, because there is no content
540
        # change
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
541
        self.assertNotContainsRe(d, b'---')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
542
543
    def test_renamed_and_modified_file(self):
544
        """Test when a file is only renamed."""
545
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
546
        self.build_tree_contents([('tree/file', b'contents\n')])
547
        tree.add(['file'], [b'file-id'])
548
        tree.commit('one', rev_id=b'rev-1')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
549
550
        tree.rename_one('file', 'newname')
6855.4.1 by Jelmer Vernooij
Yet more bees.
551
        self.build_tree_contents([('tree/newname', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
552
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
553
        self.assertContainsRe(d, b"=== renamed file 'file' => 'newname'\n")
554
        self.assertContainsRe(d, b'--- old/file\t')
555
        self.assertContainsRe(d, b'\\+\\+\\+ new/newname\t')
556
        self.assertContainsRe(d, b'-contents\n'
557
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
558
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
559
    def test_internal_diff_exec_property(self):
560
        tree = self.make_branch_and_tree('tree')
561
7350.3.2 by Jelmer Vernooij
Use Tree.get_transform.
562
        tt = tree.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
563
        tt.new_file('a', tt.root, [b'contents\n'], b'a-id', True)
564
        tt.new_file('b', tt.root, [b'contents\n'], b'b-id', False)
565
        tt.new_file('c', tt.root, [b'contents\n'], b'c-id', True)
566
        tt.new_file('d', tt.root, [b'contents\n'], b'd-id', False)
567
        tt.new_file('e', tt.root, [b'contents\n'], b'control-e-id', True)
568
        tt.new_file('f', tt.root, [b'contents\n'], b'control-f-id', False)
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
569
        tt.apply()
6855.4.1 by Jelmer Vernooij
Yet more bees.
570
        tree.commit('one', rev_id=b'rev-1')
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
571
7350.3.2 by Jelmer Vernooij
Use Tree.get_transform.
572
        tt = tree.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
573
        tt.set_executability(False, tt.trans_id_file_id(b'a-id'))
574
        tt.set_executability(True, tt.trans_id_file_id(b'b-id'))
575
        tt.set_executability(False, tt.trans_id_file_id(b'c-id'))
576
        tt.set_executability(True, tt.trans_id_file_id(b'd-id'))
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
577
        tt.apply()
578
        tree.rename_one('c', 'new-c')
579
        tree.rename_one('d', 'new-d')
580
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
581
        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
582
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
583
        self.assertContainsRe(d, br"file 'a'.*\(properties changed:"
584
                                 br".*\+x to -x.*\)")
585
        self.assertContainsRe(d, br"file 'b'.*\(properties changed:"
586
                                 br".*-x to \+x.*\)")
587
        self.assertContainsRe(d, br"file 'c'.*\(properties changed:"
588
                                 br".*\+x to -x.*\)")
589
        self.assertContainsRe(d, br"file 'd'.*\(properties changed:"
590
                                 br".*-x to \+x.*\)")
591
        self.assertNotContainsRe(d, br"file 'e'")
592
        self.assertNotContainsRe(d, br"file 'f'")
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
593
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
594
    def test_binary_unicode_filenames(self):
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
595
        """Test that contents of files are *not* encoded in UTF-8 when there
596
        is a binary file in the diff.
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
597
        """
598
        # See https://bugs.launchpad.net/bugs/110092.
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
599
        self.requireFeature(features.UnicodeFilenameFeature)
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
600
601
        tree = self.make_branch_and_tree('tree')
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
602
        alpha, omega = u'\u03b1', u'\u03c9'
603
        alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
604
        self.build_tree_contents(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
605
            [('tree/' + alpha, b'\0'),
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
606
             ('tree/' + omega,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
607
              (b'The %s and the %s\n' % (alpha_utf8, omega_utf8)))])
6855.4.1 by Jelmer Vernooij
Yet more bees.
608
        tree.add([alpha], [b'file-id'])
609
        tree.add([omega], [b'file-id-2'])
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
610
        diff_content = StubO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
611
        diff.show_diff_trees(tree.basis_tree(), tree, diff_content)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
612
        diff_content.check_types(self, bytes)
613
        d = b''.join(diff_content.write_record)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
614
        self.assertContainsRe(d, br"=== added file '%s'" % alpha_utf8)
615
        self.assertContainsRe(d, b"Binary files a/%s.*and b/%s.* differ\n"
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
616
                              % (alpha_utf8, alpha_utf8))
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
617
        self.assertContainsRe(d, br"=== added file '%s'" % omega_utf8)
618
        self.assertContainsRe(d, br"--- a/%s" % (omega_utf8,))
619
        self.assertContainsRe(d, br"\+\+\+ b/%s" % (omega_utf8,))
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
620
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
621
    def test_unicode_filename(self):
622
        """Test when the filename are unicode."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
623
        self.requireFeature(features.UnicodeFilenameFeature)
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
624
625
        alpha, omega = u'\u03b1', u'\u03c9'
626
        autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
627
628
        tree = self.make_branch_and_tree('tree')
7143.15.2 by Jelmer Vernooij
Run autopep8.
629
        self.build_tree_contents([('tree/ren_' + alpha, b'contents\n')])
630
        tree.add(['ren_' + alpha], [b'file-id-2'])
631
        self.build_tree_contents([('tree/del_' + alpha, b'contents\n')])
632
        tree.add(['del_' + alpha], [b'file-id-3'])
633
        self.build_tree_contents([('tree/mod_' + alpha, b'contents\n')])
634
        tree.add(['mod_' + alpha], [b'file-id-4'])
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
635
6855.4.1 by Jelmer Vernooij
Yet more bees.
636
        tree.commit('one', rev_id=b'rev-1')
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
637
7143.15.2 by Jelmer Vernooij
Run autopep8.
638
        tree.rename_one('ren_' + alpha, 'ren_' + omega)
639
        tree.remove('del_' + alpha)
640
        self.build_tree_contents([('tree/add_' + alpha, b'contents\n')])
641
        tree.add(['add_' + alpha], [b'file-id'])
642
        self.build_tree_contents([('tree/mod_' + alpha, b'contents_mod\n')])
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
643
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
644
        d = get_diff_as_string(tree.basis_tree(), tree)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
645
        self.assertContainsRe(d,
7143.15.2 by Jelmer Vernooij
Run autopep8.
646
                              b"=== renamed file 'ren_%s' => 'ren_%s'\n" % (autf8, outf8))
647
        self.assertContainsRe(d, b"=== added file 'add_%s'" % autf8)
648
        self.assertContainsRe(d, b"=== modified file 'mod_%s'" % autf8)
649
        self.assertContainsRe(d, b"=== removed file 'del_%s'" % autf8)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
650
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
651
    def test_unicode_filename_path_encoding(self):
652
        """Test for bug #382699: unicode filenames on Windows should be shown
653
        in user encoding.
654
        """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
655
        self.requireFeature(features.UnicodeFilenameFeature)
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
656
        # The word 'test' in Russian
657
        _russian_test = u'\u0422\u0435\u0441\u0442'
658
        directory = _russian_test + u'/'
659
        test_txt = _russian_test + u'.txt'
660
        u1234 = u'\u1234.txt'
661
662
        tree = self.make_branch_and_tree('.')
663
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
664
            (test_txt, b'foo\n'),
665
            (u1234, b'foo\n'),
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
666
            (directory, None),
667
            ])
668
        tree.add([test_txt, u1234, directory])
669
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
670
        sio = BytesIO()
5258.1.1 by Alexander Belchenko
merge diff header work from my 2.1 branch
671
        diff.show_diff_trees(tree.basis_tree(), tree, sio,
7143.15.2 by Jelmer Vernooij
Run autopep8.
672
                             path_encoding='cp1251')
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
673
674
        output = subst_dates(sio.getvalue())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
675
        shouldbe = (b'''\
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
676
=== added directory '%(directory)s'
677
=== added file '%(test_txt)s'
678
--- a/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
679
+++ b/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
680
@@ -0,0 +1,1 @@
681
+foo
682
683
=== added file '?.txt'
684
--- a/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
685
+++ b/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
686
@@ -0,0 +1,1 @@
687
+foo
688
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
689
''' % {b'directory': _russian_test.encode('cp1251'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
690
            b'test_txt': test_txt.encode('cp1251'),
691
       })
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
692
        self.assertEqualDiff(output, shouldbe)
693
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
694
695
class DiffWasIs(diff.DiffPath):
3009.2.15 by Aaron Bentley
Test differ registration
696
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
697
    def diff(self, old_path, new_path, old_kind, new_kind):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
698
        self.to_file.write(b'was: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
699
        self.to_file.write(self.old_tree.get_file(old_path).read())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
700
        self.to_file.write(b'is: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
701
        self.to_file.write(self.new_tree.get_file(new_path).read())
3009.2.15 by Aaron Bentley
Test differ registration
702
703
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
704
class TestDiffTree(tests.TestCaseWithTransport):
3009.2.9 by Aaron Bentley
Add tests for Differ
705
706
    def setUp(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
707
        super(TestDiffTree, self).setUp()
3009.2.9 by Aaron Bentley
Add tests for Differ
708
        self.old_tree = self.make_branch_and_tree('old-tree')
709
        self.old_tree.lock_write()
710
        self.addCleanup(self.old_tree.unlock)
711
        self.new_tree = self.make_branch_and_tree('new-tree')
712
        self.new_tree.lock_write()
713
        self.addCleanup(self.new_tree.unlock)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
714
        self.differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.9 by Aaron Bentley
Add tests for Differ
715
716
    def test_diff_text(self):
717
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
718
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
719
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
720
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
721
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
722
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
723
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
724
        self.new_tree.add('newdir/newfile', b'file-id')
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
725
        differ = diff.DiffText(self.old_tree, self.new_tree, BytesIO())
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
726
        differ.diff_text('olddir/oldfile', None, 'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
727
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
728
            b'--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
729
            differ.to_file.getvalue())
730
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
731
        differ.diff_text(None, 'newdir/newfile',
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
732
                         'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
733
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
734
            b'--- old label\n+++ new label\n@@ -0,0 +1,1 @@\n+new\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
735
            differ.to_file.getvalue())
736
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
737
        differ.diff_text('olddir/oldfile', 'newdir/newfile',
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
738
                         'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
739
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
740
            b'--- old label\n+++ new label\n@@ -1,1 +1,1 @@\n-old\n+new\n\n',
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
741
            differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
742
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
743
    def test_diff_deletion(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
744
        self.build_tree_contents([('old-tree/file', b'contents'),
745
                                  ('new-tree/file', b'contents')])
746
        self.old_tree.add('file', b'file-id')
747
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
748
        os.unlink('new-tree/file')
749
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
750
        self.assertContainsRe(self.differ.to_file.getvalue(), b'-contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
751
752
    def test_diff_creation(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
753
        self.build_tree_contents([('old-tree/file', b'contents'),
754
                                  ('new-tree/file', b'contents')])
755
        self.old_tree.add('file', b'file-id')
756
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
757
        os.unlink('old-tree/file')
758
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
759
        self.assertContainsRe(self.differ.to_file.getvalue(), br'\+contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
760
3009.2.9 by Aaron Bentley
Add tests for Differ
761
    def test_diff_symlink(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
762
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
763
        differ.diff_symlink('old target', None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
764
        self.assertEqual(b"=== target was 'old target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
765
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
766
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(None, 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
769
        self.assertEqual(b"=== target is 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
770
                         differ.to_file.getvalue())
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('old target', 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
774
        self.assertEqual(b"=== target changed 'old target' => 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
775
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
776
777
    def test_diff(self):
778
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
779
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
780
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
781
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
782
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
783
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
784
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
785
        self.new_tree.add('newdir/newfile', b'file-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
786
        self.differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
787
        self.assertContainsRe(
788
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
789
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
790
            br' \@\@\n-old\n\+new\n\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
791
792
    def test_diff_kind_change(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
793
        self.requireFeature(features.SymlinkFeature)
3009.2.9 by Aaron Bentley
Add tests for Differ
794
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
795
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
796
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
797
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
798
        self.build_tree(['new-tree/newdir/'])
799
        os.symlink('new', 'new-tree/newdir/newfile')
800
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
801
        self.new_tree.add('newdir/newfile', b'file-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
802
        self.differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
803
        self.assertContainsRe(
804
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
805
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+0,0'
806
            br' \@\@\n-old\n\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
807
        self.assertContainsRe(self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
808
                              b"=== target is 'new'\n")
3009.2.9 by Aaron Bentley
Add tests for Differ
809
3009.2.19 by Aaron Bentley
Implement directory diffing
810
    def test_diff_directory(self):
811
        self.build_tree(['new-tree/new-dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
812
        self.new_tree.add('new-dir', b'new-dir-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
813
        self.differ.diff(None, 'new-dir')
6973.12.3 by Jelmer Vernooij
Fixes.
814
        self.assertEqual(self.differ.to_file.getvalue(), b'')
3009.2.19 by Aaron Bentley
Implement directory diffing
815
3009.2.16 by Aaron Bentley
Test support for extra differs
816
    def create_old_new(self):
817
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
818
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
819
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
820
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
821
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
822
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
823
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
824
        self.new_tree.add('newdir/newfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
825
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
826
    def test_register_diff(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
827
        self.create_old_new()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
828
        old_diff_factories = diff.DiffTree.diff_factories
7143.15.2 by Jelmer Vernooij
Run autopep8.
829
        diff.DiffTree.diff_factories = old_diff_factories[:]
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
830
        diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
3009.2.16 by Aaron Bentley
Test support for extra differs
831
        try:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
832
            differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.16 by Aaron Bentley
Test support for extra differs
833
        finally:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
834
            diff.DiffTree.diff_factories = old_diff_factories
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
835
        differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
836
        self.assertNotContainsRe(
837
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
838
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
839
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
840
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
841
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
842
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
843
    def test_extra_factories(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
844
        self.create_old_new()
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
845
        differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO(),
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
846
                               extra_factories=[DiffWasIs.from_diff_tree])
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
847
        differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
848
        self.assertNotContainsRe(
849
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
850
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
851
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
852
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
853
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
854
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
855
    def test_alphabetical_order(self):
856
        self.build_tree(['new-tree/a-file'])
857
        self.new_tree.add('a-file')
858
        self.build_tree(['old-tree/b-file'])
859
        self.old_tree.add('b-file')
860
        self.differ.show_diff(None)
861
        self.assertContainsRe(self.differ.to_file.getvalue(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
862
                              b'.*a-file(.|\n)*b-file')
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
863
3009.2.9 by Aaron Bentley
Add tests for Differ
864
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
865
class TestDiffFromTool(tests.TestCaseWithTransport):
3123.6.2 by Aaron Bentley
Implement diff --using natively
866
867
    def test_from_string(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
868
        diff_obj = diff.DiffFromTool.from_string(
869
            ['diff', '{old_path}', '{new_path}'],
870
            None, None, None)
3123.6.2 by Aaron Bentley
Implement diff --using natively
871
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
872
        self.assertEqual(['diff', '{old_path}', '{new_path}'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
873
                         diff_obj.command_template)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
874
7290.1.44 by Jelmer Vernooij
Fix diff --using when {old_path} and {new_path} are not specified in the template.
875
    def test_from_string_no_paths(self):
876
        diff_obj = diff.DiffFromTool.from_string(
877
            ['diff', "-u5"], None, None, None)
878
        self.addCleanup(diff_obj.finish)
879
        self.assertEqual(['diff', '-u5'],
880
                         diff_obj.command_template)
881
        self.assertEqual(['diff', '-u5', 'old-path', 'new-path'],
882
                         diff_obj._get_command('old-path', 'new-path'))
883
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
884
    def test_from_string_u5(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
885
        diff_obj = diff.DiffFromTool.from_string(
7358.6.3 by Jelmer Vernooij
Fix formatting.
886
            ['diff', "-u 5", '{old_path}', '{new_path}'], None, None, None)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
887
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
888
        self.assertEqual(['diff', '-u 5', '{old_path}', '{new_path}'],
3123.6.2 by Aaron Bentley
Implement diff --using natively
889
                         diff_obj.command_template)
890
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
891
                         diff_obj._get_command('old-path', 'new-path'))
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
892
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
893
    def test_from_string_path_with_backslashes(self):
5241.2.2 by Robert Collins
Missed one test.
894
        self.requireFeature(features.backslashdir_feature)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
895
        tool = ['C:\\Tools\\Diff.exe', '{old_path}', '{new_path}']
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
896
        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.
897
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
898
        self.assertEqual(['C:\\Tools\\Diff.exe', '{old_path}', '{new_path}'],
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
899
                         diff_obj.command_template)
900
        self.assertEqual(['C:\\Tools\\Diff.exe', 'old-path', 'new-path'],
901
                         diff_obj._get_command('old-path', 'new-path'))
3123.6.2 by Aaron Bentley
Implement diff --using natively
902
903
    def test_execute(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
904
        output = BytesIO()
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
905
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
906
                                      'print("{old_path} {new_path}")'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
907
                                     None, None, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
908
        self.addCleanup(diff_obj.finish)
909
        diff_obj._execute('old', 'new')
6973.12.3 by Jelmer Vernooij
Fixes.
910
        self.assertEqual(output.getvalue().rstrip(), b'old new')
3123.6.2 by Aaron Bentley
Implement diff --using natively
911
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.
912
    def test_execute_missing(self):
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
913
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
914
                                     None, None, None)
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
915
        self.addCleanup(diff_obj.finish)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
916
        e = self.assertRaises(errors.ExecutableMissing, diff_obj._execute,
917
                              'old', 'new')
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
918
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
919
                         ' on this machine', str(e))
920
3287.18.22 by Matt McClure
Reverts to prior decomposition of exercise and verification, as suggested
921
    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
922
        self.requireFeature(features.AttribFeature)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
923
        output = BytesIO()
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
924
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
925
        self.build_tree_contents([('tree/file', b'content')])
926
        tree.add('file', b'file-id')
3287.18.11 by Matt McClure
Removed unnecessary timestamp parameter.
927
        tree.commit('old tree')
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
928
        tree.lock_read()
929
        self.addCleanup(tree.unlock)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
930
        basis_tree = tree.basis_tree()
931
        basis_tree.lock_read()
932
        self.addCleanup(basis_tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
933
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
934
                                      'print "{old_path} {new_path}"'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
935
                                     basis_tree, tree, output)
6855.4.1 by Jelmer Vernooij
Yet more bees.
936
        diff_obj._prepare_files('file', 'file', file_id=b'file-id')
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
937
        # The old content should be readonly
938
        self.assertReadableByAttrib(diff_obj._root, 'old\\file',
939
                                    r'R.*old\\file$')
940
        # The new content should use the tree object, not a 'new' file anymore
941
        self.assertEndsWith(tree.basedir, 'work/tree')
942
        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
943
944
    def assertReadableByAttrib(self, cwd, relpath, regex):
945
        proc = subprocess.Popen(['attrib', relpath],
946
                                stdout=subprocess.PIPE,
947
                                cwd=cwd)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
948
        (result, err) = proc.communicate()
949
        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
950
3123.6.2 by Aaron Bentley
Implement diff --using natively
951
    def test_prepare_files(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
952
        output = BytesIO()
3123.6.2 by Aaron Bentley
Implement diff --using natively
953
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
954
        self.build_tree_contents([('tree/oldname', b'oldcontent')])
955
        self.build_tree_contents([('tree/oldname2', b'oldcontent2')])
956
        tree.add('oldname', b'file-id')
957
        tree.add('oldname2', b'file2-id')
5151.3.1 by Martin
Fix os.utime test failures, three on FAT filesystems and one with readonly files
958
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
959
        tree.commit('old tree', timestamp=315532800)
3123.6.5 by Aaron Bentley
Symlink to real files if possible
960
        tree.rename_one('oldname', 'newname')
3287.18.23 by Matt McClure
Adds comments that document my understanding of
961
        tree.rename_one('oldname2', 'newname2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
962
        self.build_tree_contents([('tree/newname', b'newcontent')])
963
        self.build_tree_contents([('tree/newname2', b'newcontent2')])
3123.6.2 by Aaron Bentley
Implement diff --using natively
964
        old_tree = tree.basis_tree()
965
        old_tree.lock_read()
966
        self.addCleanup(old_tree.unlock)
3123.6.4 by Aaron Bentley
Set mtime (and atime) on files for --using
967
        tree.lock_read()
968
        self.addCleanup(tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
969
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
970
                                      'print "{old_path} {new_path}"'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
971
                                     old_tree, tree, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
972
        self.addCleanup(diff_obj.finish)
6681.2.10 by Jelmer Vernooij
Fix failures.
973
        self.assertContainsRe(diff_obj._root, 'brz-diff-[^/]*')
6809.4.15 by Jelmer Vernooij
Fix some more tests.
974
        old_path, new_path = diff_obj._prepare_files(
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
975
            'oldname', 'newname')
3123.6.2 by Aaron Bentley
Implement diff --using natively
976
        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
977
        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.
978
        self.assertContainsRe(new_path, 'tree/newname$')
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
979
        self.assertFileEqual(b'oldcontent', old_path)
980
        self.assertFileEqual(b'newcontent', new_path)
3287.18.14 by Matt McClure
Extracted a host_os_dereferences_symlinks method.
981
        if osutils.host_os_dereferences_symlinks():
3123.6.5 by Aaron Bentley
Symlink to real files if possible
982
            self.assertTrue(os.path.samefile('tree/newname', new_path))
3123.6.2 by Aaron Bentley
Implement diff --using natively
983
        # make sure we can create files with the same parent directories
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
984
        diff_obj._prepare_files('oldname2', 'newname2')
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
985
986
5074.5.4 by INADA Naoki
fix easy bug.
987
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
5074.5.2 by INADA Naoki
Add test for encoded filenames
988
989
    def test_encodable_filename(self):
5074.5.9 by INADA Naoki
Make additional comments to clarify
990
        # Just checks file path for external diff tool.
991
        # We cannot change CPython's internal encoding used by os.exec*.
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
992
        diffobj = diff.DiffFromTool(['dummy', '{old_path}', '{new_path}'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
993
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
994
        for _, scenario in EncodingAdapter.encoding_scenarios:
995
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
996
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
997
            filename = scenario['info']['filename']
5074.5.6 by INADA Naoki
Change directry name for each check.
998
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
999
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1000
            relpath = dirname + u'/' + filename
1001
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1002
            self.assertEqual(fullpath,
1003
                             fullpath.encode(encoding).decode(encoding))
1004
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1005
1006
    def test_unencodable_filename(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
1007
        diffobj = diff.DiffFromTool(['dummy', '{old_path}', '{new_path}'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1008
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
1009
        for _, scenario in EncodingAdapter.encoding_scenarios:
1010
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1011
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
1012
            filename = scenario['info']['filename']
1013
1014
            if encoding == 'iso-8859-1':
1015
                encoding = 'iso-8859-2'
1016
            else:
1017
                encoding = 'iso-8859-1'
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1018
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
1019
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1020
            relpath = dirname + u'/' + filename
1021
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1022
            self.assertEqual(fullpath,
1023
                             fullpath.encode(encoding).decode(encoding))
1024
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1025
1026
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1027
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.
1028
1029
    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.
1030
        """Call get_trees_and_branches_to_diff_locked."""
7479.2.1 by Jelmer Vernooij
Drop python2 support.
1031
        exit_stack = contextlib.ExitStack()
7356.1.3 by Jelmer Vernooij
Fix tests.
1032
        self.addCleanup(exit_stack.close)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1033
        return diff.get_trees_and_branches_to_diff_locked(
7356.1.3 by Jelmer Vernooij
Fix tests.
1034
            path_list, revision_specs, old_url, new_url, exit_stack)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1035
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1036
    def test_basic(self):
1037
        tree = self.make_branch_and_tree('tree')
1038
        (old_tree, new_tree,
1039
         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.
1040
         specific_files, extra_trees) = self.call_gtabtd(
1041
             ['tree'], None, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1042
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1043
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1044
        self.assertEqual(_mod_revision.NULL_REVISION,
1045
                         old_tree.get_revision_id())
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1046
        self.assertEqual(tree.basedir, new_tree.basedir)
1047
        self.assertEqual(tree.branch.base, old_branch.base)
1048
        self.assertEqual(tree.branch.base, new_branch.base)
1049
        self.assertIs(None, specific_files)
1050
        self.assertIs(None, extra_trees)
1051
1052
    def test_with_rev_specs(self):
1053
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1054
        self.build_tree_contents([('tree/file', b'oldcontent')])
1055
        tree.add('file', b'file-id')
1056
        tree.commit('old tree', timestamp=0, rev_id=b"old-id")
1057
        self.build_tree_contents([('tree/file', b'newcontent')])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1058
        tree.commit('new tree', timestamp=0, rev_id=b"new-id")
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1059
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1060
        revisions = [revisionspec.RevisionSpec.from_string('1'),
1061
                     revisionspec.RevisionSpec.from_string('2')]
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1062
        (old_tree, new_tree,
1063
         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.
1064
         specific_files, extra_trees) = self.call_gtabtd(
1065
            ['tree'], revisions, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1066
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1067
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1068
        self.assertEqual(b"old-id", old_tree.get_revision_id())
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1069
        self.assertIsInstance(new_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1070
        self.assertEqual(b"new-id", new_tree.get_revision_id())
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1071
        self.assertEqual(tree.branch.base, old_branch.base)
1072
        self.assertEqual(tree.branch.base, new_branch.base)
1073
        self.assertIs(None, specific_files)
4705.1.4 by Gary van der Merwe
Add newline to end of test_diff.py
1074
        self.assertEqual(tree.basedir, extra_trees[0].basedir)