/brz/remove-bazaar

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