bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
3376.2.6
by Martin Pool
 Make PatchesTester use bzrlib TestCase base  | 
1  | 
# Copyright (C) 2004 - 2008 Aaron Bentley, Canonical Ltd
 | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
2  | 
# <aaron.bentley@utoronto.ca>
 | 
3  | 
#
 | 
|
| 
2052.3.1
by John Arbash Meinel
 Add tests to cleanup the copyright of all source files  | 
4  | 
# This program is free software; you can redistribute it and/or modify
 | 
5  | 
# it under the terms of the GNU General Public License as published by
 | 
|
6  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
7  | 
# (at your option) any later version.
 | 
|
8  | 
#
 | 
|
9  | 
# This program is distributed in the hope that it will be useful,
 | 
|
10  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
11  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
12  | 
# GNU General Public License for more details.
 | 
|
13  | 
#
 | 
|
14  | 
# You should have received a copy of the GNU General Public License
 | 
|
15  | 
# along with this program; if not, write to the Free Software
 | 
|
| 
4183.7.1
by Sabin Iacob
 update FSF mailing address  | 
16  | 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
| 
1185.82.127
by Aaron Bentley
 PEP8 updates  | 
17  | 
|
18  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
19  | 
import os.path  | 
20  | 
||
| 
3376.2.6
by Martin Pool
 Make PatchesTester use bzrlib TestCase base  | 
21  | 
from bzrlib.tests import TestCase  | 
22  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
23  | 
from bzrlib.iterablefile import IterableFile  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
24  | 
from bzrlib.patches import (MalformedLine,  | 
25  | 
MalformedHunkHeader,  | 
|
26  | 
MalformedPatchHeader,  | 
|
| 
4634.80.1
by Aaron Bentley
 Parse binary files.  | 
27  | 
BinaryPatch,  | 
| 
4634.80.3
by Aaron Bentley
 Clean up tests, test iter_patched.  | 
28  | 
BinaryFiles,  | 
| 
4634.80.1
by Aaron Bentley
 Parse binary files.  | 
29  | 
Patch,  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
30  | 
ContextLine,  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
31  | 
InsertLine,  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
32  | 
RemoveLine,  | 
33  | 
difference_index,  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
34  | 
get_patch_names,  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
35  | 
hunk_from_header,  | 
36  | 
iter_patched,  | 
|
| 
3363.18.3
by Aaron Bentley
 Add tests for iter_patched_from_hunks  | 
37  | 
iter_patched_from_hunks,  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
38  | 
parse_line,  | 
| 
2298.6.1
by Johan Dahlberg
 Fix bzrtools shelve command for removed lines beginning with "--"  | 
39  | 
parse_patch,  | 
| 
3873.1.2
by Benoît Pierre
 Add patches test for 'No newline at end of file' in the middle of hunk lines.  | 
40  | 
parse_patches,  | 
41  | 
NO_NL)  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
42  | 
|
| 
1185.82.127
by Aaron Bentley
 PEP8 updates  | 
43  | 
|
| 
3376.2.6
by Martin Pool
 Make PatchesTester use bzrlib TestCase base  | 
44  | 
class PatchesTester(TestCase):  | 
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
45  | 
|
| 
1185.82.7
by John Arbash Meinel
 Adding patches.py into bzrlib, including the tests into the test suite.  | 
46  | 
def datafile(self, filename):  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
47  | 
data_path = os.path.join(os.path.dirname(__file__),  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
48  | 
"test_patches_data", filename)  | 
| 
1185.82.7
by John Arbash Meinel
 Adding patches.py into bzrlib, including the tests into the test suite.  | 
49  | 
return file(data_path, "rb")  | 
50  | 
||
| 
4634.80.3
by Aaron Bentley
 Clean up tests, test iter_patched.  | 
