242
247
for version in multiparent.topo_iter(vf):
243
248
mpdiff = vf.make_mpdiffs([version])[0]
244
249
new_vf.add_mpdiffs([(version, vf.get_parent_map([version])[version],
245
vf.get_sha1(version), mpdiff)])
250
vf.get_sha1s([version])[0], mpdiff)])
246
251
self.assertEqualDiff(vf.get_text(version),
247
252
new_vf.get_text(version))
348
353
set(f.get_ancestry('rM', topo_sorted=False)))
350
355
def test_mutate_after_finish(self):
356
self._transaction = 'before'
351
357
f = self.get_file()
352
f.transaction_finished()
358
self._transaction = 'after'
353
359
self.assertRaises(errors.OutSideTransaction, f.add_lines, '', [], [])
354
360
self.assertRaises(errors.OutSideTransaction, f.add_lines_with_ghosts, '', [], [])
355
361
self.assertRaises(errors.OutSideTransaction, f.join, '')
356
self.assertRaises(errors.OutSideTransaction, f.clone_text, 'base', 'bar', ['foo'])
358
def test_clear_cache(self):
360
# on a new file it should not error
362
# and after adding content, doing a clear_cache and a get should work.
363
f.add_lines('0', [], ['a'])
365
self.assertEqual(['a'], f.get_lines('0'))
367
363
def test_clone_text(self):
368
364
f = self.get_file()
369
365
f.add_lines('r0', [], ['a\n', 'b\n'])
370
f.clone_text('r1', 'r0', ['r0'])
366
self.applyDeprecated(one_four, f.clone_text, 'r1', 'r0', ['r0'])
371
367
def verify_file(f):
372
368
self.assertEquals(f.get_lines('r1'), f.get_lines('r0'))
373
369
self.assertEquals(f.get_lines('r1'), ['a\n', 'b\n'])
374
370
self.assertEqual({'r1':('r0',)}, f.get_parent_map(['r1']))
375
371
self.assertRaises(RevisionNotPresent,
376
f.clone_text, 'r2', 'rX', [])
372
self.applyDeprecated, one_four, f.clone_text, 'r2', 'rX', [])
377
373
self.assertRaises(RevisionAlreadyPresent,
378
f.clone_text, 'r1', 'r0', [])
374
self.applyDeprecated, one_four, f.clone_text, 'r1', 'r0', [])
380
376
verify_file(self.reopen_file())
384
380
f.add_lines('0', [], ['a\n'])
385
381
t = MemoryTransport()
386
382
f.copy_to('foo', t)
387
for suffix in f.__class__.get_suffixes():
383
for suffix in self.get_factory().get_suffixes():
388
384
self.assertTrue(t.has('foo' + suffix))
390
386
def test_get_suffixes(self):
391
387
f = self.get_file()
393
self.assertEqual(f.__class__.get_suffixes(), f.__class__.get_suffixes())
394
388
# and should be a list
395
self.assertTrue(isinstance(f.__class__.get_suffixes(), list))
389
self.assertTrue(isinstance(self.get_factory().get_suffixes(), list))
397
391
def build_graph(self, file, graph):
398
392
for node in topo_sort(graph.items()):
432
426
simple_b_gam.update(simple_gam)
433
427
simple_b_gam.update(simple_b)
434
428
self.build_graph(f, complex_graph)
435
self.assertEqual(simple_a, f.get_graph(['a']))
436
self.assertEqual(simple_b, f.get_graph(['b']))
437
self.assertEqual(simple_gam, f.get_graph(['gam']))
438
self.assertEqual(simple_b_gam, f.get_graph(['b', 'gam']))
429
self.assertEqual(simple_a, self.applyDeprecated(one_four, f.get_graph,
431
self.assertEqual(simple_b, self.applyDeprecated(one_four, f.get_graph,
433
self.assertEqual(simple_gam, self.applyDeprecated(one_four,
434
f.get_graph, ['gam']))
435
self.assertEqual(simple_b_gam, self.applyDeprecated(one_four,
436
f.get_graph, ['b', 'gam']))
440
438
def test_get_parents(self):
441
439
f = self.get_file()
525
523
# XXX TODO a ghost
526
524
# cases: each sample data individually:
527
525
self.assertEqual(set([('r0', ())]),
528
set(f.iter_parents(['r0'])))
526
set(self.applyDeprecated(one_four, f.iter_parents, ['r0'])))
529
527
self.assertEqual(set([('r1', ('r0', ))]),
530
set(f.iter_parents(['r1'])))
528
set(self.applyDeprecated(one_four, f.iter_parents, ['r1'])))
531
529
self.assertEqual(set([('r2', ('r1', 'r0'))]),
532
set(f.iter_parents(['r2'])))
530
set(self.applyDeprecated(one_four, f.iter_parents, ['r2'])))
533
531
# no nodes returned for a missing node
534
532
self.assertEqual(set(),
535
set(f.iter_parents(['missing'])))
533
set(self.applyDeprecated(one_four, f.iter_parents, ['missing'])))
536
534
# 1 node returned with missing nodes skipped
537
535
self.assertEqual(set([('r1', ('r0', ))]),
538
set(f.iter_parents(['ghost1', 'r1', 'ghost'])))
536
set(self.applyDeprecated(one_four, f.iter_parents, ['ghost1', 'r1',
539
538
# 2 nodes returned
540
539
self.assertEqual(set([('r0', ()), ('r1', ('r0', ))]),
541
set(f.iter_parents(['r0', 'r1'])))
540
set(self.applyDeprecated(one_four, f.iter_parents, ['r0', 'r1'])))
542
541
# 2 nodes returned, missing skipped
543
542
self.assertEqual(set([('r0', ()), ('r1', ('r0', ))]),
544
set(f.iter_parents(['a', 'r0', 'b', 'r1', 'c'])))
543
set(self.applyDeprecated(one_four, f.iter_parents,
544
['a', 'r0', 'b', 'r1', 'c'])))
546
546
def test_iter_lines_added_or_present_in_versions(self):
547
547
# test that we get at least an equalset of the lines added by
631
631
self.assertEqual(['notbxbfse'], vf.get_ancestry('notbxbfse'))
632
632
self.assertEqual([],
633
633
self.applyDeprecated(one_four, vf.get_parents, 'notbxbfse'))
634
self.assertEqual({'notbxbfse':()}, vf.get_graph())
634
self.assertEqual({'notbxbfse':()}, self.applyDeprecated(one_four,
635
636
self.assertFalse(vf.has_version(parent_id_utf8))
636
637
# we have _with_ghost apis to give us ghost information.
637
638
self.assertEqual([parent_id_utf8, 'notbxbfse'], vf.get_ancestry_with_ghosts(['notbxbfse']))
649
650
self.assertEqual({parent_id_utf8:(),
650
651
'notbxbfse':(parent_id_utf8, ),
653
self.applyDeprecated(one_four, vf.get_graph))
653
654
self.assertTrue(vf.has_version(parent_id_utf8))
654
655
# we have _with_ghost apis to give us ghost information.
655
656
self.assertEqual([parent_id_utf8, 'notbxbfse'],
695
696
self.assertRaises(errors.ReadOnlyError, vf.join, 'base')
696
self.assertRaises(errors.ReadOnlyError, vf.clone_text, 'base', 'bar', ['foo'])
698
def test_get_sha1(self):
698
def test_get_sha1s(self):
699
699
# check the sha1 data is available
700
700
vf = self.get_file()
704
704
vf.add_lines('b', ['a'], ['a\n'])
705
705
# a file differing only in last newline.
706
706
vf.add_lines('c', [], ['a'])
708
'3f786850e387550fdab836ed7e6dc881de23001b', vf.get_sha1('a'))
710
'3f786850e387550fdab836ed7e6dc881de23001b', vf.get_sha1('b'))
712
'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', vf.get_sha1('c'))
707
# Deprecasted single-version API.
709
'3f786850e387550fdab836ed7e6dc881de23001b',
710
self.applyDeprecated(one_four, vf.get_sha1, 'a'))
712
'3f786850e387550fdab836ed7e6dc881de23001b',
713
self.applyDeprecated(one_four, vf.get_sha1, 'b'))
715
'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8',
716
self.applyDeprecated(one_four, vf.get_sha1, 'c'))
714
717
self.assertEqual(['3f786850e387550fdab836ed7e6dc881de23001b',
715
718
'86f7e437faa5a7fce15d1ddcb9eaeaea377667b8',
716
719
'3f786850e387550fdab836ed7e6dc881de23001b'],
720
723
class TestWeave(TestCaseWithMemoryTransport, VersionedFileTestMixIn):
722
725
def get_file(self, name='foo'):
723
return WeaveFile(name, get_transport(self.get_url('.')), create=True)
726
return WeaveFile(name, get_transport(self.get_url('.')), create=True,
727
get_scope=self.get_transaction)
725
729
def get_file_corrupted_text(self):
726
w = WeaveFile('foo', get_transport(self.get_url('.')), create=True)
730
w = WeaveFile('foo', get_transport(self.get_url('.')), create=True,
731
get_scope=self.get_transaction)
727
732
w.add_lines('v1', [], ['hello\n'])
728
733
w.add_lines('v2', ['v1'], ['hello\n', 'there\n'])
759
764
def reopen_file(self, name='foo', create=False):
760
return WeaveFile(name, get_transport(self.get_url('.')), create=create)
765
return WeaveFile(name, get_transport(self.get_url('.')), create=create,
766
get_scope=self.get_transaction)
762
768
def test_no_implicit_create(self):
763
769
self.assertRaises(errors.NoSuchFile,
766
get_transport(self.get_url('.')))
772
get_transport(self.get_url('.')),
773
get_scope=self.get_transaction)
768
775
def get_factory(self):
796
803
def test_no_implicit_create(self):
797
self.assertRaises(errors.NoSuchFile,
800
get_transport(self.get_url('.')))
804
self.assertRaises(errors.NoSuchFile, self.get_factory(), 'foo',
805
get_transport(self.get_url('.')))
803
808
class TestPlaintextKnit(TestKnit):
804
809
"""Test a knit with no cached annotations"""
806
def _factory(self, name, transport, file_mode=None, access_mode=None,
807
delta=True, create=False):
808
return KnitVersionedFile(name, transport, file_mode, access_mode,
809
KnitPlainFactory(), delta=delta,
812
811
def get_factory(self):
812
return make_file_knit
816
815
class TestPlanMergeVersionedFile(TestCaseWithMemoryTransport):
819
818
TestCaseWithMemoryTransport.setUp(self)
820
self.vf1 = KnitVersionedFile('root', self.get_transport(), create=True)
821
self.vf2 = KnitVersionedFile('root', self.get_transport(), create=True)
819
self.vf1 = make_file_knit('root', self.get_transport(), create=True)
820
self.vf2 = make_file_knit('root', self.get_transport(), create=True)
822
821
self.plan_merge_vf = versionedfile._PlanMergeVersionedFile('root',
823
822
[self.vf1, self.vf2])
964
966
class TestWeaveHTTP(TestCaseWithWebserver, TestReadonlyHttpMixin):
966
968
def get_file(self):
967
return WeaveFile('foo', get_transport(self.get_url('.')), create=True)
969
return WeaveFile('foo', get_transport(self.get_url('.')), create=True,
970
get_scope=self.get_transaction)
969
972
def get_factory(self):
973
976
class TestKnitHTTP(TestCaseWithWebserver, TestReadonlyHttpMixin):
975
978
def get_file(self):
976
return KnitVersionedFile('foo', get_transport(self.get_url('.')),
977
delta=True, create=True)
979
return make_file_knit('foo', get_transport(self.get_url('.')),
980
delta=True, create=True, get_scope=self.get_transaction)
979
982
def get_factory(self):
980
return KnitVersionedFile
983
return make_file_knit
983
986
class MergeCasesMixin(object):
1220
1223
class TestKnitMerge(TestCaseWithMemoryTransport, MergeCasesMixin):
1222
1225
def get_file(self, name='foo'):
1223
return KnitVersionedFile(name, get_transport(self.get_url('.')),
1226
return make_file_knit(name, get_transport(self.get_url('.')),
1224
1227
delta=True, create=True)
1226
1229
def log_contents(self, w):
1241
1244
overlappedInsertExpected = ['aaa', '<<<<<<< ', 'xxx', 'yyy', '=======',
1242
1245
'xxx', '>>>>>>> ', 'bbb']
1245
class TestFormatSignatures(TestCaseWithMemoryTransport):
1247
def get_knit_file(self, name, annotated):
1249
factory = KnitAnnotateFactory()
1251
factory = KnitPlainFactory()
1252
return KnitVersionedFile(
1253
name, get_transport(self.get_url('.')), create=True,
1256
def test_knit_format_signatures(self):
1257
"""Different formats of knit have different signature strings."""
1258
knit = self.get_knit_file('a', True)
1259
self.assertEqual('knit-annotated', knit.get_format_signature())
1260
knit = self.get_knit_file('p', False)
1261
self.assertEqual('knit-plain', knit.get_format_signature())