~bzr-pqm/bzr/bzr.dev

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
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
24
from bzrlib.patches import (MalformedLine, 
25
                            MalformedHunkHeader, 
26
                            MalformedPatchHeader, 
27
                            ContextLine, 
28
                            InsertLine,
29
                            RemoveLine, 
30
                            difference_index, 
31
                            get_patch_names,
32
                            hunk_from_header, 
33
                            iter_patched, 
34
                            parse_line,
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
35
                            parse_patch,
36
                            parse_patches)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
37
1185.82.127 by Aaron Bentley
PEP8 updates
38
3376.2.6 by Martin Pool
Make PatchesTester use bzrlib TestCase base
39
class PatchesTester(TestCase):
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
40
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
41
    def datafile(self, filename):
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
42
        data_path = os.path.join(os.path.dirname(__file__), 
43
                                 "test_patches_data", filename)
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
44
        return file(data_path, "rb")
45
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
46
    def testValidPatchHeader(self):
47
        """Parse a valid patch header"""
48
        lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')
49
        (orig, mod) = get_patch_names(lines.__iter__())
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
50
        self.assertEqual(orig, "orig/commands.py")
51
        self.assertEqual(mod, "mod/dommands.py")
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
52
53
    def testInvalidPatchHeader(self):
54
        """Parse an invalid patch header"""
55
        lines = "-- orig/commands.py\n+++ mod/dommands.py".split('\n')
56
        self.assertRaises(MalformedPatchHeader, get_patch_names,
57
                          lines.__iter__())
58
59
    def testValidHunkHeader(self):
60
        """Parse a valid hunk header"""
61
        header = "@@ -34,11 +50,6 @@\n"
62
        hunk = hunk_from_header(header);
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
63
        self.assertEqual(hunk.orig_pos, 34)
64
        self.assertEqual(hunk.orig_range, 11)
65
        self.assertEqual(hunk.mod_pos, 50)
66
        self.assertEqual(hunk.mod_range, 6)