51  | 
def data_lines(self, filename):  | 
52  | 
datafile = self.datafile(filename)  | 
|
53  | 
try:  | 
|
54  | 
return datafile.readlines()  | 
|
55  | 
finally:  | 
|
56  | 
datafile.close()  | 
|
57  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
58  | 
def testValidPatchHeader(self):  | 
59  | 
"""Parse a valid patch header"""  | 
|
60  | 
lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')  | 
|
61  | 
(orig, mod) = get_patch_names(lines.__iter__())  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
62  | 
self.assertEqual(orig, "orig/commands.py")  | 
63  | 
self.assertEqual(mod, "mod/dommands.py")  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
64  | 
|
65  | 
def testInvalidPatchHeader(self):  | 
|
66  | 
"""Parse an invalid patch header"""  | 
|
67  | 
lines = "-- orig/commands.py\n+++ mod/dommands.py".split('\n')  | 
|
68  | 
self.assertRaises(MalformedPatchHeader, get_patch_names,  | 
|
69  | 
lines.__iter__())  | 
|
70  | 
||
71  | 
def testValidHunkHeader(self):  | 
|
72  | 
"""Parse a valid hunk header"""  | 
|
73  | 
header = "@@ -34,11 +50,6 @@\n"  | 
|
74  | 
hunk = hunk_from_header(header);  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
75  | 
self.assertEqual(hunk.orig_pos, 34)  | 
76  | 
self.assertEqual(hunk.orig_range, 11)  | 
|
77  | 
self.assertEqual(hunk.mod_pos, 50)  | 
|
78  | 
self.assertEqual(hunk.mod_range, 6)  | 
|
79  | 
self.assertEqual(str(hunk), header)  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
80  | 
|
81  | 
def testValidHunkHeader2(self):  | 
|
82  | 
"""Parse a tricky, valid hunk header"""  | 
|
83  | 
header = "@@ -1 +0,0 @@\n"  | 
|
84  | 
hunk = hunk_from_header(header);  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
85  | 
self.assertEqual(hunk.orig_pos, 1)  | 
86  | 
self.assertEqual(hunk.orig_range, 1)  | 
|
87  | 
self.assertEqual(hunk.mod_pos, 0)  | 
|
88  | 
self.assertEqual(hunk.mod_range, 0)  | 
|
89  | 
self.assertEqual(str(hunk), header)  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
90  | 
|
| 
1551.18.6
by Aaron Bentley
 Add support for diff -p-style diffs to patch parser  | 
91  | 
def testPDiff(self):  | 
92  | 
"""Parse a hunk header produced by diff -p"""  | 
|
93  | 
header = "@@ -407,7 +292,7 @@ bzr 0.18rc1 2007-07-10\n"  | 
|
94  | 
hunk = hunk_from_header(header)  | 
|
95  | 
self.assertEqual('bzr 0.18rc1 2007-07-10', hunk.tail)  | 
|
96  | 
self.assertEqual(header, str(hunk))  | 
|
97  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
98  | 
def makeMalformed(self, header):  | 
99  | 
self.assertRaises(MalformedHunkHeader, hunk_from_header, header)  | 
|
100  | 
||
101  | 
def testInvalidHeader(self):  | 
|
102  | 
"""Parse an invalid hunk header"""  | 
|
103  | 
self.makeMalformed(" -34,11 +50,6 \n")  | 
|
104  | 
self.makeMalformed("@@ +50,6 -34,11 @@\n")  | 
|
105  | 
self.makeMalformed("@@ -34,11 +50,6 @@")  | 
|
106  | 
self.makeMalformed("@@ -34.5,11 +50,6 @@\n")  | 
|
107  | 
self.makeMalformed("@@-34,11 +50,6@@\n")  | 
|
108  | 
self.makeMalformed("@@ 34,11 50,6 @@\n")  | 
|
109  | 
self.makeMalformed("@@ -34,11 @@\n")  | 
|
110  | 
self.makeMalformed("@@ -34,11 +50,6.5 @@\n")  | 
|
111  | 
self.makeMalformed("@@ -34,11 +50,-6 @@\n")  | 
|
112  | 
||
113  | 
def lineThing(self,text, type):  | 
|
114  | 
line = parse_line(text)  | 
|
| 
3376.2.5
by Martin Pool
 Remove a few more elusive assert statements  | 
