/brz/remove-bazaar

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