/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"""
7490.160.1 by Jelmer Vernooij
Parse out patch timestamps.
89
        lines = (
90
            b"--- orig/commands.py\t2020-09-09 23:39:35 +0000\n"
91
            b"+++ mod/dommands.py\t2020-09-09 23:39:35 +0000\n").split(b'\n')
92
        (orig, mod) = get_patch_names(lines.__iter__())
93
        self.assertEqual(
94
            orig, (b"orig/commands.py", b'2020-09-09 23:39:35 +0000'))
95
        self.assertEqual(
96
            mod, (b"mod/dommands.py", b'2020-09-09 23:39:35 +0000'))
97
98
    def testValidPatchHeaderMissingTimestamps(self):
99
        """Parse a valid patch header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
100
        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
101
        (orig, mod) = get_patch_names(lines.__iter__())
7490.160.1 by Jelmer Vernooij
Parse out patch timestamps.
102
        self.assertEqual(orig, (b"orig/commands.py", None))
103
        self.assertEqual(mod, (b"mod/dommands.py", None))
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
104
105
    def testInvalidPatchHeader(self):
106
        """Parse an invalid patch header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
107
        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
108
        self.assertRaises(MalformedPatchHeader, get_patch_names,
109
                          lines.__iter__())
110
111
    def testValidHunkHeader(self):
112
        """Parse a valid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
113
        header = b"@@ -34,11 +50,6 @@\n"
6601.1.5 by Kit Randel
linting
114
        hunk = hunk_from_header(header)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
115
        self.assertEqual(hunk.orig_pos, 34)
116
        self.assertEqual(hunk.orig_range, 11)
117
        self.assertEqual(hunk.mod_pos, 50)
118
        self.assertEqual(hunk.mod_range, 6)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
