/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2005-2010 Aaron Bentley, Canonical Ltd
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
2
#
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
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.
12
#
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
1185.82.127 by Aaron Bentley
PEP8 updates
16
17
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
18
import os.path
19
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
20
from breezy.tests import TestCase, TestCaseWithTransport
3376.2.6 by Martin Pool
Make PatchesTester use bzrlib TestCase base
21
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
22
from breezy.iterablefile import IterableFile
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
23
from breezy.patches import (
24
    AppliedPatches,
25
    MalformedLine,
26
    MalformedHunkHeader,
27
    MalformedPatchHeader,
28
    BinaryPatch,
29
    BinaryFiles,
30
    Patch,
31
    ContextLine,
32
    InsertLine,
33
    RemoveLine,
34
    difference_index,
35
    get_patch_names,
36
    hunk_from_header,
37
    iter_patched,
38
    iter_patched_from_hunks,
39
    parse_line,
40
    parse_patch,
41
    parse_patches,
42
    NO_NL,
43
    )
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
44
1185.82.127 by Aaron Bentley
PEP8 updates
45
3376.2.6 by Martin Pool
Make PatchesTester use bzrlib TestCase base
46
class PatchesTester(TestCase):
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
47
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
48
    def datafile(self, filename):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
49
        data_path = os.path.join(os.path.dirname(__file__),
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
50
                                 "test_patches_data", filename)
6973.7.5 by Jelmer Vernooij
s/file/open.
51
        return open(data_path, "rb")
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
52
4634.80.3 by Aaron Bentley
Clean up tests, test iter_patched.
53
    def data_lines(self, filename):
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
54
        with self.datafile(filename) as datafile:
4634.80.3 by Aaron Bentley
Clean up tests, test iter_patched.
55
            return datafile.readlines()
56
5016.3.2 by Martin Pool
Add test that parse_patches(.. allow_dirty=True) works
57
    def test_parse_patches_leading_noise(self):
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
58
        # https://bugs.launchpad.net/bzr/+bug/502076
59
        # https://code.launchpad.net/~toshio/bzr/allow-dirty-patches/+merge/18854
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
60
        lines = [b"diff -pruN commands.py",
61
                 b"--- orig/commands.py",
62
                 b"+++ mod/dommands.py"]
63
        bits = list(parse_patches(iter(lines), allow_dirty=True))
5016.3.2 by Martin Pool
Add test that parse_patches(.. allow_dirty=True) works
64
6601.1.6 by Kit Randel
change of plan, don't track modified state, just preserve dirty_heads if requested in parse_patches
65
    def test_preserve_dirty_head(self):
66
        """Parse a patch containing a dirty header, and preserve lines"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
67
        lines = [b"=== added directory 'foo/bar'\n",
68
                 b"=== modified file 'orig/commands.py'\n",
69
                 b"--- orig/commands.py\n",
70
                 b"+++ mod/dommands.py\n",
71
                 b"=== modified file 'orig/another.py'\n",
72
                 b"--- orig/another.py\n",
73
                 b"+++ mod/another.py\n"]
74
        patches = list(parse_patches(
75
            lines.__iter__(), allow_dirty=True, keep_dirty=True))
6603.2.2 by Colin Watson
Use assertLength.
76
        self.assertLength(2, patches)
6601.1.6 by Kit Randel
change of plan, don't track modified state, just preserve dirty_heads if requested in parse_patches
77
        self.assertEqual(patches[0]['dirty_head'],
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
78
                         [b"=== added directory 'foo/bar'\n",
79
                          b"=== modified file 'orig/commands.py'\n"])
6601.1.6 by Kit Randel
change of plan, don't track modified state, just preserve dirty_heads if requested in parse_patches
80
        self.assertEqual(patches[0]['patch'].get_header().splitlines(True),
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
81
                         [b"--- orig/commands.py\n", b"+++ mod/dommands.py\n"])
6603.2.1 by Colin Watson
Avoid associating dirty patch headers with the previous file in the patch.
82
        self.assertEqual(patches[1]['dirty_head'],
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
83
                         [b"=== modified file 'orig/another.py'\n"])
6603.2.1 by Colin Watson
Avoid associating dirty patch headers with the previous file in the patch.
84
        self.assertEqual(patches[1]['patch'].get_header().splitlines(True),
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
85
                         [b"--- orig/another.py\n", b"+++ mod/another.py\n"])
6601.1.1 by Kit Randel
added failing test: test_parse_patches_file_modified_header
86
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
87
    def testValidPatchHeader(self):
88
        """Parse a valid patch header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
89
        lines = b"--- orig/commands.py\n+++ mod/dommands.py\n".split(b'\n')
