~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_patches.py

Fix up inter_changes with dirstate both C and python.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Aaron Bentley, Canonical Ltd
 
1
# Copyright (C) 2004 - 2008 Aaron Bentley, Canonical Ltd
 
2
# <aaron.bentley@utoronto.ca>
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
12
13
#
13
14
# You should have received a copy of the GNU General Public License
14
15
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
 
17
18
 
18
19
import os.path
20
21
from bzrlib.tests import TestCase
21
22
 
22
23
from bzrlib.iterablefile import IterableFile
23
 
from bzrlib.patches import (MalformedLine,
24
 
                            MalformedHunkHeader,
25
 
                            MalformedPatchHeader,
26
 
                            BinaryPatch,
27
 
                            BinaryFiles,
28
 
                            Patch,
29
 
                            ContextLine,
 
24
from bzrlib.patches import (MalformedLine, 
 
25
                            MalformedHunkHeader, 
 
26
                            MalformedPatchHeader, 
 
27
                            ContextLine, 
30
28
                            InsertLine,
31
 
                            RemoveLine,
32
 
                            difference_index,
 
29
                            RemoveLine, 
 
30
                            difference_index, 
33
31
                            get_patch_names,
34
 
                            hunk_from_header,
35
 
                            iter_patched,
36
 
                            iter_patched_from_hunks,
 
32
                            hunk_from_header, 
 
33
                            iter_patched, 
37
34
                            parse_line,
38
35
                            parse_patch,
39
 
                            parse_patches,
40
 
                            NO_NL)
 
36
                            parse_patches)
41
37
 
42
38
 
43
39
class PatchesTester(TestCase):
44
40
 
45
41
    def datafile(self, filename):
46
 
        data_path = os.path.join(os.path.dirname(__file__),
 
42
        data_path = os.path.join(os.path.dirname(__file__), 
47
43
                                 "test_patches_data", filename)
48
44
        return file(data_path, "rb")
49
45
 
50
 
    def data_lines(self, filename):
51
 
        datafile = self.datafile(filename)
52
 
        try:
53
 
            return datafile.readlines()
54
 
        finally:
55
 
            datafile.close()
56
 
 
57
 
    def test_parse_patches_leading_noise(self):
58
 
        # https://bugs.launchpad.net/bzr/+bug/502076
59
 
        # https://code.launchpad.net/~toshio/bzr/allow-dirty-patches/+merge/18854
60
 
        lines = ["diff -pruN commands.py",
61
 
            "--- orig/commands.py",
62
 
            "+++ mod/dommands.py"]
63
 
        bits = parse_patches(iter(lines), allow_dirty=True)
64
 
 
65
46
    def testValidPatchHeader(self):
66
47
        """Parse a valid patch header"""
67
48
        lines = "--- orig/commands.py\n+++ mod/dommands.py\n".split('\n')
130
111
        self.lineThing(" hello\n", ContextLine)
131
112
        self.lineThing("+hello\n", InsertLine)
132
113
        self.lineThing("-hello\n", RemoveLine)
133
 
 
 
114
    
134
115
    def testMalformedLine(self):
135
116
        """Parse invalid valid hunk lines"""
136
117
        self.makeMalformedLine("hello\n")
137
 
 
138
 
    def testMalformedLineNO_NL(self):
139
 
        """Parse invalid '\ No newline at end of file' in hunk lines"""
140
 
        self.makeMalformedLine(NO_NL)
141
 
 
 
118
    
142
119
    def compare_parsed(self, patchtext):
143
120
        lines = patchtext.splitlines(True)
144
121
        patch = parse_patch(lines.__iter__())
153
130
        patchtext = self.datafile("patchtext.patch").read()
154
131
        self.compare_parsed(patchtext)
155
132
 
156
 
    def test_parse_binary(self):
157
 
        """Test parsing a whole patch"""
158
 
        patches = parse_patches(self.data_lines("binary.patch"))
159
 
        self.assertIs(BinaryPatch, patches[0].__class__)
160
 
        self.assertIs(Patch, patches[1].__class__)
161
 
        self.assertContainsRe(patches[0].oldname, '^bar\t')
162
 
        self.assertContainsRe(patches[0].newname, '^qux\t')
163
 
        self.assertContainsRe(str(patches[0]),
164
 
                                  'Binary files bar\t.* and qux\t.* differ\n')
165
 
 
166
 
    def test_parse_binary_after_normal(self):
167
 
        patches = parse_patches(self.data_lines("binary-after-normal.patch"))
168
 
        self.assertIs(BinaryPatch, patches[1].__class__)
169
 
        self.assertIs(Patch, patches[0].__class__)
170
 
        self.assertContainsRe(patches[1].oldname, '^bar\t')
171
 
        self.assertContainsRe(patches[1].newname, '^qux\t')
172
 
        self.assertContainsRe(str(patches[1]),
173
 
                                  'Binary files bar\t.* and qux\t.* differ\n')
174
 
 
175
 
    def test_roundtrip_binary(self):
176
 
        patchtext = ''.join(self.data_lines("binary.patch"))
177
 
        patches = parse_patches(patchtext.splitlines(True))
178
 
        self.assertEqual(patchtext, ''.join(str(p) for p in patches))
179
 
 
180
133
    def testInit(self):
181
134
        """Handle patches missing half the position, range tuple"""
182
135
        patchtext = \
220
173
            ('diff-4', 'orig-4', 'mod-4'),
221
174
            ('diff-5', 'orig-5', 'mod-5'),
222
175
            ('diff-6', 'orig-6', 'mod-6'),
223
 
            ('diff-7', 'orig-7', 'mod-7'),
224
176
        ]
