/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_multiparent.py

  • Committer: Michael Ellerman
  • Date: 2006-05-31 08:44:29 UTC
  • mto: (1711.2.63 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1792.
  • Revision ID: michael@ellerman.id.au-20060531084429-35e5429abda9f560
Add optional location to ancestry and fix behaviour for checkouts.

This adds an optional location parameter to the ancestry command. It also
changes the behaviour of ancestry on checkouts such that if they have
been created with a subset of the branch history, only the subset is
shown by 'bzr ancestry'. Tests for all of that as well.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
from unittest import TestCase
18
 
 
19
 
from bzrlib import (
20
 
    knit,
21
 
    multiparent,
22
 
    patiencediff,
23
 
    tests,
24
 
    )
25
 
 
26
 
 
27
 
LINES_1 = "a\nb\nc\nd\ne\n".splitlines(True)
28
 
LINES_2 = "a\nc\nd\ne\n".splitlines(True)
29
 
LINES_3 = "a\nb\nc\nd\n".splitlines(True)
30
 
LF_SPLIT_LINES = ['\x00\n', '\x00\r\x01\n', '\x02\r\xff']
31
 
 
32
 
 
33
 
class Mock(object):
34
 
 
35
 
    def __init__(self, **kwargs):
36
 
        self.__dict__ = kwargs
37
 
 
38
 
 
39
 
class TestMulti(TestCase):
40
 
 
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
 
 
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
 
 
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
 
 
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
 
 
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
 
 
81
 
    def test_range_iterator(self):
82
 
        diff = multiparent.MultiParent.from_lines(LINES_1, [LINES_2, LINES_3])
83
 
        diff.hunks.append(multiparent.NewText(['q\n']))
84
 
        self.assertEqual([(0, 4, 'parent', (1, 0, 4)),
85
 
                          (4, 5, 'parent', (0, 3, 4)),
86
 
                          (5, 6, 'new', ['q\n'])],
87
 
                         list(diff.range_iterator()))
88
 
 
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)]))
102
 
 
103
 
    def test_to_patch(self):
104
 
        self.assertEqual(['i 1\n', 'a\n', '\n', 'c 0 1 2 3\n'],
105
 
            list(multiparent.MultiParent([multiparent.NewText(['a\n']),
106
 
            multiparent.ParentText(0, 1, 2, 3)]).to_patch()))
107
 
 
108
 
    def test_from_patch(self):
109
 
        self.assertEqual(multiparent.MultiParent(
110
 
            [multiparent.NewText(['a\n']),
111
 
             multiparent.ParentText(0, 1, 2, 3)]),
112
 
             multiparent.MultiParent.from_patch('i 1\na\n\nc 0 1 2 3'))
113
 
        self.assertEqual(multiparent.MultiParent(
114
 
            [multiparent.NewText(['a']),
115
 
             multiparent.ParentText(0, 1, 2, 3)]),
116
 
             multiparent.MultiParent.from_patch('i 1\na\nc 0 1 2 3\n'))
117
 
 
118
 
    def test_binary_content(self):
119
 
        patch = list(
120
 
            multiparent.MultiParent.from_lines(LF_SPLIT_LINES).to_patch())
121
 
        multiparent.MultiParent.from_patch(''.join(patch))
122
 
 
123
 
    def test_make_patch_from_binary(self):
124
 
        patch = multiparent.MultiParent.from_texts(''.join(LF_SPLIT_LINES))
125
 
        expected = multiparent.MultiParent([
126
 
            multiparent.NewText(LF_SPLIT_LINES)])
127
 
        self.assertEqual(expected, patch)
128
 
 
129
 
    def test_num_lines(self):
130
 
        mp = multiparent.MultiParent([multiparent.NewText(['a\n'])])
131
 
        self.assertEqual(1, mp.num_lines())
132
 
        mp.hunks.append(multiparent.NewText(['b\n', 'c\n']))
133
 
        self.assertEqual(3, mp.num_lines())
134
 
        mp.hunks.append(multiparent.ParentText(0, 0, 3, 2))
135
 
        self.assertEqual(5, mp.num_lines())
136
 
        mp.hunks.append(multiparent.NewText(['f\n', 'g\n']))
137
 
        self.assertEqual(7, mp.num_lines())
138
 
 
139
 
    def test_to_lines(self):
140
 
        mpdiff = multiparent.MultiParent.from_texts('a\nb\nc\n', ('b\nc\n',))
141
 
        lines = mpdiff.to_lines(('b\ne\n',))
142
 
        self.assertEqual(['a\n', 'b\n', 'e\n'], lines)
143
 
 
144
 
 
145
 
class TestNewText(TestCase):
146
 
 
147
 
    def test_eq(self):
148
 
        self.assertEqual(multiparent.NewText([]), multiparent.NewText([]))
149
 
        self.assertFalse(multiparent.NewText(['a']) ==
150
 
                         multiparent.NewText(['b']))
151
 
        self.assertFalse(multiparent.NewText(['a']) == Mock(lines=['a']))
152
 
 
153
 
    def test_to_patch(self):
154
 
        self.assertEqual(['i 0\n', '\n'],
155
 
                         list(multiparent.NewText([]).to_patch()))
156
 
        self.assertEqual(['i 1\n', 'a', '\n'],
157
 
                         list(multiparent.NewText(['a']).to_patch()))
158
 
        self.assertEqual(['i 1\n', 'a\n', '\n'],
159
 
                         list(multiparent.NewText(['a\n']).to_patch()))
160
 
 
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))
172
 
 
173
 
    def test_to_patch(self):
174
 
        self.assertEqual(['c 0 1 2 3\n'],
175
 
                         list(multiparent.ParentText(0, 1, 2, 3).to_patch()))