115  | 
self.assertIsInstance(line, type)  | 
116  | 
self.assertEqual(str(line), text)  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
117  | 
|
118  | 
def makeMalformedLine(self, text):  | 
|
119  | 
self.assertRaises(MalformedLine, parse_line, text)  | 
|
120  | 
||
121  | 
def testValidLine(self):  | 
|
122  | 
"""Parse a valid hunk line"""  | 
|
123  | 
self.lineThing(" hello\n", ContextLine)  | 
|
124  | 
self.lineThing("+hello\n", InsertLine)  | 
|
125  | 
self.lineThing("-hello\n", RemoveLine)  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
126  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
127  | 
def testMalformedLine(self):  | 
128  | 
"""Parse invalid valid hunk lines"""  | 
|
129  | 
self.makeMalformedLine("hello\n")  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
130  | 
|
| 
3873.1.2
by Benoît Pierre
 Add patches test for 'No newline at end of file' in the middle of hunk lines.  | 
131  | 
def testMalformedLineNO_NL(self):  | 
| 
3873.1.4
by Benoît Pierre
 Add another test for patches to check we correctly handle '\ No newline  | 
132  | 
"""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.  | 
133  | 
self.makeMalformedLine(NO_NL)  | 
134  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
135  | 
def compare_parsed(self, patchtext):  | 
136  | 
lines = patchtext.splitlines(True)  | 
|
137  | 
patch = parse_patch(lines.__iter__())  | 
|
138  | 
pstr = str(patch)  | 
|
139  | 
i = difference_index(patchtext, pstr)  | 
|
140  | 
if i is not None:  | 
|
141  | 
print "%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i])  | 
|
142  | 
self.assertEqual (patchtext, str(patch))  | 
|
143  | 
||
144  | 
def testAll(self):  | 
|
145  | 
"""Test parsing a whole patch"""  | 
|
| 
1185.82.129
by Aaron Bentley
 Removed confusing text from the test module  | 
146  | 
patchtext = self.datafile("patchtext.patch").read()  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
147  | 
self.compare_parsed(patchtext)  | 
148  | 
||
| 
4634.80.2
by Aaron Bentley
 Ensure patch roundtripping.  | 
149  | 
def test_parse_binary(self):  | 
| 
4634.80.1
by Aaron Bentley
 Parse binary files.  | 
150  | 
"""Test parsing a whole patch"""  | 
| 
4634.80.3
by Aaron Bentley
 Clean up tests, test iter_patched.  | 
151  | 
patches = parse_patches(self.data_lines("binary.patch"))  | 
| 
4634.80.1
by Aaron Bentley
 Parse binary files.  | 
152  | 
self.assertIs(BinaryPatch, patches[0].__class__)  | 
153  | 
self.assertIs(Patch, patches[1].__class__)  | 
|
154  | 
self.assertContainsRe(patches[0].oldname, '^bar\t')  | 
|
155  | 
self.assertContainsRe(patches[0].newname, '^qux\t')  | 
|
156  | 
self.assertContainsRe(str(patches[0]),  | 
|
| 
4634.80.2
by Aaron Bentley
 Ensure patch roundtripping.  | 
157  | 
'Binary files bar\t.* and qux\t.* differ\n')  | 
158  | 
||
| 
4634.98.1
by Aaron Bentley
 Improve patch binary section handling.  | 
159  | 
def test_parse_binary_after_normal(self):  | 
160  | 
patches = parse_patches(self.data_lines("binary-after-normal.patch"))  | 
|
161  | 
self.assertIs(BinaryPatch, patches[1].__class__)  | 
|
162  | 
self.assertIs(Patch, patches[0].__class__)  | 
|
163  | 
self.assertContainsRe(patches[1].oldname, '^bar\t')  | 
|
164  | 
self.assertContainsRe(patches[1].newname, '^qux\t')  | 
|
165  | 
self.assertContainsRe(str(patches[1]),  | 
|
166  | 
'Binary files bar\t.* and qux\t.* differ\n')  | 
|
167  | 
||
| 
4634.80.2
by Aaron Bentley
 Ensure patch roundtripping.  | 
168  | 
def test_roundtrip_binary(self):  | 
| 
4634.80.3
by Aaron Bentley
 Clean up tests, test iter_patched.  | 
169  | 
patchtext = ''.join(self.data_lines("binary.patch"))  | 
| 
4634.80.2
by Aaron Bentley
 Ensure patch roundtripping.  | 
170  | 
patches = parse_patches(patchtext.splitlines(True))  | 
171  | 
self.assertEqual(patchtext, ''.join(str(p) for p in patches))  | 
|
| 
4634.80.1
by Aaron Bentley
 Parse binary files.  | 
172  | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
173  | 
def testInit(self):  | 
174  | 
"""Handle patches missing half the position, range tuple"""  | 
|
175  | 
patchtext = \  | 
|
| 
1185.82.129
by Aaron Bentley
 Removed confusing text from the test module  | 
176  | 
"""--- orig/__vavg__.cl
 | 
