/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
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
562
        tt = tree.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
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
572
        tt = tree.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)))])
7490.35.2 by Jelmer Vernooij
Distinguish between label and path when generating diffs.
608
        tree.add([alpha])
609
        tree.add([omega])
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(),
7490.35.2 by Jelmer Vernooij
Distinguish between label and path when generating diffs.
805
            br'--- olddir/oldfile.*\n'
806
            br'\+\+\+ newdir/newfile.*\n'
807
            br'\@\@ -1,1 \+0,0 \@\@\n'
808
            br'-old\n'
809
            br'\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
810
        self.assertContainsRe(self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
811
                              b"=== target is 'new'\n")
3009.2.9 by Aaron Bentley
Add tests for Differ
812
3009.2.19 by Aaron Bentley
Implement directory diffing
813
    def test_diff_directory(self):
814
        self.build_tree(['new-tree/new-dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
815
        self.new_tree.add('new-dir', b'new-dir-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
816
        self.differ.diff(None, 'new-dir')
6973.12.3 by Jelmer Vernooij
Fixes.
817
        self.assertEqual(self.differ.to_file.getvalue(), b'')
3009.2.19 by Aaron Bentley
Implement directory diffing
818
3009.2.16 by Aaron Bentley
Test support for extra differs
819
    def create_old_new(self):
820
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
821
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
822
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
823
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
824
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
825
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.16 by Aaron Bentley
Test support for extra differs
826
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
827
        self.new_tree.add('newdir/newfile', b'file-id')
3009.2.16 by Aaron Bentley
Test support for extra differs
828
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
829
    def test_register_diff(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
830
        self.create_old_new()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
831
        old_diff_factories = diff.DiffTree.diff_factories
7143.15.2 by Jelmer Vernooij
Run autopep8.
832
        diff.DiffTree.diff_factories = old_diff_factories[:]
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
833
        diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
3009.2.16 by Aaron Bentley
Test support for extra differs
834
        try:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
835
            differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.16 by Aaron Bentley
Test support for extra differs
836
        finally:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
837
            diff.DiffTree.diff_factories = old_diff_factories
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
838
        differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
839
        self.assertNotContainsRe(
840
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
841
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
842
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
843
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
844
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
845
3009.2.27 by Aaron Bentley
Use extra_factories instead of extra_diffs
846
    def test_extra_factories(self):
3009.2.16 by Aaron Bentley
Test support for extra differs
847
        self.create_old_new()
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
848
        differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO(),
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
849
                               extra_factories=[DiffWasIs.from_diff_tree])
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
850
        differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.16 by Aaron Bentley
Test support for extra differs
851
        self.assertNotContainsRe(
852
            differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
853
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
854
            br' \@\@\n-old\n\+new\n\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
855
        self.assertContainsRe(differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
856
                              b'was: old\nis: new\n')
3009.2.16 by Aaron Bentley
Test support for extra differs
857
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
858
    def test_alphabetical_order(self):
859
        self.build_tree(['new-tree/a-file'])
860
        self.new_tree.add('a-file')
861
        self.build_tree(['old-tree/b-file'])
862
        self.old_tree.add('b-file')
863
        self.differ.show_diff(None)
864
        self.assertContainsRe(self.differ.to_file.getvalue(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
865
                              b'.*a-file(.|\n)*b-file')
3123.4.1 by Aaron Bentley
Diff sorts files in alphabetical order
866
3009.2.9 by Aaron Bentley
Add tests for Differ
867
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
868
class TestDiffFromTool(tests.TestCaseWithTransport):
3123.6.2 by Aaron Bentley
Implement diff --using natively
869
870
    def test_from_string(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
871
        diff_obj = diff.DiffFromTool.from_string(
872
            ['diff', '{old_path}', '{new_path}'],
873
            None, None, None)
3123.6.2 by Aaron Bentley
Implement diff --using natively
874
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
875
        self.assertEqual(['diff', '{old_path}', '{new_path}'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
876
                         diff_obj.command_template)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
877
7290.1.44 by Jelmer Vernooij
Fix diff --using when {old_path} and {new_path} are not specified in the template.
878
    def test_from_string_no_paths(self):
879
        diff_obj = diff.DiffFromTool.from_string(
880
            ['diff', "-u5"], None, None, None)
881
        self.addCleanup(diff_obj.finish)
882
        self.assertEqual(['diff', '-u5'],
883
                         diff_obj.command_template)
884
        self.assertEqual(['diff', '-u5', 'old-path', 'new-path'],
885
                         diff_obj._get_command('old-path', 'new-path'))
886
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
887
    def test_from_string_u5(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
888
        diff_obj = diff.DiffFromTool.from_string(
7358.6.3 by Jelmer Vernooij
Fix formatting.
889
            ['diff', "-u 5", '{old_path}', '{new_path}'], None, None, None)
3199.1.6 by Vincent Ladeuil
Fiz last leaking tmp dir.
890
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
891
        self.assertEqual(['diff', '-u 5', '{old_path}', '{new_path}'],
3123.6.2 by Aaron Bentley
Implement diff --using natively
892
                         diff_obj.command_template)
893
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
894
                         diff_obj._get_command('old-path', 'new-path'))
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
895
4913.5.8 by Gordon Tyler
Added test_from_string_path_with_backslashes, which tests the actual scenario in bug 392428.
896
    def test_from_string_path_with_backslashes(self):
5241.2.2 by Robert Collins
Missed one test.
897
        self.requireFeature(features.backslashdir_feature)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
898
        tool = ['C:\\Tools\\Diff.exe', '{old_path}', '{new_path}']
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
899
        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.
900
        self.addCleanup(diff_obj.finish)
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
901
        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.
902
                         diff_obj.command_template)
903
        self.assertEqual(['C:\\Tools\\Diff.exe', 'old-path', 'new-path'],
904
                         diff_obj._get_command('old-path', 'new-path'))
3123.6.2 by Aaron Bentley
Implement diff --using natively
905
906
    def test_execute(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
907
        output = BytesIO()
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
908
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
909
                                      'print("{old_path} {new_path}")'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
910
                                     None, None, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
911
        self.addCleanup(diff_obj.finish)
912
        diff_obj._execute('old', 'new')
6973.12.3 by Jelmer Vernooij
Fixes.
913
        self.assertEqual(output.getvalue().rstrip(), b'old new')
3123.6.2 by Aaron Bentley
Implement diff --using natively
914
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.
915
    def test_execute_missing(self):
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
916
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
917
                                     None, None, None)
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
918
        self.addCleanup(diff_obj.finish)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
919
        e = self.assertRaises(errors.ExecutableMissing, diff_obj._execute,
920
                              'old', 'new')
3145.1.1 by Aaron Bentley
Handle missing tools gracefully in diff --using
921
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
922
                         ' on this machine', str(e))
923
3287.18.22 by Matt McClure
Reverts to prior decomposition of exercise and verification, as suggested
924
    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
925
        self.requireFeature(features.AttribFeature)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
926
        output = BytesIO()
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
927
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
928
        self.build_tree_contents([('tree/file', b'content')])
929
        tree.add('file', b'file-id')
3287.18.11 by Matt McClure
Removed unnecessary timestamp parameter.
930
        tree.commit('old tree')
3287.18.10 by Matt McClure
Uses TestSkipped for test_execute_windows_tool on non-Windows platforms.
931
        tree.lock_read()
932
        self.addCleanup(tree.unlock)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
933
        basis_tree = tree.basis_tree()
934
        basis_tree.lock_read()
935
        self.addCleanup(basis_tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
936
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
937
                                      'print "{old_path} {new_path}"'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
938
                                     basis_tree, tree, output)
6855.4.1 by Jelmer Vernooij
Yet more bees.
939
        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
940
        # The old content should be readonly
941
        self.assertReadableByAttrib(diff_obj._root, 'old\\file',
942
                                    r'R.*old\\file$')
943
        # The new content should use the tree object, not a 'new' file anymore
944
        self.assertEndsWith(tree.basedir, 'work/tree')
945
        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
946
947
    def assertReadableByAttrib(self, cwd, relpath, regex):
948
        proc = subprocess.Popen(['attrib', relpath],
949
                                stdout=subprocess.PIPE,
950
                                cwd=cwd)
4873.3.1 by John Arbash Meinel
Now that we return files directly from the working tree
951
        (result, err) = proc.communicate()
952
        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
953
3123.6.2 by Aaron Bentley
Implement diff --using natively
954
    def test_prepare_files(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
955
        output = BytesIO()
3123.6.2 by Aaron Bentley
Implement diff --using natively
956
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
957
        self.build_tree_contents([('tree/oldname', b'oldcontent')])
958
        self.build_tree_contents([('tree/oldname2', b'oldcontent2')])
959
        tree.add('oldname', b'file-id')
960
        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
961
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
962
        tree.commit('old tree', timestamp=315532800)
3123.6.5 by Aaron Bentley
Symlink to real files if possible
963
        tree.rename_one('oldname', 'newname')
3287.18.23 by Matt McClure
Adds comments that document my understanding of
964
        tree.rename_one('oldname2', 'newname2')
6855.4.1 by Jelmer Vernooij
Yet more bees.
965
        self.build_tree_contents([('tree/newname', b'newcontent')])
966
        self.build_tree_contents([('tree/newname2', b'newcontent2')])
3123.6.2 by Aaron Bentley
Implement diff --using natively
967
        old_tree = tree.basis_tree()
968
        old_tree.lock_read()
969
        self.addCleanup(old_tree.unlock)
3123.6.4 by Aaron Bentley
Set mtime (and atime) on files for --using
970
        tree.lock_read()
971
        self.addCleanup(tree.unlock)
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
972
        diff_obj = diff.DiffFromTool([sys.executable, '-c',
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
973
                                      'print "{old_path} {new_path}"'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
974
                                     old_tree, tree, output)
3123.6.2 by Aaron Bentley
Implement diff --using natively
975
        self.addCleanup(diff_obj.finish)
6681.2.10 by Jelmer Vernooij
Fix failures.
976
        self.assertContainsRe(diff_obj._root, 'brz-diff-[^/]*')
6809.4.15 by Jelmer Vernooij
Fix some more tests.
977
        old_path, new_path = diff_obj._prepare_files(
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
978
            'oldname', 'newname')
3123.6.2 by Aaron Bentley
Implement diff --using natively
979
        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
980
        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.
981
        self.assertContainsRe(new_path, 'tree/newname$')
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
982
        self.assertFileEqual(b'oldcontent', old_path)
983
        self.assertFileEqual(b'newcontent', new_path)
3287.18.14 by Matt McClure
Extracted a host_os_dereferences_symlinks method.
984
        if osutils.host_os_dereferences_symlinks():
3123.6.5 by Aaron Bentley
Symlink to real files if possible
985
            self.assertTrue(os.path.samefile('tree/newname', new_path))
3123.6.2 by Aaron Bentley
Implement diff --using natively
986
        # make sure we can create files with the same parent directories
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
987
        diff_obj._prepare_files('oldname2', 'newname2')
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
988
989
5074.5.4 by INADA Naoki
fix easy bug.
990
class TestDiffFromToolEncodedFilename(tests.TestCaseWithTransport):
5074.5.2 by INADA Naoki
Add test for encoded filenames
991
992
    def test_encodable_filename(self):
5074.5.9 by INADA Naoki
Make additional comments to clarify
993
        # Just checks file path for external diff tool.
994
        # 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.
995
        diffobj = diff.DiffFromTool(['dummy', '{old_path}', '{new_path}'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
996
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
997
        for _, scenario in EncodingAdapter.encoding_scenarios:
998
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
999
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
1000
            filename = scenario['info']['filename']
5074.5.6 by INADA Naoki
Change directry name for each check.
1001
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
1002
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1003
            relpath = dirname + u'/' + filename
1004
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1005
            self.assertEqual(fullpath,
1006
                             fullpath.encode(encoding).decode(encoding))
1007
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1008
1009
    def test_unencodable_filename(self):
7358.6.1 by Jelmer Vernooij
Use standard syntax for the ``change_editor`` configuration option.
1010
        diffobj = diff.DiffFromTool(['dummy', '{old_path}', '{new_path}'],
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1011
                                    None, None, None)
5074.5.2 by INADA Naoki
Add test for encoded filenames
1012
        for _, scenario in EncodingAdapter.encoding_scenarios:
1013
            encoding = scenario['encoding']
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1014
            dirname = scenario['info']['directory']
5074.5.2 by INADA Naoki
Add test for encoded filenames
1015
            filename = scenario['info']['filename']
1016
1017
            if encoding == 'iso-8859-1':
1018
                encoding = 'iso-8859-2'
1019
            else:
1020
                encoding = 'iso-8859-1'
5074.5.7 by INADA Naoki
Test for filename encoding can't test subprocess execution because
1021
5074.5.8 by INADA Naoki
Use tempfile when filepath in tree is not be able to encode with fsencoding.
1022
            self.overrideAttr(diffobj, '_fenc', lambda: encoding)
1023
            relpath = dirname + u'/' + filename
1024
            fullpath = diffobj._safe_filename('safe', relpath)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1025
            self.assertEqual(fullpath,
1026
                             fullpath.encode(encoding).decode(encoding))
1027
            self.assertTrue(fullpath.startswith(diffobj._root + '/safe'))
5074.5.2 by INADA Naoki
Add test for encoded filenames
1028
1029
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1030
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.
1031
1032
    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.
1033
        """Call get_trees_and_branches_to_diff_locked."""
7479.2.1 by Jelmer Vernooij
Drop python2 support.
1034
        exit_stack = contextlib.ExitStack()
7356.1.3 by Jelmer Vernooij
Fix tests.
1035
        self.addCleanup(exit_stack.close)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
1036
        return diff.get_trees_and_branches_to_diff_locked(
7356.1.3 by Jelmer Vernooij
Fix tests.
1037
            path_list, revision_specs, old_url, new_url, exit_stack)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1038
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1039
    def test_basic(self):
1040
        tree = self.make_branch_and_tree('tree')
1041
        (old_tree, new_tree,
1042
         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.
1043
         specific_files, extra_trees) = self.call_gtabtd(
1044
             ['tree'], None, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1045
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1046
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1047
        self.assertEqual(_mod_revision.NULL_REVISION,
1048
                         old_tree.get_revision_id())
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1049
        self.assertEqual(tree.basedir, new_tree.basedir)
1050
        self.assertEqual(tree.branch.base, old_branch.base)
1051
        self.assertEqual(tree.branch.base, new_branch.base)
1052
        self.assertIs(None, specific_files)
1053
        self.assertIs(None, extra_trees)
1054
1055
    def test_with_rev_specs(self):
1056
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
1057
        self.build_tree_contents([('tree/file', b'oldcontent')])
1058
        tree.add('file', b'file-id')
1059
        tree.commit('old tree', timestamp=0, rev_id=b"old-id")
1060
        self.build_tree_contents([('tree/file', b'newcontent')])
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1061
        tree.commit('new tree', timestamp=0, rev_id=b"new-id")
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1062
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1063
        revisions = [revisionspec.RevisionSpec.from_string('1'),
1064
                     revisionspec.RevisionSpec.from_string('2')]
4705.1.2 by Gary van der Merwe
Start on tests for get_trees_and_branches_to_diff.
1065
        (old_tree, new_tree,
1066
         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.
1067
         specific_files, extra_trees) = self.call_gtabtd(
1068
            ['tree'], revisions, None, None)
4732.1.2 by Vincent Ladeuil
(trivial) Fix some PEP8 issues
1069
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1070
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1071
        self.assertEqual(b"old-id", old_tree.get_revision_id())
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
1072
        self.assertIsInstance(new_tree, revisiontree.RevisionTree)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
1073
        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.
1074
        self.assertEqual(tree.branch.base, old_branch.base)
1075
        self.assertEqual(tree.branch.base, new_branch.base)
1076
        self.assertIs(None, specific_files)
4705.1.4 by Gary van der Merwe
Add newline to end of test_diff.py
1077
        self.assertEqual(tree.basedir, extra_trees[0].basedir)