224
233
"""Open the versioned file from disk again."""
225
234
raise NotImplementedError(self.reopen_file)
236
def test_iter_lines_added_or_present_in_versions(self):
237
# test that we get at least an equalset of the lines added by
238
# versions in the weave
239
# the ordering here is to make a tree so that dumb searches have
240
# more changes to muck up.
242
# add a base to get included
243
vf.add_lines('base', [], ['base\n'])
244
# add a ancestor to be included on one side
245
vf.add_lines('lancestor', [], ['lancestor\n'])
246
# add a ancestor to be included on the other side
247
vf.add_lines('rancestor', ['base'], ['rancestor\n'])
248
# add a child of rancestor with no eofile-nl
249
vf.add_lines('child', ['rancestor'], ['base\n', 'child\n'])
250
# add a child of lancestor and base to join the two roots
251
vf.add_lines('otherchild',
252
['lancestor', 'base'],
253
['base\n', 'lancestor\n', 'otherchild\n'])
254
def iter_with_versions(versions):
255
# now we need to see what lines are returned, and how often.
262
# iterate over the lines
263
for line in vf.iter_lines_added_or_present_in_versions(versions):
266
lines = iter_with_versions(['child', 'otherchild'])
267
# we must see child and otherchild
268
self.assertTrue(lines['child\n'] > 0)
269
self.assertTrue(lines['otherchild\n'] > 0)
270
# we dont care if we got more than that.
273
lines = iter_with_versions(None)
274
# all lines must be seen at least once
275
self.assertTrue(lines['base\n'] > 0)
276
self.assertTrue(lines['lancestor\n'] > 0)
277
self.assertTrue(lines['rancestor\n'] > 0)
278
self.assertTrue(lines['child\n'] > 0)
279
self.assertTrue(lines['otherchild\n'] > 0)
281
def test_fix_parents(self):
282
# some versioned files allow incorrect parents to be corrected after
283
# insertion - this may not fix ancestry..
284
# if they do not supported, they just do not implement it.
285
# we test this as an interface test to ensure that those that *do*
286
# implementent it get it right.
288
vf.add_lines('notbase', [], [])
289
vf.add_lines('base', [], [])
291
vf.fix_parents('notbase', ['base'])
292
except NotImplementedError:
294
self.assertEqual(['base'], vf.get_parents('notbase'))
295
# open again, check it stuck.
297
self.assertEqual(['base'], vf.get_parents('notbase'))
299
def test_fix_parents_with_ghosts(self):
300
# when fixing parents, ghosts that are listed should not be ghosts
305
vf.add_lines_with_ghosts('notbase', ['base', 'stillghost'], [])
306
except NotImplementedError:
308
vf.add_lines('base', [], [])
309
vf.fix_parents('notbase', ['base', 'stillghost'])
310
self.assertEqual(['base'], vf.get_parents('notbase'))
311
# open again, check it stuck.
313
self.assertEqual(['base'], vf.get_parents('notbase'))
314
# and check the ghosts
315
self.assertEqual(['base', 'stillghost'],
316
vf.get_parents_with_ghosts('notbase'))
318
def test_add_lines_with_ghosts(self):
319
# some versioned file formats allow lines to be added with parent
320
# information that is > than that in the format. Formats that do
321
# not support this need to raise NotImplementedError on the
322
# add_lines_with_ghosts api.
324
# add a revision with ghost parents
326
vf.add_lines_with_ghosts('notbase', ['base'], [])
327
except NotImplementedError:
328
# check the other ghost apis are also not implemented
329
self.assertRaises(NotImplementedError, vf.has_ghost, 'foo')
330
self.assertRaises(NotImplementedError, vf.get_ancestry_with_ghosts, ['foo'])
331
self.assertRaises(NotImplementedError, vf.get_parents_with_ghosts, 'foo')
332
self.assertRaises(NotImplementedError, vf.get_graph_with_ghosts)
334
# test key graph related apis: getncestry, _graph, get_parents
336
# - these are ghost unaware and must not be reflect ghosts
337
self.assertEqual(['notbase'], vf.get_ancestry('notbase'))
338
self.assertEqual([], vf.get_parents('notbase'))
339
self.assertEqual({'notbase':[]}, vf.get_graph())
340
self.assertFalse(vf.has_version('base'))
341
# we have _with_ghost apis to give us ghost information.
342
self.assertEqual(['base', 'notbase'], vf.get_ancestry_with_ghosts(['notbase']))
343
self.assertEqual(['base'], vf.get_parents_with_ghosts('notbase'))
344
self.assertEqual({'notbase':['base']}, vf.get_graph_with_ghosts())
345
self.assertTrue(vf.has_ghost('base'))
346
# if we add something that is a ghost of another, it should correct the
347
# results of the prior apis
348
vf.add_lines('base', [], [])
349
self.assertEqual(['base', 'notbase'], vf.get_ancestry(['notbase']))
350
self.assertEqual(['base'], vf.get_parents('notbase'))
351
self.assertEqual({'base':[],
355
self.assertTrue(vf.has_version('base'))
356
# we have _with_ghost apis to give us ghost information.
357
self.assertEqual(['base', 'notbase'], vf.get_ancestry_with_ghosts(['notbase']))
358
self.assertEqual(['base'], vf.get_parents_with_ghosts('notbase'))
359
self.assertEqual({'base':[],
362
vf.get_graph_with_ghosts())
363
self.assertFalse(vf.has_ghost('base'))
365
def test_add_lines_with_ghosts_after_normal_revs(self):
366
# some versioned file formats allow lines to be added with parent
367
# information that is > than that in the format. Formats that do
368
# not support this need to raise NotImplementedError on the
369
# add_lines_with_ghosts api.
371
# probe for ghost support
374
except NotImplementedError:
376
vf.add_lines_with_ghosts('base', [], ['line\n', 'line_b\n'])
377
vf.add_lines_with_ghosts('references_ghost',
379
['line\n', 'line_b\n', 'line_c\n'])
380
origins = vf.annotate('references_ghost')
381
self.assertEquals(('base', 'line\n'), origins[0])
382
self.assertEquals(('base', 'line_b\n'), origins[1])
383
self.assertEquals(('references_ghost', 'line_c\n'), origins[2])
385
def test_readonly_mode(self):
386
transport = get_transport(self.get_url('.'))
387
factory = self.get_factory()
388
vf = factory('id', transport, 0777, create=True, access_mode='w')
389
vf = factory('id', transport, access_mode='r')
390
self.assertRaises(errors.ReadOnlyError, vf.add_lines, 'base', [], [])
391
self.assertRaises(errors.ReadOnlyError,
392
vf.add_lines_with_ghosts,
396
self.assertRaises(errors.ReadOnlyError, vf.fix_parents, 'base', [])
397
self.assertRaises(errors.ReadOnlyError, vf.join, 'base')
398
self.assertRaises(errors.ReadOnlyError, vf.clone_text, 'base', 'bar', ['foo'])
228
401
class TestWeave(TestCaseWithTransport, VersionedFileTestMixIn):