/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2007, 2009, 2011 Canonical Ltd
2520.4.85 by Aaron Bentley
Get all test passing (which just proves there aren't enough tests!)
2
#
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
2520.4.85 by Aaron Bentley
Get all test passing (which just proves there aren't enough tests!)
16
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
17
import patiencediff
0.9.1 by Aaron Bentley
Get trivial case passing
18
from unittest import TestCase
19
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
20
from .. import (
2520.4.2 by Aaron Bentley
Integrate mpdiff into bazaar
21
    multiparent,
22
    tests,
23
    )
6973.7.9 by Jelmer Vernooij
Port multiparent.
24
25
26
LINES_1 = b"a\nb\nc\nd\ne\n".splitlines(True)
27
LINES_2 = b"a\nc\nd\ne\n".splitlines(True)
28
LINES_3 = b"a\nb\nc\nd\n".splitlines(True)
29
LF_SPLIT_LINES = [b'\x00\n', b'\x00\r\x01\n', b'\x02\r\xff']
0.9.2 by Aaron Bentley
Get single-parent comparison working
30
31
32
class Mock(object):
33
34
    def __init__(self, **kwargs):
35
        self.__dict__ = kwargs
36
0.9.1 by Aaron Bentley
Get trivial case passing
37
38
class TestMulti(TestCase):
39
0.9.2 by Aaron Bentley
Get single-parent comparison working
40
    def test_compare_no_parent(self):
41
        diff = multiparent.MultiParent.from_lines(LINES_1)
42
        self.assertEqual([multiparent.NewText(LINES_1)], diff.hunks)
43
44
    def test_compare_one_parent(self):
45
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2])
46
        self.assertEqual([multiparent.ParentText(0, 0, 0, 1),
6973.7.9 by Jelmer Vernooij
Port multiparent.
47
                          multiparent.NewText([b'b\n']),
0.9.2 by Aaron Bentley
Get single-parent comparison working
48
                          multiparent.ParentText(0, 1, 2, 3)],
49
                         diff.hunks)
50
2520.4.138 by Aaron Bentley
Fix benign off-by-one error generating mpdiffs
51
        diff = multiparent.MultiParent.from_lines(LINES_2, [LINES_1])
52
        self.assertEqual([multiparent.ParentText(0, 0, 0, 1),
53
                          multiparent.ParentText(0, 2, 1, 3)],
54
                         diff.hunks)
55
0.9.3 by Aaron Bentley
Get three-parent comparisions under test
56
    def test_compare_two_parents(self):
57
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2, LINES_3])
58
        self.assertEqual([multiparent.ParentText(1, 0, 0, 4),
59
                          multiparent.ParentText(0, 3, 4, 1)],
60
                         diff.hunks)
61
2520.4.41 by Aaron Bentley
Accelerate mpdiff generation
62
    def test_compare_two_parents_blocks(self):
63
        matcher = patiencediff.PatienceSequenceMatcher(None, LINES_2, LINES_1)
64
        blocks = matcher.get_matching_blocks()
65
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2, LINES_3],
66
                                                  left_blocks=blocks)
67
        self.assertEqual([multiparent.ParentText(1, 0, 0, 4),
68
                          multiparent.ParentText(0, 3, 4, 1)],
69
                         diff.hunks)
70
2520.4.139 by Aaron Bentley
Support Multiparent.get_matching_blocks
71
    def test_get_matching_blocks(self):
72
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2])
73
        self.assertEqual([(0, 0, 1), (1, 2, 3), (4, 5, 0)],
74
                         list(diff.get_matching_blocks(0, len(LINES_2))))
75
76
        diff = multiparent.MultiParent.from_lines(LINES_2, [LINES_1])
77
        self.assertEqual([(0, 0, 1), (2, 1, 3), (5, 4, 0)],
78
                         list(diff.get_matching_blocks(0, len(LINES_1))))
79
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
80
    def test_range_iterator(self):
