/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6619.2.1 by Vincent Ladeuil
Fix test failure for recent versions of diff
1
# Copyright (C) 2005-2012, 2014, 2016, 2017 Canonical Ltd
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
12
#
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
16
1740.2.5 by Aaron Bentley
Merge from bzr.dev
17
import os
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
18
import re
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
19
import subprocess
7141.1.1 by Jelmer Vernooij
Use sys.executable rather than python for ad-hoc tests.
20
import sys
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
21
import tempfile
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
22
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
23
from .. import (
7356.1.3 by Jelmer Vernooij
Fix tests.
24
    cleanup,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
25
    diff,
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
26
    errors,
27
    osutils,
28
    revision as _mod_revision,
29
    revisionspec,
30
    revisiontree,
31
    tests,
32
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
33
from ..sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
34
    BytesIO,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
35
    unichr,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
36
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
37
from ..tests import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
38
    features,
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
39
    EncodingAdapter,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
40
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
41
from ..tests.scenarios import load_tests_apply_scenarios
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
42
43
44
load_tests = load_tests_apply_scenarios
2781.1.1 by Martin Pool
merge cpatiencediff from Lukas
45
46
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
47
def subst_dates(string):
48
    """Replace date strings with constant values."""
49
    return re.sub(br'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
50
                  b'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
51
52
1558.15.11 by Aaron Bentley
Apply merge review suggestions
53
def udiff_lines(old, new, allow_binary=False):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
54
    output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
55
    diff.internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
56
    output.seek(0, 0)
57
    return output.readlines()
58
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
59
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
60
def external_udiff_lines(old, new, use_stringio=False):
61
    if use_stringio:
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
62
        # BytesIO has no fileno, so it tests a different codepath
63
        output = BytesIO()
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
64
    else:
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
65
        output = tempfile.TemporaryFile()
1692.8.7 by James Henstridge
changes suggested by John Meinel
66
    try:
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
67
        diff.external_diff('old', old, 'new', new, output, diff_opts=['-u'])
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
68
    except errors.NoDiff:
69
        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
70
    output.seek(0, 0)
71
    lines = output.readlines()
72
    output.close()
73
    return lines
74
75
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
76
class StubO(object):
77
    """Simple file-like object that allows writes with any type and records."""
78
79
    def __init__(self):
80
        self.write_record = []
81
82
    def write(self, data):
83
        self.write_record.append(data)
84
85
    def check_types(self, testcase, expected_type):
86
        testcase.assertFalse(
87
            any(not isinstance(o, expected_type) for o in self.write_record),
88
            "Not all writes of type %s: %r" % (
89
                expected_type.__name__, self.write_record))
90
91
6597.2.2 by Vincent Ladeuil
Split the diff tests to get finer grained failures. Also cleaned up some unused imports.
92
class TestDiffOptions(tests.TestCase):
93
94
    def test_unified_added(self):
95
        """Check for default style '-u' only if no other style specified
96
        in 'diff-options'.
97
        """
98
        # Verify that style defaults to unified, id est '-u' appended
99
        # to option list, in the absence of an alternative style.
100
        self.assertEqual(['-a', '-u'], diff.default_style_unified(['-a']))
101
102
103
class TestDiffOptionsScenarios(tests.TestCase):
104
105
    scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
7143.15.2 by Jelmer Vernooij
Run autopep8.
106
    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.
107
108
    def test_unified_not_added(self):
109
        # Verify that for all valid style options, '-u' is not
110
        # appended to option list.
111
        ret_opts = diff.default_style_unified(diff_opts=["%s" % (self.style,)])
112
        self.assertEqual(["%s" % (self.style,)], ret_opts)
113
114
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
115
class TestDiff(tests.TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
116
1102 by Martin Pool
- merge test refactoring from robertc
117
    def test_add_nl(self):
118
        """diff generates a valid diff for patches that add a newline"""
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
119
        lines = udiff_lines([b'boo'], [b'boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
120
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
121
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
122
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
123
1102 by Martin Pool
- merge test refactoring from robertc
124
    def test_add_nl_2(self):
125
        """diff generates a valid diff for patches that change last line and
126
        add a newline.
127
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
128
        lines = udiff_lines([b'boo'], [b'goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
129
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
130
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
131
        ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
132
1102 by Martin Pool
- merge test refactoring from robertc
133
    def test_remove_nl(self):
134
        """diff generates a valid diff for patches that change last line and
135
        add a newline.
136
        """
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
137
        lines = udiff_lines([b'boo\n'], [b'boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
138
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
139
        self.assertEqual(lines[5], b'\\ No newline at end of file\n')
7143.15.2 by Jelmer Vernooij
Run autopep8.
140
        ## "expected no-nl, got %r" % lines[5]
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
141
142
    def check_patch(self, lines):
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
143
        self.assertTrue(len(lines) > 1)
7143.15.2 by Jelmer Vernooij
Run autopep8.
144
        ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
145
        self.assertTrue(lines[0].startswith(b'---'))
146
        ## 'No orig line for patch:\n%s' % "".join(lines)
147
        self.assertTrue(lines[1].startswith(b'+++'))
148
        ## 'No mod line for patch:\n%s' % "".join(lines)
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
149
        self.assertTrue(len(lines) > 2)
7143.15.2 by Jelmer Vernooij
Run autopep8.
150
        ## "No hunks for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
151
        self.assertTrue(lines[2].startswith(b'@@'))
7143.15.2 by Jelmer Vernooij
Run autopep8.
152
        ## "No hunk header for patch:\n%s" % "".join(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
153
        self.assertTrue(b'@@' in lines[2][2:])
7143.15.2 by Jelmer Vernooij
Run autopep8.
154
        ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
155
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
156
    def test_binary_lines(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
157
        empty = []
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
158
        uni_lines = [1023 * b'a' + b'\x00']
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
159
        self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines, empty)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
160
        self.assertRaises(errors.BinaryFile, udiff_lines, empty, uni_lines)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
161
        udiff_lines(uni_lines, empty, allow_binary=True)
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
162
        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
163
164
    def test_external_diff(self):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
165
        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
166
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
167
        self.assertEqual(b'\n', lines[-1])
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
168
169
    def test_external_diff_no_fileno(self):
170
        # Make sure that we can handle not having a fileno, even
171
        # if the diff is large
7143.15.2 by Jelmer Vernooij
Run autopep8.
172
        lines = external_udiff_lines([b'boo\n'] * 10000,
173
                                     [b'goo\n'] * 10000,
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
174
                                     use_stringio=True)
175
        self.check_patch(lines)
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
176
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
177
    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)
178
        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.
179
            self.overrideEnv(lang, 'C')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
180
        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.
181
        # Older versions of diffutils say "Binary files", newer
182
        # versions just say "Files".
7143.15.2 by Jelmer Vernooij
Run autopep8.
183
        self.assertContainsRe(
184
            lines[0], b'(Binary f|F)iles old and new differ\n')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
185
        self.assertEqual(lines[1:], [b'\n'])
1899.1.4 by John Arbash Meinel
Just swallow a return code of 2
186
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
187
    def test_no_external_diff(self):
188
        """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.
189
        # Make sure no 'diff' command is available
190
        # XXX: Weird, using None instead of '' breaks the test -- vila 20101216
191
        self.overrideEnv('PATH', '')
192
        self.assertRaises(errors.NoDiff, diff.external_diff,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
193
                          b'old', [b'boo\n'], b'new', [b'goo\n'],
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
194
                          BytesIO(), diff_opts=['-u'])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
196
    def test_internal_diff_default(self):
197
        # Default internal diff encoding is utf8
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
198
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
199
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
200
                           u'new_\xe5', [b'new_text\n'], output)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
201
        lines = output.getvalue().splitlines(True)
202
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
203
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
204
                          b'+++ new_\xc3\xa5\n',
205
                          b'@@ -1,1 +1,1 @@\n',
206
                          b'-old_text\n',
207
                          b'+new_text\n',
208
                          b'\n',
209
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
210
211
    def test_internal_diff_utf8(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
212
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
213
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
214
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
215
                           path_encoding='utf8')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
216
        lines = output.getvalue().splitlines(True)
217
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
218
        self.assertEqual([b'--- old_\xc2\xb5\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
219
                          b'+++ new_\xc3\xa5\n',
220
                          b'@@ -1,1 +1,1 @@\n',
221
                          b'-old_text\n',
222
                          b'+new_text\n',
223
                          b'\n',
224
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
225
226
    def test_internal_diff_iso_8859_1(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
227
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
228
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
229
                           u'new_\xe5', [b'new_text\n'], output,
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
230
                           path_encoding='iso-8859-1')
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
231
        lines = output.getvalue().splitlines(True)
232
        self.check_patch(lines)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
233
        self.assertEqual([b'--- old_\xb5\n',
234
                          b'+++ new_\xe5\n',
235
                          b'@@ -1,1 +1,1 @@\n',
236
                          b'-old_text\n',
237
                          b'+new_text\n',
238
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
239
                          ], lines)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
240
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
241
    def test_internal_diff_no_content(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
242
        output = BytesIO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
243
        diff.internal_diff(u'old', [], u'new', [], output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
244
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
245
246
    def test_internal_diff_no_changes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
247
        output = BytesIO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
248
        diff.internal_diff(u'old', [b'text\n', b'contents\n'],
249
                           u'new', [b'text\n', b'contents\n'],
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
250
                           output)
6973.13.2 by Jelmer Vernooij
Fix some more tests.
251
        self.assertEqual(b'', output.getvalue())
3085.1.1 by John Arbash Meinel
Fix internal_diff to not fail when the texts are identical.
252
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
253
    def test_internal_diff_returns_bytes(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
254
        output = StubO()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
255
        diff.internal_diff(u'old_\xb5', [b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
256
                           u'new_\xe5', [b'new_text\n'], output)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
257
        output.check_types(self, bytes)
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
258
6524.5.5 by Paul Nixon
Added tests of configurable context
259
    def test_internal_diff_default_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
260
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
261
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
262
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
263
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
264
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output)
6524.5.5 by Paul Nixon
Added tests of configurable context
265
        lines = output.getvalue().splitlines(True)
266
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
267
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
268
                          b'+++ new\n',
269
                          b'@@ -3,4 +3,4 @@\n',
270
                          b' same_text\n',
271
                          b' same_text\n',
272
                          b' same_text\n',
273
                          b'-old_text\n',
274
                          b'+new_text\n',
275
                          b'\n',
276
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
277
278
    def test_internal_diff_no_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
279
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
280
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
281
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
282
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
283
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
6524.5.5 by Paul Nixon
Added tests of configurable context
284
                           context_lines=0)
285
        lines = output.getvalue().splitlines(True)
286
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
287
        self.assertEqual([b'--- old\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
288
                          b'+++ new\n',
289
                          b'@@ -6,1 +6,1 @@\n',
290
                          b'-old_text\n',
291
                          b'+new_text\n',
292
                          b'\n',
293
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
294
295
    def test_internal_diff_more_context(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
296
        output = BytesIO()
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
297
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
298
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
299
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
300
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
6524.5.5 by Paul Nixon
Added tests of configurable context
301
                           context_lines=4)
302
        lines = output.getvalue().splitlines(True)
303
        self.check_patch(lines)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
304
        self.assertEqual([b'--- old\n',
305
                          b'+++ new\n',
306
                          b'@@ -2,5 +2,5 @@\n',
307
                          b' same_text\n',
308
                          b' same_text\n',
309
                          b' same_text\n',
310
                          b' same_text\n',
311
                          b'-old_text\n',
312
                          b'+new_text\n',
313
                          b'\n',
7143.15.2 by Jelmer Vernooij
Run autopep8.
314
                          ], lines)
6524.5.5 by Paul Nixon
Added tests of configurable context
315
316
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
317
class TestDiffFiles(tests.TestCaseInTempDir):
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
318
319
    def test_external_diff_binary(self):
320
        """The output when using external diff should use diff's i18n error"""
6792.1.2 by Jelmer Vernooij
Alternative approach.
321
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
322
            self.overrideEnv(lang, 'C')
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
323
        # Make sure external_diff doesn't fail in the current LANG
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
324
        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
325
2240.1.1 by Alexander Belchenko
test_external_diff_binary: run external diff with --binary flag
326
        cmd = ['diff', '-u', '--binary', 'old', 'new']
7143.15.2 by Jelmer Vernooij
Run autopep8.
327
        with open('old', 'wb') as f:
328
            f.write(b'\x00foobar\n')
329
        with open('new', 'wb') as f:
330
            f.write(b'foo\x00bar\n')
6792.1.3 by Jelmer Vernooij
Alternative approach.
331
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
7143.15.2 by Jelmer Vernooij
Run autopep8.
332
                                stdin=subprocess.PIPE)
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
333
        out, err = pipe.communicate()
334
        # We should output whatever diff tells us, plus a trailing newline
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
335
        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
336
337
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
338
def get_diff_as_string(tree1, tree2, specific_files=None, working_tree=None):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
339
    output = BytesIO()
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
340
    if working_tree is not None:
341
        extra_trees = (working_tree,)
342
    else:
343
        extra_trees = ()
344
    diff.show_diff_trees(tree1, tree2, output,
7143.15.2 by Jelmer Vernooij
Run autopep8.
345
                         specific_files=specific_files,
346
                         extra_trees=extra_trees, old_label='old/',
347
                         new_label='new/')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
348
    return output.getvalue()
349
350
351
class TestDiffDates(tests.TestCaseWithTransport):
1740.2.5 by Aaron Bentley
Merge from bzr.dev
352
353
    def setUp(self):
354
        super(TestDiffDates, self).setUp()
355
        self.wt = self.make_branch_and_tree('.')
356
        self.b = self.wt.branch
357
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
358
            ('file1', b'file1 contents at rev 1\n'),
359
            ('file2', b'file2 contents at rev 1\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
360
            ])
361
        self.wt.add(['file1', 'file2'])
362
        self.wt.commit(
363
            message='Revision 1',
7143.15.2 by Jelmer Vernooij
Run autopep8.
364
            timestamp=1143849600,  # 2006-04-01 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
365
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
366
            rev_id=b'rev-1')
367
        self.build_tree_contents([('file1', b'file1 contents at rev 2\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
368
        self.wt.commit(
369
            message='Revision 2',
7143.15.2 by Jelmer Vernooij
Run autopep8.
370
            timestamp=1143936000,  # 2006-04-02 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
371
            timezone=28800,
6855.4.1 by Jelmer Vernooij
Yet more bees.
372
            rev_id=b'rev-2')
373
        self.build_tree_contents([('file2', b'file2 contents at rev 3\n')])
1740.2.5 by Aaron Bentley
Merge from bzr.dev
374
        self.wt.commit(
375
            message='Revision 3',
7143.15.2 by Jelmer Vernooij
Run autopep8.
376
            timestamp=1144022400,  # 2006-04-03 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
377
            timezone=-3600,
6855.4.1 by Jelmer Vernooij
Yet more bees.
378
            rev_id=b'rev-3')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
379
        self.wt.remove(['file2'])
380
        self.wt.commit(
381
            message='Revision 4',
7143.15.2 by Jelmer Vernooij
Run autopep8.
382
            timestamp=1144108800,  # 2006-04-04 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
383
            timezone=0,
6855.4.1 by Jelmer Vernooij
Yet more bees.
384
            rev_id=b'rev-4')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
385
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
386
            ('file1', b'file1 contents in working tree\n')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
387
            ])
388
        # set the date stamps for files in the working tree to known values
7143.15.2 by Jelmer Vernooij
Run autopep8.
389
        os.utime('file1', (1144195200, 1144195200))  # 2006-04-05 00:00:00 UTC
1740.2.5 by Aaron Bentley
Merge from bzr.dev
390
391
    def test_diff_rev_tree_working_tree(self):
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
392
        output = get_diff_as_string(self.wt.basis_tree(), self.wt)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
393
        # note that the date for old/file1 is from rev 2 rather than from
394
        # the basis revision (rev 4)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
395
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
396
=== modified file 'file1'
397
--- old/file1\t2006-04-02 00:00:00 +0000
398
+++ new/file1\t2006-04-05 00:00:00 +0000
399
@@ -1,1 +1,1 @@
400
-file1 contents at rev 2
401
+file1 contents in working tree
402
403
''')
404
405
    def test_diff_rev_tree_rev_tree(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
406
        tree1 = self.b.repository.revision_tree(b'rev-2')
407
        tree2 = self.b.repository.revision_tree(b'rev-3')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
408
        output = get_diff_as_string(tree1, tree2)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
409
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
410
=== modified file 'file2'
411
--- old/file2\t2006-04-01 00:00:00 +0000
412
+++ new/file2\t2006-04-03 00:00:00 +0000
413
@@ -1,1 +1,1 @@
414
-file2 contents at rev 1
415
+file2 contents at rev 3
416
417
''')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
418
1740.2.5 by Aaron Bentley
Merge from bzr.dev
419
    def test_diff_add_files(self):
3668.5.1 by Jelmer Vernooij
Use NULL_REVISION rather than None for Repository.revision_tree().
420
        tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
6973.5.2 by Jelmer Vernooij
Add more bees.
421
        tree2 = self.b.repository.revision_tree(b'rev-1')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
422
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
423
        # the files have the epoch time stamp for the tree in which
424
        # they don't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
425
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
426
=== added file 'file1'
427
--- old/file1\t1970-01-01 00:00:00 +0000
428
+++ new/file1\t2006-04-01 00:00:00 +0000
429
@@ -0,0 +1,1 @@
430
+file1 contents at rev 1
431
432
=== added file 'file2'
433
--- old/file2\t1970-01-01 00:00:00 +0000
434
+++ new/file2\t2006-04-01 00:00:00 +0000
435
@@ -0,0 +1,1 @@
436
+file2 contents at rev 1
437
438
''')
439
440
    def test_diff_remove_files(self):
6973.5.2 by Jelmer Vernooij
Add more bees.
441
        tree1 = self.b.repository.revision_tree(b'rev-3')
442
        tree2 = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
443
        output = get_diff_as_string(tree1, tree2)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
444
        # the file has the epoch time stamp for the tree in which
445
        # it doesn't exist.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
446
        self.assertEqualDiff(output, b'''\
1740.2.5 by Aaron Bentley
Merge from bzr.dev
447
=== removed file 'file2'
448
--- old/file2\t2006-04-03 00:00:00 +0000
449
+++ new/file2\t1970-01-01 00:00:00 +0000
450
@@ -1,1 +0,0 @@
451
-file2 contents at rev 3
452
453
''')
454
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
455
    def test_show_diff_specified(self):
1551.7.22 by Aaron Bentley
Changes from review
456
        """A working tree filename can be used to identify a file"""
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
457
        self.wt.rename_one('file1', 'file1b')
6973.5.2 by Jelmer Vernooij
Add more bees.
458
        old_tree = self.b.repository.revision_tree(b'rev-1')
459
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
460
        out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
461
                                 working_tree=self.wt)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
462
        self.assertContainsRe(out, b'file1\t')
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
463
1551.7.22 by Aaron Bentley
Changes from review
464
    def test_recursive_diff(self):
465
        """Children of directories are matched"""
466
        os.mkdir('dir1')
467
        os.mkdir('dir2')
468
        self.wt.add(['dir1', 'dir2'])
469
        self.wt.rename_one('file1', 'dir1/file1')
6973.5.2 by Jelmer Vernooij
Add more bees.
470
        old_tree = self.b.repository.revision_tree(b'rev-1')
471
        new_tree = self.b.repository.revision_tree(b'rev-4')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
472
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
473
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
474
        self.assertContainsRe(out, b'file1\t')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
475
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
476
                                 working_tree=self.wt)
6973.14.7 by Jelmer Vernooij
Bees bees bees.
477
        self.assertNotContainsRe(out, b'file1\t')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
478
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
479
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
480
class TestShowDiffTrees(tests.TestCaseWithTransport):
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
481
    """Direct tests for show_diff_trees"""
482
483
    def test_modified_file(self):
484
        """Test when a file is modified."""
485
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
486
        self.build_tree_contents([('tree/file', b'contents\n')])
487
        tree.add(['file'], [b'file-id'])
488
        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'
489
6855.4.1 by Jelmer Vernooij
Yet more bees.
490
        self.build_tree_contents([('tree/file', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
491
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
492
        self.assertContainsRe(d, b"=== modified file 'file'\n")
493
        self.assertContainsRe(d, b'--- old/file\t')
494
        self.assertContainsRe(d, b'\\+\\+\\+ new/file\t')
495
        self.assertContainsRe(d, b'-contents\n'
496
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
497
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
498
    def test_modified_file_in_renamed_dir(self):
499
        """Test when a file is modified in a renamed directory."""
500
        tree = self.make_branch_and_tree('tree')
501
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
502
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
503
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
504
        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
505
506
        tree.rename_one('dir', 'other')
6855.4.1 by Jelmer Vernooij
Yet more bees.
507
        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
508
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
509
        self.assertContainsRe(d, b"=== renamed directory 'dir' => 'other'\n")
510
        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
511
        # XXX: This is technically incorrect, because it used to be at another
512
        # location. What to do?
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
513
        self.assertContainsRe(d, b'--- old/dir/file\t')
514
        self.assertContainsRe(d, b'\\+\\+\\+ new/other/file\t')
515
        self.assertContainsRe(d, b'-contents\n'
516
                                 b'\\+new contents\n')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
517
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
518
    def test_renamed_directory(self):
519
        """Test when only a directory is only renamed."""
520
        tree = self.make_branch_and_tree('tree')
521
        self.build_tree(['tree/dir/'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
522
        self.build_tree_contents([('tree/dir/file', b'contents\n')])
523
        tree.add(['dir', 'dir/file'], [b'dir-id', b'file-id'])
524
        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'
525
526
        tree.rename_one('dir', 'newdir')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
527
        d = get_diff_as_string(tree.basis_tree(), tree)
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
528
        # Renaming a directory should be a single "you renamed this dir" even
529
        # when there are files inside.
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
530
        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'
531
532
    def test_renamed_file(self):
533
        """Test when a file is only renamed."""
534
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
535
        self.build_tree_contents([('tree/file', b'contents\n')])
536
        tree.add(['file'], [b'file-id'])
537
        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'
538
539
        tree.rename_one('file', 'newname')
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
540
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
541
        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'
542
        # We shouldn't have a --- or +++ line, because there is no content
543
        # change
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
544
        self.assertNotContainsRe(d, b'---')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
545
546
    def test_renamed_and_modified_file(self):
547
        """Test when a file is only renamed."""
548
        tree = self.make_branch_and_tree('tree')
6855.4.1 by Jelmer Vernooij
Yet more bees.
549
        self.build_tree_contents([('tree/file', b'contents\n')])
550
        tree.add(['file'], [b'file-id'])
551
        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'
552
553
        tree.rename_one('file', 'newname')
6855.4.1 by Jelmer Vernooij
Yet more bees.
554
        self.build_tree_contents([('tree/newname', b'new contents\n')])
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
555
        d = get_diff_as_string(tree.basis_tree(), tree)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
556
        self.assertContainsRe(d, b"=== renamed file 'file' => 'newname'\n")
557
        self.assertContainsRe(d, b'--- old/file\t')
558
        self.assertContainsRe(d, b'\\+\\+\\+ new/newname\t')
559
        self.assertContainsRe(d, b'-contents\n'
560
                                 b'\\+new contents\n')
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
561
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
562
    def test_internal_diff_exec_property(self):
563
        tree = self.make_branch_and_tree('tree')
564
7350.3.2 by Jelmer Vernooij
Use Tree.get_transform.
565
        tt = tree.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
566
        tt.new_file('a', tt.root, [b'contents\n'], b'a-id', True)
567
        tt.new_file('b', tt.root, [b'contents\n'], b'b-id', False)
568
        tt.new_file('c', tt.root, [b'contents\n'], b'c-id', True)
569
        tt.new_file('d', tt.root, [b'contents\n'], b'd-id', False)
570
        tt.new_file('e', tt.root, [b'contents\n'], b'control-e-id', True)
571
        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
572
        tt.apply()
6855.4.1 by Jelmer Vernooij
Yet more bees.
573
        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
574
7350.3.2 by Jelmer Vernooij
Use Tree.get_transform.
575
        tt = tree.get_transform()
6973.13.2 by Jelmer Vernooij
Fix some more tests.
576
        tt.set_executability(False, tt.trans_id_file_id(b'a-id'))
577
        tt.set_executability(True, tt.trans_id_file_id(b'b-id'))
578
        tt.set_executability(False, tt.trans_id_file_id(b'c-id'))
579
        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
580
        tt.apply()
581
        tree.rename_one('c', 'new-c')
582
        tree.rename_one('d', 'new-d')
583
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
584
        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
585
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
586
        self.assertContainsRe(d, br"file 'a'.*\(properties changed:"
587
                                 br".*\+x to -x.*\)")
588
        self.assertContainsRe(d, br"file 'b'.*\(properties changed:"
589
                                 br".*-x to \+x.*\)")
590
        self.assertContainsRe(d, br"file 'c'.*\(properties changed:"
591
                                 br".*\+x to -x.*\)")
592
        self.assertContainsRe(d, br"file 'd'.*\(properties changed:"
593
                                 br".*-x to \+x.*\)")
594
        self.assertNotContainsRe(d, br"file 'e'")
595
        self.assertNotContainsRe(d, br"file 'f'")
3268.1.1 by C Miller
Describe the property changes in diffs. Currently, this is the executable-bit
596
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
597
    def test_binary_unicode_filenames(self):
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
598
        """Test that contents of files are *not* encoded in UTF-8 when there
599
        is a binary file in the diff.
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
600
        """
601
        # See https://bugs.launchpad.net/bugs/110092.
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
602
        self.requireFeature(features.UnicodeFilenameFeature)
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
603
604
        tree = self.make_branch_and_tree('tree')
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
605
        alpha, omega = u'\u03b1', u'\u03c9'
606
        alpha_utf8, omega_utf8 = alpha.encode('utf8'), omega.encode('utf8')
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
607
        self.build_tree_contents(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
608
            [('tree/' + alpha, b'\0'),
2592.2.2 by Jonathan Lange
Apply jam's comments to test_binary_unicode_filenames. Change the
609
             ('tree/' + omega,
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
610
              (b'The %s and the %s\n' % (alpha_utf8, omega_utf8)))])
6855.4.1 by Jelmer Vernooij
Yet more bees.
611
        tree.add([alpha], [b'file-id'])
612
        tree.add([omega], [b'file-id-2'])
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
613
        diff_content = StubO()
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
614
        diff.show_diff_trees(tree.basis_tree(), tree, diff_content)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
615
        diff_content.check_types(self, bytes)
616
        d = b''.join(diff_content.write_record)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
617
        self.assertContainsRe(d, br"=== added file '%s'" % alpha_utf8)
618
        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.
619
                              % (alpha_utf8, alpha_utf8))
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
620
        self.assertContainsRe(d, br"=== added file '%s'" % omega_utf8)
621
        self.assertContainsRe(d, br"--- a/%s" % (omega_utf8,))
622
        self.assertContainsRe(d, br"\+\+\+ b/%s" % (omega_utf8,))
2592.2.1 by Jonathan Lange
Reproduce and fix bug 110092.
623
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
624
    def test_unicode_filename(self):
625
        """Test when the filename are unicode."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
626
        self.requireFeature(features.UnicodeFilenameFeature)
2725.2.1 by ghigo
When a unicode filename is renamed, in the diff is showed a wrong result
627
628
        alpha, omega = u'\u03b1', u'\u03c9'
629
        autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
630
631
        tree = self.make_branch_and_tree('tree')
7143.15.2 by Jelmer Vernooij
Run autopep8.
632
        self.build_tree_contents([('tree/ren_' + alpha, b'contents\n')])
633
        tree.add(['ren_' + alpha], [b'file-id-2'])
634
        self.build_tree_contents([('tree/del_' + alpha, b'contents\n')])
635
        tree.add(['del_' + alpha], [b'file-id-3'])
636
        self.build_tree_contents([('tree/mod_' + alpha, b'contents\n')])
637
        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
638
6855.4.1 by Jelmer Vernooij
Yet more bees.
639
        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
640
7143.15.2 by Jelmer Vernooij
Run autopep8.
641
        tree.rename_one('ren_' + alpha, 'ren_' + omega)
642
        tree.remove('del_' + alpha)
643
        self.build_tree_contents([('tree/add_' + alpha, b'contents\n')])
644
        tree.add(['add_' + alpha], [b'file-id'])
645
        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
646
5784.3.1 by Martin Pool
Remove unnecessary TestShowDiffTreesHelper and just use a function
647
        d = get_diff_as_string(tree.basis_tree(), tree)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
648
        self.assertContainsRe(d,
7143.15.2 by Jelmer Vernooij
Run autopep8.
649
                              b"=== renamed file 'ren_%s' => 'ren_%s'\n" % (autf8, outf8))
650
        self.assertContainsRe(d, b"=== added file 'add_%s'" % autf8)
651
        self.assertContainsRe(d, b"=== modified file 'mod_%s'" % autf8)
652
        self.assertContainsRe(d, b"=== removed file 'del_%s'" % autf8)
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
653
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
654
    def test_unicode_filename_path_encoding(self):
655
        """Test for bug #382699: unicode filenames on Windows should be shown
656
        in user encoding.
657
        """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
658
        self.requireFeature(features.UnicodeFilenameFeature)
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
659
        # The word 'test' in Russian
660
        _russian_test = u'\u0422\u0435\u0441\u0442'
661
        directory = _russian_test + u'/'
662
        test_txt = _russian_test + u'.txt'
663
        u1234 = u'\u1234.txt'
664
665
        tree = self.make_branch_and_tree('.')
666
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
667
            (test_txt, b'foo\n'),
668
            (u1234, b'foo\n'),
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
669
            (directory, None),
670
            ])
671
        tree.add([test_txt, u1234, directory])
672
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
673
        sio = BytesIO()
5258.1.1 by Alexander Belchenko
merge diff header work from my 2.1 branch
674
        diff.show_diff_trees(tree.basis_tree(), tree, sio,
7143.15.2 by Jelmer Vernooij
Run autopep8.
675
                             path_encoding='cp1251')
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
676
677
        output = subst_dates(sio.getvalue())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
678
        shouldbe = (b'''\
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
679
=== added directory '%(directory)s'
680
=== added file '%(test_txt)s'
681
--- a/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
682
+++ b/%(test_txt)s\tYYYY-MM-DD HH:MM:SS +ZZZZ
683
@@ -0,0 +1,1 @@
684
+foo
685
686
=== added file '?.txt'
687
--- a/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
688
+++ b/?.txt\tYYYY-MM-DD HH:MM:SS +ZZZZ
689
@@ -0,0 +1,1 @@
690
+foo
691
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
692
''' % {b'directory': _russian_test.encode('cp1251'),
7143.15.2 by Jelmer Vernooij
Run autopep8.
693
            b'test_txt': test_txt.encode('cp1251'),
694
       })
4797.57.6 by Alexander Belchenko
added whitebox test for path_encoding in diff.
695
        self.assertEqualDiff(output, shouldbe)
696
5168.1.4 by Vincent Ladeuil
Final import fixes for bt.test_diff.
697
698
class DiffWasIs(diff.DiffPath):
3009.2.15 by Aaron Bentley
Test differ registration
699
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
700
    def diff(self, old_path, new_path, old_kind, new_kind):
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
701
        self.to_file.write(b'was: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
702
        self.to_file.write(self.old_tree.get_file(old_path).read())
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
703
        self.to_file.write(b'is: ')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
704
        self.to_file.write(self.new_tree.get_file(new_path).read())
3009.2.15 by Aaron Bentley
Test differ registration
705
706
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
707
class TestDiffTree(tests.TestCaseWithTransport):
3009.2.9 by Aaron Bentley
Add tests for Differ
708
709
    def setUp(self):
5168.1.2 by Vincent Ladeuil
Ckeanup some more imports.
710
        super(TestDiffTree, self).setUp()
3009.2.9 by Aaron Bentley
Add tests for Differ
711
        self.old_tree = self.make_branch_and_tree('old-tree')
712
        self.old_tree.lock_write()
713
        self.addCleanup(self.old_tree.unlock)
714
        self.new_tree = self.make_branch_and_tree('new-tree')
715
        self.new_tree.lock_write()
716
        self.addCleanup(self.new_tree.unlock)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
717
        self.differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
3009.2.9 by Aaron Bentley
Add tests for Differ
718
719
    def test_diff_text(self):
720
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
721
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
722
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
723
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
724
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
725
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
726
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
727
        self.new_tree.add('newdir/newfile', b'file-id')
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
728
        differ = diff.DiffText(self.old_tree, self.new_tree, BytesIO())
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
729
        differ.diff_text('olddir/oldfile', None, 'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
730
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
731
            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
732
            differ.to_file.getvalue())
733
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
734
        differ.diff_text(None, 'newdir/newfile',
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
735
                         'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
736
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
737
            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
738
            differ.to_file.getvalue())
739
        differ.to_file.seek(0)
6809.4.9 by Jelmer Vernooij
Fix some more tests.
740
        differ.diff_text('olddir/oldfile', 'newdir/newfile',
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
741
                         'old label', 'new label')
3009.2.9 by Aaron Bentley
Add tests for Differ
742
        self.assertEqual(
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
743
            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
744
            differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
745
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
746
    def test_diff_deletion(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
747
        self.build_tree_contents([('old-tree/file', b'contents'),
748
                                  ('new-tree/file', b'contents')])
749
        self.old_tree.add('file', b'file-id')
750
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
751
        os.unlink('new-tree/file')
752
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
753
        self.assertContainsRe(self.differ.to_file.getvalue(), b'-contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
754
755
    def test_diff_creation(self):
6855.4.1 by Jelmer Vernooij
Yet more bees.
756
        self.build_tree_contents([('old-tree/file', b'contents'),
757
                                  ('new-tree/file', b'contents')])
758
        self.old_tree.add('file', b'file-id')
759
        self.new_tree.add('file', b'file-id')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
760
        os.unlink('old-tree/file')
761
        self.differ.show_diff(None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
762
        self.assertContainsRe(self.differ.to_file.getvalue(), br'\+contents')
3087.1.1 by Aaron Bentley
Diff handles missing files correctly, with no tracebacks
763
3009.2.9 by Aaron Bentley
Add tests for Differ
764
    def test_diff_symlink(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
765
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
766
        differ.diff_symlink('old target', None)
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
767
        self.assertEqual(b"=== target was 'old target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
768
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
769
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
770
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
771
        differ.diff_symlink(None, 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
772
        self.assertEqual(b"=== target is 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
773
                         differ.to_file.getvalue())
774
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
775
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, BytesIO())
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
776
        differ.diff_symlink('old target', 'new target')
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
777
        self.assertEqual(b"=== target changed 'old target' => 'new target'\n",
3009.2.11 by Aaron Bentley
Refactor diff to be more pluggable
778
                         differ.to_file.getvalue())
3009.2.9 by Aaron Bentley
Add tests for Differ
779
780
    def test_diff(self):
781
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
782
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
783
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
784
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
785
        self.build_tree_contents([('new-tree/newdir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
786
                                  ('new-tree/newdir/newfile', b'new\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
787
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
788
        self.new_tree.add('newdir/newfile', b'file-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
789
        self.differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
790
        self.assertContainsRe(
791
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
792
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
793
            br' \@\@\n-old\n\+new\n\n')
3009.2.9 by Aaron Bentley
Add tests for Differ
794
795
    def test_diff_kind_change(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
796
        self.requireFeature(features.SymlinkFeature)
3009.2.9 by Aaron Bentley
Add tests for Differ
797
        self.build_tree_contents([('old-tree/olddir/',),
6855.4.1 by Jelmer Vernooij
Yet more bees.
798
                                  ('old-tree/olddir/oldfile', b'old\n')])
3009.2.9 by Aaron Bentley
Add tests for Differ
799
        self.old_tree.add('olddir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
800
        self.old_tree.add('olddir/oldfile', b'file-id')
3009.2.9 by Aaron Bentley
Add tests for Differ
801
        self.build_tree(['new-tree/newdir/'])
802
        os.symlink('new', 'new-tree/newdir/newfile')
803
        self.new_tree.add('newdir')
6855.4.1 by Jelmer Vernooij
Yet more bees.
804
        self.new_tree.add('newdir/newfile', b'file-id')
7206.6.2 by Jelmer Vernooij
Remove file_id from diff API.
805
        self.differ.diff('olddir/oldfile', 'newdir/newfile')
3009.2.9 by Aaron Bentley
Add tests for Differ
806
        self.assertContainsRe(
807
            self.differ.to_file.getvalue(),
7031.1.1 by Jelmer Vernooij
Fix breezy.tests.test_diff.
808
            br'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+0,0'
809
            br' \@\@\n-old\n\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."""
7356.1.3 by Jelmer Vernooij
Fix tests.
1034
        exit_stack = cleanup.ExitStack()
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)