225
177
        for diff, orig, mod in files:
226
178
            patch = self.datafile(diff)
235
187
                count += 1
236
188
            self.assertEqual(count, len(mod_lines))
237
189
 
238
 
    def test_iter_patched_binary(self):
239
 
        binary_lines = self.data_lines('binary.patch')
240
 
        e = self.assertRaises(BinaryFiles, iter_patched, [], binary_lines)
241
 
 
242
 
 
243
 
    def test_iter_patched_from_hunks(self):
244
 
        """Test a few patch files, and make sure they work."""
245
 
        files = [
246
 
            ('diff-2', 'orig-2', 'mod-2'),
247
 
            ('diff-3', 'orig-3', 'mod-3'),
248
 
            ('diff-4', 'orig-4', 'mod-4'),
249
 
            ('diff-5', 'orig-5', 'mod-5'),
250
 
            ('diff-6', 'orig-6', 'mod-6'),
251
 
            ('diff-7', 'orig-7', 'mod-7'),
252
 
        ]
253
 
        for diff, orig, mod in files:
254
 
            parsed = parse_patch(self.datafile(diff))
255
 
            orig_lines = list(self.datafile(orig))
256
 
            mod_lines = list(self.datafile(mod))
257
 
            iter_patched = iter_patched_from_hunks(orig_lines, parsed.hunks)
258
 
            patched_file = IterableFile(iter_patched)
259
 
            lines = []
260
 
            count = 0
261
 
            for patch_line in patched_file:
262
 
                self.assertEqual(patch_line, mod_lines[count])
263
 
                count += 1
264
 
            self.assertEqual(count, len(mod_lines))
265
 
 
266
190
    def testFirstLineRenumber(self):
267
191
        """Make sure we handle lines at the beginning of the hunk"""
268
192
        patch = parse_patch(self.datafile("insert_top.patch"))
303
227
        for patch in patches:
304
228
            patch_files.append((patch.oldname, patch.newname))
305
229
        self.assertEqual(patch_files, filenames)
306
 
 
307
 
    def testStatsValues(self):
308
 
        """Test the added, removed and hunks values for stats_values."""
309
 
        patch = parse_patch(self.datafile("diff"))
310
 
        self.assertEqual((299, 407, 48), patch.stats_values())