176
 
 
177
 
 
178
 
REV_A = ['a\n', 'b\n', 'c\n', 'd\n']
179
 
REV_B = ['a\n', 'c\n', 'd\n', 'e\n']
180
 
REV_C = ['a\n', 'b\n', 'e\n', 'f\n']
181
 
 
182
 
 
183
 
class TestVersionedFile(TestCase):
184
 
 
185
 
    def add_version(self, vf, text, version_id, parent_ids):
186
 
        vf.add_version([(t+'\n') for t in text], version_id, parent_ids)
187
 
 
188
 
    def make_vf(self):
189
 
        vf = multiparent.MultiMemoryVersionedFile()
190
 
        self.add_version(vf, 'abcd', 'rev-a', [])
191
 
        self.add_version(vf, 'acde', 'rev-b', [])
192
 
        self.add_version(vf, 'abef', 'rev-c', ['rev-a', 'rev-b'])
193
 
        return vf
194
 
 
195
 
    def test_add_version(self):
196
 
        vf = self.make_vf()
197
 
        self.assertEqual(REV_A, vf._lines['rev-a'])
198
 
        vf.clear_cache()
199
 
        self.assertEqual(vf._lines, {})
200
 
 
201
 
    def test_get_line_list(self):
202
 
        vf = self.make_vf()
203
 
        vf.clear_cache()
204
 
        self.assertEqual(REV_A, vf.get_line_list(['rev-a'])[0])
205
 
        self.assertEqual([REV_B, REV_C], vf.get_line_list(['rev-b', 'rev-c']))
206
 
 
207
 
    def test_reconstruct_empty(self):
208
 
        vf = multiparent.MultiMemoryVersionedFile()
209
 
        vf.add_version([], 'a', [])
210
 
        self.assertEqual([], self.reconstruct_version(vf, 'a'))
211
 
 
212
 
    @staticmethod
213
 
    def reconstruct(vf, revision_id, start, end):
214
 
        reconstructor = multiparent._Reconstructor(vf, vf._lines,
215
 
                                                   vf._parents)
216
 
        lines = []
217
 
        reconstructor._reconstruct(lines, revision_id, start, end)
218
 
        return lines
219
 
 
220
 
    @staticmethod
221
 
    def reconstruct_version(vf, revision_id):
222
 
        reconstructor = multiparent._Reconstructor(vf, vf._lines,
223
 
                                                   vf._parents)
224
 
        lines = []
225
 
        reconstructor.reconstruct_version(lines, revision_id)
226
 
        return lines
227
 
 
228
 
    def test_reconstructor(self):
229
 
        vf = self.make_vf()
230
 
        self.assertEqual(['a\n', 'b\n'], self.reconstruct(vf, 'rev-a',  0, 2))
231
 
        self.assertEqual(['c\n', 'd\n'], self.reconstruct(vf, 'rev-a',  2, 4))
232
 
        self.assertEqual(['e\n', 'f\n'], self.reconstruct(vf, 'rev-c',  2, 4))
233
 
        self.assertEqual(['a\n', 'b\n', 'e\n', 'f\n'],
234
 
                          self.reconstruct(vf, 'rev-c',  0, 4))
235
 
        self.assertEqual(['a\n', 'b\n', 'e\n', 'f\n'],
236
 
                          self.reconstruct_version(vf, 'rev-c'))
237
 
 
238
 
    def test_reordered(self):
239
 
        """Check for a corner case that requires re-starting the cursor"""
240
 
        vf = multiparent.MultiMemoryVersionedFile()
241
 
        # rev-b must have at least two hunks, so split a and b with c.
242
 
        self.add_version(vf, 'c', 'rev-a', [])
243
 
        self.add_version(vf, 'acb', 'rev-b', ['rev-a'])
244
 
        # rev-c and rev-d must each have a line from a different rev-b hunk
245
 
        self.add_version(vf, 'b', 'rev-c', ['rev-b'])
246
 
        self.add_version(vf, 'a', 'rev-d', ['rev-b'])
247
 
        # The lines from rev-c and rev-d must appear in the opposite order
248
 
        self.add_version(vf, 'ba', 'rev-e', ['rev-c', 'rev-d'])
249
 
        vf.clear_cache()
250
 
        lines = vf.get_line_list(['rev-e'])[0]
251
 
        self.assertEqual(['b\n', 'a\n'], lines)
252
 
 
253
 
 
254
 
class TestMultiVersionedFile(tests.TestCaseInTempDir):
255
 
 
256
 
    def test_save_load(self):
257
 
        vf = multiparent.MultiVersionedFile('foop')
258
 
        vf.add_version('a\nb\nc\nd'.splitlines(True), 'a', [])
259
 
        vf.add_version('a\ne\nd\n'.splitlines(True), 'b', ['a'])
260
 
        vf.save()
261
 
        newvf = multiparent.MultiVersionedFile('foop')
262
 
        newvf.load()
263
 
        self.assertEqual('a\nb\nc\nd', ''.join(newvf.get_line_list(['a'])[0]))
264
 
        self.assertEqual('a\ne\nd\n', ''.join(newvf.get_line_list(['b'])[0]))
265
 
 
266
 
    def test_filenames(self):
267
 
        vf = multiparent.MultiVersionedFile('foop')
268
 
        vf.add_version('a\nb\nc\nd'.splitlines(True), 'a', [])
269
 
        self.failUnlessExists('foop.mpknit')
270
 
        self.failIfExists('foop.mpidx')
271
 
        vf.save()
272
 
        self.failUnlessExists('foop.mpidx')
273
 
        vf.destroy()
274
 
        self.failIfExists('foop.mpknit')
275
 
        self.failIfExists('foop.mpidx')