119
        self.assertEqual(hunk.as_bytes(), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
120
121
    def testValidHunkHeader2(self):
122
        """Parse a tricky, valid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
123
        header = b"@@ -1 +0,0 @@\n"
6601.1.5 by Kit Randel
linting
124
        hunk = hunk_from_header(header)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
125
        self.assertEqual(hunk.orig_pos, 1)
126
        self.assertEqual(hunk.orig_range, 1)
127
        self.assertEqual(hunk.mod_pos, 0)
128
        self.assertEqual(hunk.mod_range, 0)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
129
        self.assertEqual(hunk.as_bytes(), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
130
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
131
    def testPDiff(self):
132
        """Parse a hunk header produced by diff -p"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
133
        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
134
        hunk = hunk_from_header(header)
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
135
        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__.
136
        self.assertEqual(header, hunk.as_bytes())
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
137
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
138
    def makeMalformed(self, header):
139
        self.assertRaises(MalformedHunkHeader, hunk_from_header, header)
140
141
    def testInvalidHeader(self):
142
        """Parse an invalid hunk header"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
143
        self.makeMalformed(b" -34,11 +50,6 \n")
144
        self.makeMalformed(b"@@ +50,6 -34,11 @@\n")
145
        self.makeMalformed(b"@@ -34,11 +50,6 @@")
146
        self.makeMalformed(b"@@ -34.5,11 +50,6 @@\n")
147
        self.makeMalformed(b"@@-34,11 +50,6@@\n")
148
        self.makeMalformed(b"@@ 34,11 50,6 @@\n")
149
        self.makeMalformed(b"@@ -34,11 @@\n")
150
        self.makeMalformed(b"@@ -34,11 +50,6.5 @@\n")
151
        self.makeMalformed(b"@@ -34,11 +50,-6 @@\n")
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
152
6601.1.5 by Kit Randel
linting
153
    def lineThing(self, text, type):
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
154
        line = parse_line(text)
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
155
        self.assertIsInstance(line, type)
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
156
        self.assertEqual(line.as_bytes(), text)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
157
158
    def makeMalformedLine(self, text):
159
        self.assertRaises(MalformedLine, parse_line, text)
160
161
    def testValidLine(self):
162
        """Parse a valid hunk line"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
163
        self.lineThing(b" hello\n", ContextLine)
164
        self.lineThing(b"+hello\n", InsertLine)
165
        self.lineThing(b"-hello\n", RemoveLine)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
166
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
167
    def testMalformedLine(self):
168
        """Parse invalid valid hunk lines"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
169
        self.makeMalformedLine(b"hello\n")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
170
3873.1.2 by Benoît Pierre
Add patches test for 'No newline at end of file' in the middle of hunk lines.
171
    def testMalformedLineNO_NL(self):
6798.1.1 by Jelmer Vernooij
Properly escape backslashes.
172
        """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.
173
        self.makeMalformedLine(NO_NL)
174
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
175
    def compare_parsed(self, patchtext):
176
        lines = patchtext.splitlines(True)
177
        patch = parse_patch(lines.__iter__())
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
178
        pstr = patch.as_bytes()
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
179
        i = difference_index(patchtext, pstr)
180
        if i is not None:
6619.3.3 by Jelmer Vernooij
Apply 2to3 print fix.
181
            print("%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i]))
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
182
        self.assertEqual(patchtext, patch.as_bytes())
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
183
184
    def testAll(self):
185
        """Test parsing a whole patch"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
186
        with self.datafile("patchtext.patch") as f:
187
            patchtext = f.read()
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
188
        self.compare_parsed(patchtext)
189
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
190
    def test_parse_binary(self):
4634.80.1 by Aaron Bentley
Parse binary files.
191
        """Test parsing a whole patch"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
192
        patches = list(parse_patches(self.data_lines("binary.patch")))
4634.80.1 by Aaron Bentley
Parse binary files.
193
        self.assertIs(BinaryPatch, patches[0].__class__)
194
        self.assertIs(Patch, patches[1].__class__)
7490.160.1 by Jelmer Vernooij
Parse out patch timestamps.
195
        self.assertEqual(patches[0].oldname, b'bar')
196
        self.assertEqual(patches[0].newname, b'qux')
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
197
        self.assertContainsRe(patches[0].as_bytes(),
7490.160.1 by Jelmer Vernooij
Parse out patch timestamps.
198
                              b'Binary files bar and qux differ\n')
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
199
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
200
    def test_parse_binary_after_normal(self):
7143.15.2 by Jelmer Vernooij
Run autopep8.
201
        patches = list(parse_patches(
202
            self.data_lines("binary-after-normal.patch")))
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
203
        self.assertIs(BinaryPatch, patches[1].__class__)
204
        self.assertIs(Patch, patches[0].__class__)
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
205
        self.assertContainsRe(patches[1].oldname, b'^bar\t')
206
        self.assertContainsRe(patches[1].newname, b'^qux\t')
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
207
        self.assertContainsRe(patches[1].as_bytes(),
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
208
                              b'Binary files bar\t.* and qux\t.* differ\n')
4634.98.1 by Aaron Bentley
Improve patch binary section handling.
209
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
210
    def test_roundtrip_binary(self):
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
211
        patchtext = b''.join(self.data_lines("binary.patch"))
4634.80.2 by Aaron Bentley
Ensure patch roundtripping.
212
        patches = parse_patches(patchtext.splitlines(True))
7029.1.3 by Jelmer Vernooij
Use separate .as_bytes method rather than __bytes__.
213
        self.assertEqual(patchtext, b''.join(p.as_bytes() for p in patches))
4634.80.1 by Aaron Bentley
Parse binary files.
214
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
215
    def testInit(self):
216
        """Handle patches missing half the position, range tuple"""
217
        patchtext = \
7143.15.2 by Jelmer Vernooij
Run autopep8.
218
            b"""--- orig/__vavg__.cl
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
219
+++ mod/__vavg__.cl
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
220
@@ -1 +1,2 @@
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
221
 __qbpsbezng__ = "erfgehpgherqgrkg ra"
222
+__qbp__ = Na nygreangr Nepu pbzznaqyvar vagresnpr
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
223
"""
224
        self.compare_parsed(patchtext)
225
226
    def testLineLookup(self):
227
        """Make sure we can accurately look up mod line from orig"""
228
        patch = parse_patch(self.datafile("diff"))
229
        orig = list(self.datafile("orig"))
230
        mod = list(self.datafile("mod"))
231
        removals = []
232
        for i in range(len(orig)):
233
            mod_pos = patch.pos_in_mod(i)
234
            if mod_pos is None:
235
                removals.append(orig[i])
236
                continue
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
237
            self.assertEqual(mod[mod_pos], orig[i])
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
238
        rem_iter = removals.__iter__()
239
        for hunk in patch.hunks:
240
            for line in hunk.lines:
241
                if isinstance(line, RemoveLine):
6634.2.2 by Martin
Fix and unbogofy PatchesTester.testLineLookup
242
                    self.assertEqual(line.contents, next(rem_iter))
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
243
        self.assertRaises(StopIteration, next, rem_iter)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
244
245
    def testPatching(self):
246
        """Test a few patch files, and make sure they work."""
247
        files = [
248
            ('diff-2', 'orig-2', 'mod-2'),
249
            ('diff-3', 'orig-3', 'mod-3'),
250
            ('diff-4', 'orig-4', 'mod-4'),
251
            ('diff-5', 'orig-5', 'mod-5'),
252
            ('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
253
            ('diff-7', 'orig-7', 'mod-7'),
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
254
        ]
255
        for diff, orig, mod in files:
256
            patch = self.datafile(diff)
257
            orig_lines = list(self.datafile(orig))
258
            mod_lines = list(self.datafile(mod))
259
260
            patched_file = IterableFile(iter_patched(orig_lines, patch))
261
            count = 0
262
            for patch_line in patched_file:
263
                self.assertEqual(patch_line, mod_lines[count])
264
                count += 1
265
            self.assertEqual(count, len(mod_lines))
266
4634.80.3 by Aaron Bentley
Clean up tests, test iter_patched.
267
    def test_iter_patched_binary(self):
268
        binary_lines = self.data_lines('binary.patch')
269
        e = self.assertRaises(BinaryFiles, iter_patched, [], binary_lines)
270
3363.18.3 by Aaron Bentley
Add tests for iter_patched_from_hunks
271
    def test_iter_patched_from_hunks(self):
272
        """Test a few patch files, and make sure they work."""
273
        files = [
274
            ('diff-2', 'orig-2', 'mod-2'),
275
            ('diff-3', 'orig-3', 'mod-3'),
276
            ('diff-4', 'orig-4', 'mod-4'),
277
            ('diff-5', 'orig-5', 'mod-5'),
278
            ('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
279
            ('diff-7', 'orig-7', 'mod-7'),
3363.18.3 by Aaron Bentley
Add tests for iter_patched_from_hunks
280
        ]
281
        for diff, orig, mod in files:
282
            parsed = parse_patch(self.datafile(diff))
283
            orig_lines = list(self.datafile(orig))
284
            mod_lines = list(self.datafile(mod))
285
            iter_patched = iter_patched_from_hunks(orig_lines, parsed.hunks)
286
            patched_file = IterableFile(iter_patched)
287
            count = 0
288
            for patch_line in patched_file:
289
                self.assertEqual(patch_line, mod_lines[count])
290
                count += 1
291
            self.assertEqual(count, len(mod_lines))
292
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
293
    def testFirstLineRenumber(self):
294
        """Make sure we handle lines at the beginning of the hunk"""
295
        patch = parse_patch(self.datafile("insert_top.patch"))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
296
        self.assertEqual(patch.pos_in_mod(0), 1)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
297
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
298
    def testParsePatches(self):
299
        """Make sure file names can be extracted from tricky unified diffs"""
300
        patchtext = \
7143.15.2 by Jelmer Vernooij
Run autopep8.
301
            b"""--- orig-7
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
302
+++ mod-7
303
@@ -1,10 +1,10 @@
304
 -- a
305
--- b
306
+++ c
307
 xx d
308
 xx e
309
 ++ f
310
-++ g
311
+-- h
312
 xx i
313
 xx j
314
 -- k
315
--- l
316
+++ m
317
--- orig-8
318
+++ mod-8
319
@@ -1 +1 @@
320
--- A
321
+++ B
322
@@ -1 +1 @@
323
--- C
324
+++ D
325
"""
7029.1.1 by Jelmer Vernooij
Port breezy.patches to Python3.
326
        filenames = [(b'orig-7', b'mod-7'),
327
                     (b'orig-8', b'mod-8')]
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
328
        patches = parse_patches(patchtext.splitlines(True))
329
        patch_files = []
330
        for patch in patches:
331
            patch_files.append((patch.oldname, patch.newname))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
332
        self.assertEqual(patch_files, filenames)
3946.4.1 by Tim Penhey
Extract out the counting of the stats values.
333
334
    def testStatsValues(self):
335
        """Test the added, removed and hunks values for stats_values."""
336
        patch = parse_patch(self.datafile("diff"))
337
        self.assertEqual((299, 407, 48), patch.stats_values())
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
338
339
340
class AppliedPatchesTests(TestCaseWithTransport):
341
342
    def test_apply_simple(self):
343
        tree = self.make_branch_and_tree('.')
344
        self.build_tree_contents([('a', 'a\n')])
345
        tree.add('a')
346
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
347
        patch = parse_patch(b"""\
7413.2.5 by Jelmer Vernooij
Add prefix argument.
348
--- a/a
349
+++ a/a
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
350
@@ -1 +1 @@
351
-a
352
+b
353
""".splitlines(True))
354
        with AppliedPatches(tree, [patch]) as newtree:
355
            self.assertEqual(b'b\n', newtree.get_file_text('a'))
356
357
    def test_apply_delete(self):
358
        tree = self.make_branch_and_tree('.')
359
        self.build_tree_contents([('a', 'a\n')])
360
        tree.add('a')
361
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
362
        patch = parse_patch(b"""\
7413.2.5 by Jelmer Vernooij
Add prefix argument.
363
--- a/a
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
364
+++ /dev/null
365
@@ -1 +0,0 @@
366
-a
367
""".splitlines(True))
368
        with AppliedPatches(tree, [patch]) as newtree:
369
            self.assertFalse(newtree.has_filename('a'))
370
371
    def test_apply_add(self):
372
        tree = self.make_branch_and_tree('.')
373
        self.build_tree_contents([('a', 'a\n')])
374
        tree.add('a')
375
        tree.commit('Add a')
7413.2.6 by Jelmer Vernooij
Python3 compatibility.
376
        patch = parse_patch(b"""\
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
377
--- /dev/null
7413.2.5 by Jelmer Vernooij
Add prefix argument.
378
+++ a/b
7413.2.4 by Jelmer Vernooij
Add AppliedPatches context manager.
379
@@ -0,0 +1 @@
380
+b
381
""".splitlines(True))
382
        with AppliedPatches(tree, [patch]) as newtree:
383
            self.assertEqual(b'b\n', newtree.get_file_text('b'))