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