105
103
verify_file(self.reopen_file())
105
def test_create_empty(self):
107
f.add_lines('0', [], ['a\n'])
108
new_f = f.create_empty('t', MemoryTransport())
109
# smoke test, specific types should check it is honoured correctly for
110
# non type attributes
111
self.assertEqual([], new_f.versions())
112
self.assertTrue(isinstance(new_f, f.__class__))
114
def test_get_graph(self):
116
f.add_lines('v1', [], ['hello\n'])
117
f.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
118
f.add_lines('v3', ['v2'], ['hello\n', 'cruel\n', 'world\n'])
119
self.assertEqual({'v1': [],
107
124
def test_get_parents(self):
108
125
f = self.get_file()
109
126
f.add_lines('r0', [], ['a\n', 'b\n'])
175
190
"""Open the versioned file from disk again."""
176
191
raise NotImplementedError(self.reopen_file)
178
def test_join_add_parents(self):
179
"""Reweave inserting new parents
181
The new version must have the right parent list and must identify
182
lines originating in another parent.
184
w1 = self.get_file('w1')
185
w2 = self.get_file('w2')
186
w1.add_lines('v-1', [], ['line 1\n'])
187
w2.add_lines('v-2', [], ['line 2\n'])
188
w1.add_lines('v-3', ['v-1'], ['line 1\n'])
189
w2.add_lines('v-3', ['v-2'], ['line 1\n'])
191
self.assertEqual(sorted(w1.names()),
192
'v-1 v-2 v-3'.split())
193
self.assertEqualDiff(w1.get_text('v-3'),
195
self.assertEqual(sorted(w1.parent_names('v-3')),
197
ann = list(w1.annotate('v-3'))
198
self.assertEqual(len(ann), 1)
199
self.assertEqual(ann[0][0], 'v-1')
200
self.assertEqual(ann[0][1], 'line 1\n')
202
def build_weave1(self):
203
weave1 = self.get_file()
204
self.lines1 = ['hello\n']
205
self.lines3 = ['hello\n', 'cruel\n', 'world\n']
206
weave1.add_lines('v1', [], self.lines1)
207
weave1.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
208
weave1.add_lines('v3', ['v2'], self.lines3)
211
def test_join_with_empty(self):
212
"""Reweave adding empty weave"""
213
wb = self.get_file('b')
214
w1 = self.build_weave1()
216
self.assertEqual(sorted(w1.iter_names()), ['v1', 'v2', 'v3'])
217
self.assertEqual(w1.get_lines('v1'), ['hello\n'])
218
self.assertEqual([], w1.get_parents('v1'))
219
self.assertEqual(w1.get_lines('v2'), ['hello\n', 'world\n'])
220
self.assertEqual(['v1'], w1.get_parents('v2'))
221
self.assertEqual(w1.get_lines('v3'), ['hello\n', 'cruel\n', 'world\n'])
222
self.assertEqual(['v2'], w1.get_parents('v3'))
224
def test_join_with_ghosts_raises_parent_mismatch(self):
225
"""Join combined parent lists"""
226
wa = self.build_weave1()
227
wb = self.get_file('b')
228
wb.add_lines('x1', [], ['line from x1\n'])
229
wb.add_lines('v1', [], ['hello\n'])
230
wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
232
self.assertEqual(['v1','x1'], wa.get_parents('v2'))
234
def test_join_with_ghosts(self):
235
"""Join that inserts parents of an existing revision.
237
This can happen when merging from another branch who
238
knows about revisions the destination does not. In
239
this test the second weave knows of an additional parent of
240
v2. Any revisions which are in common still have to have the
243
w1 = self.build_weave1()
244
wb = self.get_file('b')
245
wb.add_lines('x1', [], ['line from x1\n'])
246
wb.add_lines('v1', [], ['hello\n'])
247
wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
249
eq = self.assertEquals
250
eq(sorted(w1.iter_names()), ['v1', 'v2', 'v3', 'x1',])
251
eq(w1.get_text('x1'), 'line from x1\n')
252
eq(w1.get_lines('v2'), ['hello\n', 'world\n'])
253
eq(w1.parent_names('v2'), ['v1', 'x1'])
255
def build_empty_weave(self, name, *pattern):
256
w = self.get_file(name)
257
for version, parents in pattern:
258
w.add_lines(version, parents, [])
261
def test_join_reorder(self):
262
"""Reweave requiring reordering of versions.
264
Weaves must be stored such that parents come before children. When
265
reweaving, we may add new parents to some children, but it is required
266
that there must be *some* valid order that can be found, otherwise the
267
ancestries are contradictory. (For the specific case of inserting
268
ghost revisions there will be no disagreement, only partial knowledge
271
Note that the weaves are only partially ordered: when there are two
272
versions where neither is an ancestor of the other the order in which
273
they occur is unconstrained. When we join those versions into
274
another weave, they may become more constrained and it may be
275
necessary to change their order.
277
One simple case of this is
282
We need to recognize that the final weave must show the ordering
283
a[], b[a], c[b]. The version that must be first in the result is
284
not first in either of the input weaves.
286
w1 = self.build_empty_weave('1', ('c', []), ('a', []), ('b', ['a']))
287
w2 = self.build_empty_weave('2', ('b', []), ('c', ['b']), ('a', []))
289
self.assertEqual([], w1.get_parents('a'))
290
self.assertEqual(['a'], w1.get_parents('b'))
291
self.assertEqual(['b'], w1.get_parents('c'))
293
194
class TestWeave(TestCaseWithTransport, VersionedFileTestMixIn):