6601.1.6 by Kit Randel
change of plan, don't track modified state, just preserve dirty_heads if requested in parse_patches
90
        (orig, mod) = get_patch_names(lines.__iter__())
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
91
        self.assertEqual(orig, b"orig/commands.py")
92
        self.assertEqual(mod, b"mod/dommands.py")
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
93
94
    def testInvalidPatchHeader(self):
95
        """Parse an invalid patch header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
96
        lines = b"-- orig/commands.py\n+++ mod/dommands.py".split(b'\n')
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
97
        self.assertRaises(MalformedPatchHeader, get_patch_names,
98
                          lines.__iter__())
99
100
    def testValidHunkHeader(self):
101
        """Parse a valid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
102
        header = b"@@ -34,11 +50,6 @@\n"
6601.1.5 by Kit Randel
linting
103
        hunk = hunk_from_header(header)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
104
        self.assertEqual(hunk.orig_pos, 34)
105
        self.assertEqual(hunk.orig_range, 11)
106
        self.assertEqual(hunk.mod_pos, 50)
107
        self.assertEqual(hunk.mod_range, 6)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
108
        self.assertEqual(hunk.as_bytes(), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
109
110
    def testValidHunkHeader2(self):
111
        """Parse a tricky, valid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
112
        header = b"@@ -1 +0,0 @@\n"
6601.1.5 by Kit Randel
linting
113
        hunk = hunk_from_header(header)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
114
        self.assertEqual(hunk.orig_pos, 1)
115
        self.assertEqual(hunk.orig_range, 1)
116
        self.assertEqual(hunk.mod_pos, 0)
117
        self.assertEqual(hunk.mod_range, 0)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
118
        self.assertEqual(hunk.as_bytes(), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
119
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
120
    def testPDiff(self):
121
        """Parse a hunk header produced by diff -p"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
122
        header = b"@@ -407,7 +292,7 @@ bzr 0.18rc1  2007-07-10\n"
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
123
        hunk = hunk_from_header(header)
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
124
        self.assertEqual(b'bzr 0.18rc1  2007-07-10', hunk.tail)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
125
        self.assertEqual(header, hunk.as_bytes())
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
126
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
127
    def makeMalformed(self, header):
128
        self.assertRaises(MalformedHunkHeader, hunk_from_header, header)
129
130
    def testInvalidHeader(self):
131
        """Parse an invalid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
132
        self.makeMalformed(b" -34,11 +50,6 \n")
133
        self.makeMalformed(b"@@ +50,6 -34,11 @@\n")
134
        self.makeMalformed(b"@@ -34,11 +50,6 @@")
135
        self.makeMalformed(b"@@ -34.5,11 +50,6 @@\n")
136
        self.makeMalformed(b"@@-34,11 +50,6@@\n")
137
        self.makeMalformed(b"@@ 34,11 50,6 @@\n")
138
        self.makeMalformed(b"@@ -34,11 @@\n")
139
        self.makeMalformed(b"@@ -34,11 +50,6.5 @@\n")
140
        self.makeMalformed(b"@@ -34,11 +50,-6 @@\n")
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
141
6601.1.5 by Kit Randel
linting
142
    def lineThing(self, text, type):
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
143
        line = parse_line(text)
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
144
        self.assertIsInstance(line, type)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
145
        self.assertEqual(line.as_bytes(), text)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
146
147
    def makeMalformedLine(self, text):
148
        self.assertRaises(MalformedLine, parse_line, text)
149
150
    def testValidLine(self):
151
        """Parse a valid hunk line"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
152
        self.lineThing(b" hello\n", ContextLine)
153
        self.lineThing(b"+hello\n", InsertLine)
154
        self.lineThing(b"-hello\n", RemoveLine)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
155
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
156
    def testMalformedLine(self):
157
        """Parse invalid valid hunk lines"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
158
        self.makeMalformedLine(b"hello\n")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
159
3873.1.2 by Benoît Pierre
Add patches test for 'No newline at end of file' in the middle of hunk lines.
160
    def testMalformedLineNO_NL(self):
6798.1.1 by Jelmer Vernooij
Properly escape backslashes.
161
        """Parse invalid '\\ No newline at end of file' in hunk lines"""
3873.1.2 by Benoît Pierre
Add patches test for 'No newline at end of file' in the middle of hunk lines.
162
        self.makeMalformedLine(NO_NL)
163
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
164
    def compare_parsed(self, patchtext):
165
        lines = patchtext.splitlines(True)
166
        patch = parse_patch(lines.__iter__())
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
167
        pstr = patch.as_bytes()
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
168
        i = difference_index(patchtext, pstr)
169
        if i is not None:
6619.3.3 by Jelmer Vernooij
Apply 2to3 print fix.
170
            print("%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i]))
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
171
        self.assertEqual(patchtext, patch.as_bytes())
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
172
173
    def testAll(self):
174
        """Test parsing a whole patch"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
175
        with self.datafile("patchtext.patch") as f:
176
            patchtext = f.read()
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
177
        self.compare_parsed(patchtext)
178
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
179
    def test_parse_binary(self):
4634.80.1 by Aaron Bentley
Parse binary files.
180
        """Test parsing a whole patch"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
181
        patches = list(parse_patches(self.data_lines("binary.patch")))
4634.80.1 by Aaron Bentley
Parse binary files.
182
        self.assertIs(BinaryPatch, patches[0].__class__)
183
        self.assertIs(Patch, patches[1].__class__)
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
184
        self.assertContainsRe(patches[0].oldname, b'^bar\t')
185
        self.assertContainsRe(patches[0].newname, b'^qux\t')
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
186
        self.assertContainsRe(patches[0].as_bytes(),
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
187
                              b'Binary files bar\t.* and qux\t.* differ\n')
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
188
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
189
    def test_parse_binary_after_normal(self):
7143.15.2 by Jelmer Vernooij
Run autopep8.
190
        patches = list(parse_patches(
191
            self.data_lines("binary-after-normal.patch")))
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
192
        self.assertIs(BinaryPatch, patches[1].__class__)
193
        self.assertIs(Patch, patches[0].__class__)
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
194
        self.assertContainsRe(patches[1].oldname, b'^bar\t')
195
        self.assertContainsRe(patches[1].newname, b'^qux\t')
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
196
        self.assertContainsRe(patches[1].as_bytes(),
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
197
                              b'Binary files bar\t.* and qux\t.* differ\n')
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
198
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
199
    def test_roundtrip_binary(self):
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
200
        patchtext = b''.join(self.data_lines("binary.patch"))
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
201
        patches = parse_patches(patchtext.splitlines(True))
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
202
        self.assertEqual(patchtext, b''.join(p.as_bytes() for p in patches))
4634.80.1 by Aaron Bentley
Parse binary files.
203
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
204
    def testInit(self):
205
        """Handle patches missing half the position, range tuple"""
206
        patchtext = \
7143.15.2 by Jelmer Vernooij
Run autopep8.
207
            b"""--- orig/__vavg__.cl
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
208
+++ mod/__vavg__.cl
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
209
@@ -1 +1,2 @@
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
210
 __qbpsbezng__ = "erfgehpgherqgrkg ra"
211
+__qbp__ = Na nygreangr Nepu pbzznaqyvar vagresnpr
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
212
"""
213
        self.compare_parsed(patchtext)
214
215
    def testLineLookup(self):
216
        """Make sure we can accurately look up mod line from orig"""
217
        patch = parse_patch(self.datafile("diff"))
218
        orig = list(self.datafile("orig"))
219
        mod = list(self.datafile("mod"))
220
        removals = []
221
        for i in range(len(orig)):
222
            mod_pos = patch.pos_in_mod(i)
223
            if mod_pos is None:
224
                removals.append(orig[i])
225
                continue
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
226
            self.assertEqual(mod[mod_pos], orig[i])
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
227
        rem_iter = removals.__iter__()
228
        for hunk in patch.hunks:
229
            for line in hunk.lines:
230
                if isinstance(line, RemoveLine):
6634.2.2 by Martin
Fix and unbogofy PatchesTester.testLineLookup
231
                    self.assertEqual(line.contents, next(rem_iter))
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
232
        self.assertRaises(StopIteration, next, rem_iter)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
233
234
    def testPatching(self):
235
        """Test a few patch files, and make sure they work."""
236
        files = [
237
            ('diff-2', 'orig-2', 'mod-2'),
238
            ('diff-3', 'orig-3', 'mod-3'),
239
            ('diff-4', 'orig-4', 'mod-4'),
240
            ('diff-5', 'orig-5', 'mod-5'),
241
            ('diff-6', 'orig-6', 'mod-6'),
3873.1.4 by Benoît Pierre
Add another test for patches to check we correctly handle '\ No newline
242
            ('diff-7', 'orig-7', 'mod-7'),
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
243
        ]
244
        for diff, orig, mod in files:
245
            patch = self.datafile(diff)
246
            orig_lines = list(self.datafile(orig))
247
            mod_lines = list(self.datafile(mod))
248
249
            patched_file = IterableFile(iter_patched(orig_lines, patch))
250
            count = 0
251
            for patch_line in patched_file:
252
                self.assertEqual(patch_line, mod_lines[count])
253
                count += 1
254
            self.assertEqual(count, len(mod_lines))
255
4634.80.3 by Aaron Bentley
Clean up tests, test iter_patched.
256
    def test_iter_patched_binary(self):
257
        binary_lines = self.data_lines('binary.patch')
258
        e = self.assertRaises(BinaryFiles, iter_patched, [], binary_lines)
259
3363.18.3 by Aaron Bentley
Add tests for iter_patched_from_hunks
260
    def test_iter_patched_from_hunks(self):
261
        """Test a few patch files, and make sure they work."""
262
        files = [
263
            ('diff-2', 'orig-2', 'mod-2'),
264
            ('diff-3', 'orig-3', 'mod-3'),
265
            ('diff-4', 'orig-4', 'mod-4'),
266
            ('diff-5', 'orig-5', 'mod-5'),
267
            ('diff-6', 'orig-6', 'mod-6'),
3873.1.4 by Benoît Pierre
Add another test for patches to check we correctly handle '\ No newline
268
            ('diff-7', 'orig-7', 'mod-7'),
3363.18.3 by Aaron Bentley
Add tests for iter_patched_from_hunks
269
        ]
270
        for diff, orig, mod in files:
271
            parsed = parse_patch(self.datafile(diff))
272
            orig_lines = list(self.datafile(orig))
273
            mod_lines = list(self.datafile(mod))
274
            iter_patched = iter_patched_from_hunks(orig_lines, parsed.hunks)
275
            patched_file = IterableFile(iter_patched)
276
            count = 0
277
            for patch_line in patched_file:
278
                self.assertEqual(patch_line, mod_lines[count])
279
                count += 1
280
            self.assertEqual(count, len(mod_lines))
281
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
282
    def testFirstLineRenumber(self):
283
        """Make sure we handle lines at the beginning of the hunk"""
284
        patch = parse_patch(self.datafile("insert_top.patch"))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
285
        self.assertEqual(patch.pos_in_mod(0), 1)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
286
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
287
    def testParsePatches(self):
288
        """Make sure file names can be extracted from tricky unified diffs"""
289
        patchtext = \
7143.15.2 by Jelmer Vernooij
Run autopep8.
290
            b"""--- orig-7
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
291
+++ mod-7
292
@@ -1,10 +1,10 @@
293
 -- a
294
--- b
295
+++ c
296
 xx d
297
 xx e
298
 ++ f
299
-++ g
300
+-- h
301
 xx i
302
 xx j
303
 -- k
304
--- l
305
+++ m
306
--- orig-8
307
+++ mod-8
308
@@ -1 +1 @@
309
--- A
310
+++ B
311
@@ -1 +1 @@
312
--- C
313
+++ D
314
"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
315
        filenames = [(b'orig-7', b'mod-7'),
316
                     (b'orig-8', b'mod-8')]
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
317
        patches = parse_patches(patchtext.splitlines(True))
318
        patch_files = []
319
        for patch in patches:
320
            patch_files.append((patch.oldname, patch.newname))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
321
        self.assertEqual(patch_files, filenames)
3946.4.1 by Tim Penhey
Extract out the counting of the stats values.
322
323
    def testStatsValues(self):
324
        """Test the added, removed and hunks values for stats_values."""
325
        patch = parse_patch(self.datafile("diff"))
326
        self.assertEqual((299, 407, 48), patch.stats_values())
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
327
328
329
class AppliedPatchesTests(TestCaseWithTransport):
330
331
    def test_apply_simple(self):
332
        tree = self.make_branch_and_tree('.')
333
        self.build_tree_contents([('a', 'a\n')])
334
        tree.add('a')
335
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
336
        patch = parse_patch(b"""\
7413.2.5 by Jelmer Vernooij
Add prefix argument.
337
--- a/a
338
+++ a/a
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
339
@@ -1 +1 @@
340
-a
341
+b
342
""".splitlines(True))
343
        with AppliedPatches(tree, [patch]) as newtree:
344
            self.assertEqual(b'b\n', newtree.get_file_text('a'))
345
346
    def test_apply_delete(self):
347
        tree = self.make_branch_and_tree('.')
348
        self.build_tree_contents([('a', 'a\n')])
349
        tree.add('a')
350
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
351
        patch = parse_patch(b"""\
7413.2.5 by Jelmer Vernooij
Add prefix argument.
352
--- a/a
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
353
+++ /dev/null
354
@@ -1 +0,0 @@
355
-a
356
""".splitlines(True))
357
        with AppliedPatches(tree, [patch]) as newtree:
358
            self.assertFalse(newtree.has_filename('a'))
359
360
    def test_apply_add(self):
361
        tree = self.make_branch_and_tree('.')
362
        self.build_tree_contents([('a', 'a\n')])
363
        tree.add('a')
364
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
365
        patch = parse_patch(b"""\
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
366
--- /dev/null
7413.2.5 by Jelmer Vernooij
Add prefix argument.
367
+++ a/b
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
368
@@ -0,0 +1 @@
369
+b
370
""".splitlines(True))
371
        with AppliedPatches(tree, [patch]) as newtree:
372
            self.assertEqual(b'b\n', newtree.get_file_text('b'))