81
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2, LINES_3])
6973.7.9 by Jelmer Vernooij
Port multiparent.
82
        diff.hunks.append(multiparent.NewText([b'q\n']))
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
83
        self.assertEqual([(0, 4, 'parent', (1, 0, 4)),
84
                          (4, 5, 'parent', (0, 3, 4)),
6973.7.9 by Jelmer Vernooij
Port multiparent.
85
                          (5, 6, 'new', [b'q\n'])],
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
86
                         list(diff.range_iterator()))
87
0.9.2 by Aaron Bentley
Get single-parent comparison working
88
    def test_eq(self):
89
        diff = multiparent.MultiParent.from_lines(LINES_1)
90
        diff2 = multiparent.MultiParent.from_lines(LINES_1)
91
        self.assertEqual(diff, diff2)
92
        diff3 = multiparent.MultiParent.from_lines(LINES_2)
93
        self.assertFalse(diff == diff3)
94
        self.assertFalse(diff == Mock(hunks=[multiparent.NewText(LINES_1)]))
95
        self.assertEqual(multiparent.MultiParent(
96
                         [multiparent.NewText(LINES_1),
97
                          multiparent.ParentText(0, 1, 2, 3)]),
98
                         multiparent.MultiParent(
99
                         [multiparent.NewText(LINES_1),
100
                          multiparent.ParentText(0, 1, 2, 3)]))