67
        self.assertEqual(str(hunk), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
68
69
    def testValidHunkHeader2(self):
70
        """Parse a tricky, valid hunk header"""
71
        header = "@@ -1 +0,0 @@\n"
72
        hunk = hunk_from_header(header);
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
73
        self.assertEqual(hunk.orig_pos, 1)
74
        self.assertEqual(hunk.orig_range, 1)
75
        self.assertEqual(hunk.mod_pos, 0)
76
        self.assertEqual(hunk.mod_range, 0)
77
        self.assertEqual(str(hunk), header)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
78
1551.18.6 by Aaron Bentley
Add support for diff -p-style diffs to patch parser
79
    def testPDiff(self):
80
        """Parse a hunk header produced by diff -p"""
81
        header = "@@ -407,7 +292,7 @@ bzr 0.18rc1  2007-07-10\n"
82
        hunk = hunk_from_header(header)
83
        self.assertEqual('bzr 0.18rc1  2007-07-10', hunk.tail)
84
        self.assertEqual(header, str(hunk))
85
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
86
    def makeMalformed(self, header):
87
        self.assertRaises(MalformedHunkHeader, hunk_from_header, header)
88
89
    def testInvalidHeader(self):
90
        """Parse an invalid hunk header"""
91
        self.makeMalformed(" -34,11 +50,6 \n")
92
        self.makeMalformed("@@ +50,6 -34,11 @@\n")
93
        self.makeMalformed("@@ -34,11 +50,6 @@")
94
        self.makeMalformed("@@ -34.5,11 +50,6 @@\n")
95
        self.makeMalformed("@@-34,11 +50,6@@\n")
96
        self.makeMalformed("@@ 34,11 50,6 @@\n")
97
        self.makeMalformed("@@ -34,11 @@\n")
98
        self.makeMalformed("@@ -34,11 +50,6.5 @@\n")
99
        self.makeMalformed("@@ -34,11 +50,-6 @@\n")
100
101
    def lineThing(self,text, type):
102
        line = parse_line(text)
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
103
        self.assertIsInstance(line, type)
104
        self.assertEqual(str(line), text)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
105
106
    def makeMalformedLine(self, text):
107
        self.assertRaises(MalformedLine, parse_line, text)
108
109
    def testValidLine(self):
110
        """Parse a valid hunk line"""
111
        self.lineThing(" hello\n", ContextLine)
112
        self.lineThing("+hello\n", InsertLine)
113
        self.lineThing("-hello\n", RemoveLine)
114
    
115
    def testMalformedLine(self):
116
        """Parse invalid valid hunk lines"""
117
        self.makeMalformedLine("hello\n")
118
    
119
    def compare_parsed(self, patchtext):
120
        lines = patchtext.splitlines(True)
121
        patch = parse_patch(lines.__iter__())
122
        pstr = str(patch)
123
        i = difference_index(patchtext, pstr)
124
        if i is not None:
125
            print "%i: \"%s\" != \"%s\"" % (i, patchtext[i], pstr[i])
126
        self.assertEqual (patchtext, str(patch))
127
128
    def testAll(self):
129
        """Test parsing a whole patch"""
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
130
        patchtext = self.datafile("patchtext.patch").read()
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
131
        self.compare_parsed(patchtext)
132
133
    def testInit(self):
134
        """Handle patches missing half the position, range tuple"""
135
        patchtext = \
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
136
"""--- orig/__vavg__.cl
137
+++ mod/__vavg__.cl
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
138
@@ -1 +1,2 @@
1185.82.129 by Aaron Bentley
Removed confusing text from the test module
139
 __qbpsbezng__ = "erfgehpgherqgrkg ra"
140
+__qbp__ = Na nygreangr Nepu pbzznaqyvar vagresnpr
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
141
"""
142
        self.compare_parsed(patchtext)
143
144
    def testLineLookup(self):
145
        import sys
146
        """Make sure we can accurately look up mod line from orig"""
147
        patch = parse_patch(self.datafile("diff"))
148
        orig = list(self.datafile("orig"))
149
        mod = list(self.datafile("mod"))
150
        removals = []
151
        for i in range(len(orig)):
152
            mod_pos = patch.pos_in_mod(i)
153
            if mod_pos is None:
154
                removals.append(orig[i])
155
                continue
3376.2.5 by Martin Pool
Remove a few more elusive assert statements
156
            self.assertEqual(mod[mod_pos], orig[i])
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
157
        rem_iter = removals.__iter__()
158
        for hunk in patch.hunks:
159
            for line in hunk.lines:
160
                if isinstance(line, RemoveLine):
161
                    next = rem_iter.next()
162
                    if line.contents != next:
163
                        sys.stdout.write(" orig:%spatch:%s" % (next,
164
                                         line.contents))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
165
                    self.assertEqual(line.contents, next)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
166
        self.assertRaises(StopIteration, rem_iter.next)
167
168
    def testPatching(self):
169
        """Test a few patch files, and make sure they work."""
170
        files = [
171
            ('diff-2', 'orig-2', 'mod-2'),
172
            ('diff-3', 'orig-3', 'mod-3'),
173
            ('diff-4', 'orig-4', 'mod-4'),
174
            ('diff-5', 'orig-5', 'mod-5'),
175
            ('diff-6', 'orig-6', 'mod-6'),
176
        ]
177
        for diff, orig, mod in files:
178
            patch = self.datafile(diff)
179
            orig_lines = list(self.datafile(orig))
180
            mod_lines = list(self.datafile(mod))
181
182
            patched_file = IterableFile(iter_patched(orig_lines, patch))
183
            lines = []
184
            count = 0
185
            for patch_line in patched_file:
186
                self.assertEqual(patch_line, mod_lines[count])
187
                count += 1
188
            self.assertEqual(count, len(mod_lines))
189
190
    def testFirstLineRenumber(self):
191
        """Make sure we handle lines at the beginning of the hunk"""
192
        patch = parse_patch(self.datafile("insert_top.patch"))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
193
        self.assertEqual(patch.pos_in_mod(0), 1)
1185.82.126 by Aaron Bentley
Split the patch testing out into a separate file
194
2298.6.1 by Johan Dahlberg
Fix bzrtools shelve command for removed lines beginning with "--"
195
    def testParsePatches(self):
196
        """Make sure file names can be extracted from tricky unified diffs"""
197
        patchtext = \
198
"""--- orig-7
199
+++ mod-7
200
@@ -1,10 +1,10 @@
201
 -- a
202
--- b
203
+++ c
204
 xx d
205
 xx e
206
 ++ f
207
-++ g
208
+-- h
209
 xx i
210
 xx j
211
 -- k
212
--- l
213
+++ m
214
--- orig-8
215
+++ mod-8
216
@@ -1 +1 @@
217
--- A
218
+++ B
219
@@ -1 +1 @@
220
--- C
221
+++ D
222
"""
223
        filenames = [('orig-7', 'mod-7'),
224
                     ('orig-8', 'mod-8')]
225
        patches = parse_patches(patchtext.splitlines(True))
226
        patch_files = []
227
        for patch in patches:
228
            patch_files.append((patch.oldname, patch.newname))
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
229
        self.assertEqual(patch_files, filenames)