~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_patches.py

NEWS section template into a separate file

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
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
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
18
 
19
19
import os.path
21
21
from bzrlib.tests import TestCase
22
22
 
23
23
from bzrlib.iterablefile import IterableFile
24
 
from bzrlib.patches import (MalformedLine, 
25
 
                            MalformedHunkHeader, 
26
 
                            MalformedPatchHeader, 
27
 
                            ContextLine, 
 
24
from bzrlib.patches import (MalformedLine,
 
25
                            MalformedHunkHeader,
 
26
                            MalformedPatchHeader,
 
27
                            BinaryPatch,
 
28
                            BinaryFiles,
 
29
                            Patch,
 
30
                            ContextLine,
28
31
                            InsertLine,
29
 
                            RemoveLine, 
30
 
                            difference_index, 
 
32
                            RemoveLine,
 
33
                            difference_index,
31
34
                            get_patch_names,
32
 
                            hunk_from_header, 
33
 
                            iter_patched, 
 
35
                            hunk_from_header,
 
36
                            iter_patched,
 
37
                            iter_patched_from_hunks,
34
38
                            parse_line,
35
39
                            parse_patch,
36
 
                            parse_patches)
 
40
                            parse_patches,
 
41
                            NO_NL)
37
42
 
38
43
 
39
44
class PatchesTester(TestCase):
40
45
 
41
46
    def datafile(self, filename):
42
 
        data_path = os.path.join(os.path.dirname(__file__), 
 
47
        data_path = os.path.join(os.path.dirname(__file__),
43
48
                                 "test_patches_data", filename)
44
49
        return file(data_path, "rb")
45
50
 
 
51
    def data_lines(self, filename):
 
52
        datafile = self.datafile(filename)
 
53
        try:
 
54
            return datafile.readlines()
 
55
        finally:
 
56
            datafile.close()
 
57
 
46
58
    def testValidPatchHeader(self):
47
59
        """Parse a valid patch header"""
48
60
        lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')
111
123
        self.lineThing(" hello\n", ContextLine)
112
124
        self.lineThing("+hello\n", InsertLine)
113
125
        self.lineThing("-hello\n", RemoveLine)
114
 
    
 
126
 
115
127
    def testMalformedLine(self):
116
128
        """Parse invalid valid hunk lines"""
117
129
        self.makeMalformedLine("hello\n")
118
 
    
 
130
 
 
131
    def testMalformedLineNO_NL(self):
 
132
        """Parse invalid '\ No newline at end of file' in hunk lines"""
 
133
        self.makeMalformedLine(NO_NL)
 
134
 
119
135
    def compare_parsed(self, patchtext):
120
136
        lines = patchtext.splitlines(True)
121
137
        patch = parse_patch(lines.__iter__())
130
146
        patchtext = self.datafile("patchtext.patch").read()
131
147
        self.compare_parsed(patchtext)
132
148
 
 
149
    def test_parse_binary(self):
 
150
        """Test parsing a whole patch"""
 
151
        patches = parse_patches(self.data_lines("binary.patch"))
 
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]),
 
157
                                  'Binary files bar\t.* and qux\t.* differ\n')
 
158
 
 
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
 
 
168
    def test_roundtrip_binary(self):
 
169
        patchtext = ''.join(self.data_lines("binary.patch"))
 
170
        patches = parse_patches(patchtext.splitlines(True))
 
171
        self.assertEqual(patchtext, ''.join(str(p) for p in patches))
 
172
 
133
173
    def testInit(self):
134
174
        """Handle patches missing half the position, range tuple"""
135
175
        patchtext = \
173
213
            ('diff-4', 'orig-4', 'mod-4'),
174
214
            ('diff-5', 'orig-5', 'mod-5'),
175
215
            ('diff-6', 'orig-6', 'mod-6'),
 
216
            ('diff-7', 'orig-7', 'mod-7'),
176
217
        ]
177
218
        for diff, orig, mod in files:
178
219
            patch = self.datafile(diff)
187
228
                count += 1
188
229
            self.assertEqual(count, len(mod_lines))
189
230
 
 
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
 
 
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'),
 
244
            ('diff-7', 'orig-7', 'mod-7'),
 
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
 
190
259
    def testFirstLineRenumber(self):
191
260
        """Make sure we handle lines at the beginning of the hunk"""
192
261
        patch = parse_patch(self.datafile("insert_top.patch"))
227
296
        for patch in patches:
228
297
            patch_files.append((patch.oldname, patch.newname))
229
298
        self.assertEqual(patch_files, filenames)
 
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())