0.9.1 by Aaron Bentley
Get trivial case passing
101
0.9.4 by Aaron Bentley
Start supporting serialization
102
    def test_to_patch(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
103
        self.assertEqual([b'i 1\n', b'a\n', b'\n', b'c 0 1 2 3\n'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
104
                         list(multiparent.MultiParent([multiparent.NewText([b'a\n']),
105
                                                       multiparent.ParentText(0, 1, 2, 3)]).to_patch()))
0.9.4 by Aaron Bentley
Start supporting serialization
106
0.9.18 by Aaron Bentley
Implement from_patch
107
    def test_from_patch(self):
108
        self.assertEqual(multiparent.MultiParent(
6973.7.9 by Jelmer Vernooij
Port multiparent.
109
            [multiparent.NewText([b'a\n']),
0.9.18 by Aaron Bentley
Implement from_patch
110
             multiparent.ParentText(0, 1, 2, 3)]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
111
            multiparent.MultiParent.from_patch(b'i 1\na\n\nc 0 1 2 3'))
0.9.18 by Aaron Bentley
Implement from_patch
112
        self.assertEqual(multiparent.MultiParent(
6973.7.9 by Jelmer Vernooij
Port multiparent.
113
            [multiparent.NewText([b'a']),
0.9.18 by Aaron Bentley
Implement from_patch
114
             multiparent.ParentText(0, 1, 2, 3)]),
7143.15.2 by Jelmer Vernooij
Run autopep8.
115
            multiparent.MultiParent.from_patch(b'i 1\na\nc 0 1 2 3\n'))
2520.4.30 by Aaron Bentley
Do our own line splitting for mp-diffs
116
117
    def test_binary_content(self):
118
        patch = list(
119
            multiparent.MultiParent.from_lines(LF_SPLIT_LINES).to_patch())
6973.7.9 by Jelmer Vernooij
Port multiparent.
120
        multiparent.MultiParent.from_patch(b''.join(patch))
0.9.18 by Aaron Bentley
Implement from_patch
121
2520.4.90 by Aaron Bentley
Handle \r terminated lines in Weaves properly
122
    def test_make_patch_from_binary(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
123
        patch = multiparent.MultiParent.from_texts(b''.join(LF_SPLIT_LINES))
2520.4.92 by Aaron Bentley
fix line-splitting in MultiParent.from_texts
124
        expected = multiparent.MultiParent([
125
            multiparent.NewText(LF_SPLIT_LINES)])
126
        self.assertEqual(expected, patch)
2520.4.90 by Aaron Bentley
Handle \r terminated lines in Weaves properly
127
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
128
    def test_num_lines(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
129
        mp = multiparent.MultiParent([multiparent.NewText([b'a\n'])])
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
130
        self.assertEqual(1, mp.num_lines())
6973.7.9 by Jelmer Vernooij
Port multiparent.
131
        mp.hunks.append(multiparent.NewText([b'b\n', b'c\n']))
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
132
        self.assertEqual(3, mp.num_lines())
133
        mp.hunks.append(multiparent.ParentText(0, 0, 3, 2))
134
        self.assertEqual(5, mp.num_lines())
6973.7.9 by Jelmer Vernooij
Port multiparent.
135
        mp.hunks.append(multiparent.NewText([b'f\n', b'g\n']))
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
136
        self.assertEqual(7, mp.num_lines())
137
2520.4.103 by Aaron Bentley
Add MultiParent.to_lines
138
    def test_to_lines(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
139
        mpdiff = multiparent.MultiParent.from_texts(b'a\nb\nc\n', (b'b\nc\n',))
140
        lines = mpdiff.to_lines((b'b\ne\n',))
141
        self.assertEqual([b'a\n', b'b\n', b'e\n'], lines)
2520.4.103 by Aaron Bentley
Add MultiParent.to_lines
142
0.9.1 by Aaron Bentley
Get trivial case passing
143
144
class TestNewText(TestCase):
145
146
    def test_eq(self):
147
        self.assertEqual(multiparent.NewText([]), multiparent.NewText([]))
7143.15.2 by Jelmer Vernooij
Run autopep8.
148
        self.assertFalse(multiparent.NewText([b'a'])
149
                         == multiparent.NewText([b'b']))
6973.7.9 by Jelmer Vernooij
Port multiparent.
150
        self.assertFalse(multiparent.NewText([b'a']) == Mock(lines=[b'a']))
0.9.2 by Aaron Bentley
Get single-parent comparison working
151
0.9.4 by Aaron Bentley
Start supporting serialization
152
    def test_to_patch(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
153
        self.assertEqual([b'i 0\n', b'\n'],
0.9.4 by Aaron Bentley
Start supporting serialization
154
                         list(multiparent.NewText([]).to_patch()))
6973.7.9 by Jelmer Vernooij
Port multiparent.
155
        self.assertEqual([b'i 1\n', b'a', b'\n'],
156
                         list(multiparent.NewText([b'a']).to_patch()))
157
        self.assertEqual([b'i 1\n', b'a\n', b'\n'],
158
                         list(multiparent.NewText([b'a\n']).to_patch()))
0.9.4 by Aaron Bentley
Start supporting serialization
159
0.9.2 by Aaron Bentley
Get single-parent comparison working
160
161
class TestParentText(TestCase):
162
163
    def test_eq(self):
164
        self.assertEqual(multiparent.ParentText(1, 2, 3, 4),
165
                         multiparent.ParentText(1, 2, 3, 4))
7143.15.2 by Jelmer Vernooij
Run autopep8.
166
        self.assertFalse(multiparent.ParentText(1, 2, 3, 4)
167
                         == multiparent.ParentText(2, 2, 3, 4))
168
        self.assertFalse(multiparent.ParentText(1, 2, 3, 4)
169
                         == Mock(parent=1, parent_pos=2, child_pos=3,
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
170
                                 num_lines=4))
0.9.4 by Aaron Bentley
Start supporting serialization
171
172
    def test_to_patch(self):
6973.7.9 by Jelmer Vernooij
Port multiparent.
173
        self.assertEqual([b'c 0 1 2 3\n'],
0.9.4 by Aaron Bentley
Start supporting serialization
174
                         list(multiparent.ParentText(0, 1, 2, 3).to_patch()))
0.9.8 by Aaron Bentley
get add_version working
175
176
6973.7.9 by Jelmer Vernooij
Port multiparent.
177
REV_A = [b'a\n', b'b\n', b'c\n', b'd\n']
178
REV_B = [b'a\n', b'c\n', b'd\n', b'e\n']
179
REV_C = [b'a\n', b'b\n', b'e\n', b'f\n']
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
180
181
0.9.8 by Aaron Bentley
get add_version working
182
class TestVersionedFile(TestCase):
183
184
    def add_version(self, vf, text, version_id, parent_ids):
6973.7.9 by Jelmer Vernooij
Port multiparent.
185
        vf.add_version(
7479.2.1 by Jelmer Vernooij
Drop python2 support.
186
            [(bytes([t]) + b'\n') for t in bytearray(text)],
7143.15.2 by Jelmer Vernooij
Run autopep8.
187
            version_id, parent_ids)
0.9.8 by Aaron Bentley
get add_version working
188
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
189
    def make_vf(self):
0.9.30 by Aaron Bentley
Split into MultiVersionedFile and MultiMemoryVersionedFile
190
        vf = multiparent.MultiMemoryVersionedFile()
6973.7.9 by Jelmer Vernooij
Port multiparent.
191
        self.add_version(vf, b'abcd', b'rev-a', [])
192
        self.add_version(vf, b'acde', b'rev-b', [])
193
        self.add_version(vf, b'abef', b'rev-c', [b'rev-a', b'rev-b'])
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
194
        return vf
195
196
    def test_add_version(self):
197
        vf = self.make_vf()
6973.7.9 by Jelmer Vernooij
Port multiparent.
198
        self.assertEqual(REV_A, vf._lines[b'rev-a'])
0.9.8 by Aaron Bentley
get add_version working
199
        vf.clear_cache()
200
        self.assertEqual(vf._lines, {})
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
201
202
    def test_get_line_list(self):
203
        vf = self.make_vf()
204
        vf.clear_cache()
6973.7.9 by Jelmer Vernooij
Port multiparent.
205
        self.assertEqual(REV_A, vf.get_line_list([b'rev-a'])[0])
7143.15.2 by Jelmer Vernooij
Run autopep8.
206
        self.assertEqual(
207
            [REV_B, REV_C], vf.get_line_list([b'rev-b', b'rev-c']))
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
208
2520.4.16 by Aaron Bentley
Handle empty versions correctly
209
    def test_reconstruct_empty(self):
210
        vf = multiparent.MultiMemoryVersionedFile()
6973.7.9 by Jelmer Vernooij
Port multiparent.
211
        vf.add_version([], b'a', [])
212
        self.assertEqual([], self.reconstruct_version(vf, b'a'))
2520.4.16 by Aaron Bentley
Handle empty versions correctly
213
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
214
    @staticmethod
215
    def reconstruct(vf, revision_id, start, end):
0.9.30 by Aaron Bentley
Split into MultiVersionedFile and MultiMemoryVersionedFile
216
        reconstructor = multiparent._Reconstructor(vf, vf._lines,
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
217
                                                   vf._parents)
218
        lines = []
219
        reconstructor._reconstruct(lines, revision_id, start, end)
220
        return lines
221
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
222
    @staticmethod
223
    def reconstruct_version(vf, revision_id):
0.9.30 by Aaron Bentley
Split into MultiVersionedFile and MultiMemoryVersionedFile
224
        reconstructor = multiparent._Reconstructor(vf, vf._lines,
0.9.11 by Aaron Bentley
Implement reconstruct_version, handle all hunks through that
225
                                                   vf._parents)
226
        lines = []
227
        reconstructor.reconstruct_version(lines, revision_id)
228
        return lines
229
0.9.9 by Aaron Bentley
Much progress on non-naive text reconstruction
230
    def test_reconstructor(self):
231
        vf = self.make_vf()
7143.15.2 by Jelmer Vernooij
Run autopep8.
232
        self.assertEqual([b'a\n', b'b\n'],
233
                         self.reconstruct(vf, b'rev-a', 0, 2))
234
        self.assertEqual([b'c\n', b'd\n'],
235
                         self.reconstruct(vf, b'rev-a', 2, 4))
236
        self.assertEqual([b'e\n', b'f\n'],
237
                         self.reconstruct(vf, b'rev-c', 2, 4))
238
        self.assertEqual([b'a\n', b'b\n', b'e\n', b'f\n'],
239
                         self.reconstruct(vf, b'rev-c', 0, 4))
240
        self.assertEqual([b'a\n', b'b\n', b'e\n', b'f\n'],
241
                         self.reconstruct_version(vf, b'rev-c'))
0.9.22 by Aaron Bentley
Fix restoration bug
242
243
    def test_reordered(self):
244
        """Check for a corner case that requires re-starting the cursor"""
0.9.30 by Aaron Bentley
Split into MultiVersionedFile and MultiMemoryVersionedFile
245
        vf = multiparent.MultiMemoryVersionedFile()
0.9.22 by Aaron Bentley
Fix restoration bug
246
        # rev-b must have at least two hunks, so split a and b with c.
6973.7.9 by Jelmer Vernooij
Port multiparent.
247
        self.add_version(vf, b'c', b'rev-a', [])
248
        self.add_version(vf, b'acb', b'rev-b', [b'rev-a'])
0.9.22 by Aaron Bentley
Fix restoration bug
249
        # rev-c and rev-d must each have a line from a different rev-b hunk
6973.7.9 by Jelmer Vernooij
Port multiparent.
250
        self.add_version(vf, b'b', b'rev-c', [b'rev-b'])
251
        self.add_version(vf, b'a', b'rev-d', [b'rev-b'])
0.9.22 by Aaron Bentley
Fix restoration bug
252
        # The lines from rev-c and rev-d must appear in the opposite order
6973.7.9 by Jelmer Vernooij
Port multiparent.
253
        self.add_version(vf, b'ba', b'rev-e', [b'rev-c', b'rev-d'])
0.9.22 by Aaron Bentley
Fix restoration bug
254
        vf.clear_cache()
6973.7.9 by Jelmer Vernooij
Port multiparent.
255
        lines = vf.get_line_list([b'rev-e'])[0]
256
        self.assertEqual([b'b\n', b'a\n'], lines)
0.9.34 by Aaron Bentley
Implement save, load, snapshot-by-size
257
258
259
class TestMultiVersionedFile(tests.TestCaseInTempDir):
260
261
    def test_save_load(self):
262
        vf = multiparent.MultiVersionedFile('foop')
6973.7.9 by Jelmer Vernooij
Port multiparent.
263
        vf.add_version(b'a\nb\nc\nd'.splitlines(True), b'a', [])
264
        vf.add_version(b'a\ne\nd\n'.splitlines(True), b'b', [b'a'])
0.9.34 by Aaron Bentley
Implement save, load, snapshot-by-size
265
        vf.save()
266
        newvf = multiparent.MultiVersionedFile('foop')
267
        newvf.load()
7143.15.2 by Jelmer Vernooij
Run autopep8.
268
        self.assertEqual(b'a\nb\nc\nd', b''.join(
269
            newvf.get_line_list([b'a'])[0]))
270
        self.assertEqual(b'a\ne\nd\n', b''.join(
271
            newvf.get_line_list([b'b'])[0]))
0.9.34 by Aaron Bentley
Implement save, load, snapshot-by-size
272
273
    def test_filenames(self):
274
        vf = multiparent.MultiVersionedFile('foop')
6973.7.9 by Jelmer Vernooij
Port multiparent.
275
        vf.add_version(b'a\nb\nc\nd'.splitlines(True), b'a', [])
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
276
        self.assertPathExists('foop.mpknit')
277
        self.assertPathDoesNotExist('foop.mpidx')
0.9.34 by Aaron Bentley
Implement save, load, snapshot-by-size
278
        vf.save()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
279
        self.assertPathExists('foop.mpidx')
0.9.34 by Aaron Bentley
Implement save, load, snapshot-by-size
280
        vf.destroy()
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
281
        self.assertPathDoesNotExist('foop.mpknit')
282
        self.assertPathDoesNotExist('foop.mpidx')