177  | 
+++ mod/__vavg__.cl
 | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
178  | 
@@ -1 +1,2 @@
 | 
| 
1185.82.129
by Aaron Bentley
 Removed confusing text from the test module  | 
179  | 
 __qbpsbezng__ = "erfgehpgherqgrkg ra"
 | 
180  | 
+__qbp__ = Na nygreangr Nepu pbzznaqyvar vagresnpr
 | 
|
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
181  | 
"""
 | 
182  | 
self.compare_parsed(patchtext)  | 
|
183  | 
||
184  | 
def testLineLookup(self):  | 
|
185  | 
import sys  | 
|
186  | 
"""Make sure we can accurately look up mod line from orig"""  | 
|
187  | 
patch = parse_patch(self.datafile("diff"))  | 
|
188  | 
orig = list(self.datafile("orig"))  | 
|
189  | 
mod = list(self.datafile("mod"))  | 
|
190  | 
removals = []  | 
|
191  | 
for i in range(len(orig)):  | 
|
192  | 
mod_pos = patch.pos_in_mod(i)  | 
|
193  | 
if mod_pos is None:  | 
|
194  | 
removals.append(orig[i])  | 
|
195  | 
                continue
 | 
|
| 
3376.2.5
by Martin Pool
 Remove a few more elusive assert statements  | 
196  | 
self.assertEqual(mod[mod_pos], orig[i])  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
197  | 
rem_iter = removals.__iter__()  | 
198  | 
for hunk in patch.hunks:  | 
|
199  | 
for line in hunk.lines:  | 
|
200  | 
if isinstance(line, RemoveLine):  | 
|
201  | 
next = rem_iter.next()  | 
|
202  | 
if line.contents != next:  | 
|
203  | 
sys.stdout.write(" orig:%spatch:%s" % (next,  | 
|
204  | 
line.contents))  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
205  | 
self.assertEqual(line.contents, next)  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
206  | 
self.assertRaises(StopIteration, rem_iter.next)  | 
207  | 
||
208  | 
def testPatching(self):  | 
|
209  | 
"""Test a few patch files, and make sure they work."""  | 
|
210  | 
files = [  | 
|
211  | 
('diff-2', 'orig-2', 'mod-2'),  | 
|
212  | 
('diff-3', 'orig-3', 'mod-3'),  | 
|
213  | 
('diff-4', 'orig-4', 'mod-4'),  | 
|
214  | 
('diff-5', 'orig-5', 'mod-5'),  | 
|
215  | 
('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  | 
216  | 
('diff-7', 'orig-7', 'mod-7'),  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
217  | 
        ]
 | 
218  | 
for diff, orig, mod in files:  | 
|
219  | 
patch = self.datafile(diff)  | 
|
220  | 
orig_lines = list(self.datafile(orig))  | 
|
221  | 
mod_lines = list(self.datafile(mod))  | 
|
222  | 
||
223  | 
patched_file = IterableFile(iter_patched(orig_lines, patch))  | 
|
224  | 
lines = []  | 
|
225  | 
count = 0  | 
|
226  | 
for patch_line in patched_file:  | 
|
227  | 
self.assertEqual(patch_line, mod_lines[count])  | 
|
228  | 
count += 1  | 
|
229  | 
self.assertEqual(count, len(mod_lines))  | 
|
230  | 
||
| 
4634.80.3
by Aaron Bentley
 Clean up tests, test iter_patched.  | 
231  | 
def test_iter_patched_binary(self):  | 
232  | 
binary_lines = self.data_lines('binary.patch')  | 
|
233  | 
e = self.assertRaises(BinaryFiles, iter_patched, [], binary_lines)  | 
|
234  | 
||
235  | 
||
| 
3363.18.3
by Aaron Bentley
 Add tests for iter_patched_from_hunks  | 
236  | 
def test_iter_patched_from_hunks(self):  | 
237  | 
"""Test a few patch files, and make sure they work."""  | 
|
238  | 
files = [  | 
|
239  | 
('diff-2', 'orig-2', 'mod-2'),  | 
|
240  | 
('diff-3', 'orig-3', 'mod-3'),  | 
|
241  | 
('diff-4', 'orig-4', 'mod-4'),  | 
|
242  | 
('diff-5', 'orig-5', 'mod-5'),  | 
|
243  | 
('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  | 
244  | 
('diff-7', 'orig-7', 'mod-7'),  | 
| 
3363.18.3
by Aaron Bentley
 Add tests for iter_patched_from_hunks  | 
245  | 
        ]
 | 
246  | 
for diff, orig, mod in files:  | 
|
247  | 
parsed = parse_patch(self.datafile(diff))  | 
|
248  | 
orig_lines = list(self.datafile(orig))  | 
|
249  | 
mod_lines = list(self.datafile(mod))  | 
|
250  | 
iter_patched = iter_patched_from_hunks(orig_lines, parsed.hunks)  | 
|
251  | 
patched_file = IterableFile(iter_patched)  | 
|
252  | 
lines = []  | 
|
253  | 
count = 0  | 
|
254  | 
for patch_line in patched_file:  | 
|
255  | 
self.assertEqual(patch_line, mod_lines[count])  | 
|
256  | 
count += 1  | 
|
257  | 
self.assertEqual(count, len(mod_lines))  | 
|
258  | 
||
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
259  | 
def testFirstLineRenumber(self):  | 
260  | 
"""Make sure we handle lines at the beginning of the hunk"""  | 
|
261  | 
patch = parse_patch(self.datafile("insert_top.patch"))  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
262  | 
self.assertEqual(patch.pos_in_mod(0), 1)  | 
| 
1185.82.126
by Aaron Bentley
 Split the patch testing out into a separate file  | 
263  | 
|
| 
2298.6.1
by Johan Dahlberg
 Fix bzrtools shelve command for removed lines beginning with "--"  | 
264  | 
def testParsePatches(self):  | 
265  | 
"""Make sure file names can be extracted from tricky unified diffs"""  | 
|
266  | 
patchtext = \  | 
|
267  | 
"""--- orig-7
 | 
|
268  | 
+++ mod-7
 | 
|
269  | 
@@ -1,10 +1,10 @@
 | 
|
270  | 
 -- a
 | 
|
271  | 
--- b
 | 
|
272  | 
+++ c
 | 
|
273  | 
 xx d
 | 
|
274  | 
 xx e
 | 
|
275  | 
 ++ f
 | 
|
276  | 
-++ g
 | 
|
277  | 
+-- h
 | 
|
278  | 
 xx i
 | 
|
279  | 
 xx j
 | 
|
280  | 
 -- k
 | 
|
281  | 
--- l
 | 
|
282  | 
+++ m
 | 
|
283  | 
--- orig-8
 | 
|
284  | 
+++ mod-8
 | 
|
285  | 
@@ -1 +1 @@
 | 
|
286  | 
--- A
 | 
|
287  | 
+++ B
 | 
|
288  | 
@@ -1 +1 @@
 | 
|
289  | 
--- C
 | 
|
290  | 
+++ D
 | 
|
291  | 
"""
 | 
|
292  | 
filenames = [('orig-7', 'mod-7'),  | 
|
293  | 
('orig-8', 'mod-8')]  | 
|
294  | 
patches = parse_patches(patchtext.splitlines(True))  | 
|
295  | 
patch_files = []  | 
|
296  | 
for patch in patches:  | 
|
297  | 
patch_files.append((patch.oldname, patch.newname))  | 
|
| 
3376.2.4
by Martin Pool
 Remove every assert statement from bzrlib!  | 
298  | 
self.assertEqual(patch_files, filenames)  | 
| 
3946.4.1
by Tim Penhey
 Extract out the counting of the stats values.  | 
299  | 
|
300  | 
def testStatsValues(self):  | 
|
301  | 
"""Test the added, removed and hunks values for stats_values."""  | 
|
302  | 
patch = parse_patch(self.datafile("diff"))  | 
|
303  | 
self.assertEqual((299, 407, 48), patch.stats_values())  |