23
23
from bzrlib.errors import KnitError, RevisionAlreadyPresent
24
from bzrlib.knit import KnitVersionedFile, KnitPlainFactory, KnitAnnotateFactory
24
from bzrlib.knit import (
25
29
from bzrlib.osutils import split_lines
26
from bzrlib.tests import TestCaseInTempDir
30
from bzrlib.tests import TestCaseWithTransport
27
31
from bzrlib.transport import TransportLogger
28
32
from bzrlib.transport.local import LocalTransport
29
33
from bzrlib.transport.memory import MemoryTransport
32
class KnitTests(TestCaseInTempDir):
34
def add_stock_one_and_one_a(self, k):
35
k.add_lines('text-1', [], split_lines(TEXT_1))
36
k.add_lines('text-1a', ['text-1'], split_lines(TEXT_1A))
38
def test_knit_constructor(self):
39
"""Construct empty k"""
34
from bzrlib.weave import Weave
37
class KnitTests(TestCaseWithTransport):
38
"""Class containing knit test helper routines."""
42
40
def make_test_knit(self, annotate=False):
47
45
return KnitVersionedFile('test', LocalTransport('.'), access_mode='w', factory=factory, create=True)
48
class BasicKnitTests(KnitTests):
50
def add_stock_one_and_one_a(self, k):
51
k.add_lines('text-1', [], split_lines(TEXT_1))
52
k.add_lines('text-1a', ['text-1'], split_lines(TEXT_1A))
54
def test_knit_constructor(self):
55
"""Construct empty k"""
49
58
def test_knit_add(self):
50
59
"""Store one text in knit and retrieve"""
51
60
k = self.make_test_knit()
54
63
self.assertEqualDiff(''.join(k.get_lines('text-1')), TEXT_1)
56
65
def test_knit_reload(self):
57
"""Store and reload a knit"""
66
# test that the content in a reloaded knit is correct
58
67
k = self.make_test_knit()
59
68
k.add_lines('text-1', [], split_lines(TEXT_1))
89
98
k = KnitVersionedFile('test', LocalTransport('.'), delta=False, create=True)
90
99
k.add_lines('text-1', [], ['a\n', 'b' ])
91
100
k.add_lines('text-2', ['text-1'], ['a\rb\n', 'b\n'])
101
# reopening ensures maximum room for confusion
102
k = KnitVersionedFile('test', LocalTransport('.'), delta=False, create=True)
92
103
self.assertEquals(k.get_lines('text-1'), ['a\n', 'b' ])
93
104
self.assertEquals(k.get_lines('text-2'), ['a\rb\n', 'b\n'])
334
345
self.assertEqual(k1.delta, k2.delta)
335
346
# the generic test checks for empty content and file class
348
def test_knit_format(self):
349
# this tests that a new knit index file has the expected content
350
# and that is writes the data we expect as records are added.
351
knit = self.make_test_knit(True)
352
self.assertFileEqual("# bzr knit index 8\n", 'test.kndx')
353
knit.add_lines_with_ghosts('revid', ['a_ghost'], ['a\n'])
354
self.assertFileEqual(
355
"# bzr knit index 8\n"
357
"revid fulltext 0 84 .a_ghost :",
359
knit.add_lines_with_ghosts('revid2', ['revid'], ['a\n'])
360
self.assertFileEqual(
361
"# bzr knit index 8\n"
362
"\nrevid fulltext 0 84 .a_ghost :"
363
"\nrevid2 line-delta 84 82 0 :",
365
# we should be able to load this file again
366
knit = KnitVersionedFile('test', LocalTransport('.'), access_mode='r')
367
self.assertEqual(['revid', 'revid2'], knit.versions())
368
# write a short write to the file and ensure that its ignored
369
indexfile = file('test.kndx', 'at')
370
indexfile.write('\nrevid3 line-delta 166 82 1 2 3 4 5 .phwoar:demo ')
372
# we should be able to load this file again
373
knit = KnitVersionedFile('test', LocalTransport('.'), access_mode='w')
374
self.assertEqual(['revid', 'revid2'], knit.versions())
375
# and add a revision with the same id the failed write had
376
knit.add_lines('revid3', ['revid2'], ['a\n'])
377
# and when reading it revid3 should now appear.
378
knit = KnitVersionedFile('test', LocalTransport('.'), access_mode='r')
379
self.assertEqual(['revid', 'revid2', 'revid3'], knit.versions())
380
self.assertEqual(['revid2'], knit.get_parents('revid3'))
382
def test_plan_merge(self):
383
my_knit = self.make_test_knit(annotate=True)
384
my_knit.add_lines('text1', [], split_lines(TEXT_1))
385
my_knit.add_lines('text1a', ['text1'], split_lines(TEXT_1A))
386
my_knit.add_lines('text1b', ['text1'], split_lines(TEXT_1B))
387
plan = list(my_knit.plan_merge('text1a', 'text1b'))
388
for plan_line, expected_line in zip(plan, AB_MERGE):
389
self.assertEqual(plan_line, expected_line)
339
393
Banana cup cakes:
436
AB_MERGE_TEXT="""unchanged|Banana cup cake recipe
441
new-b|- bananas (do not use plantains!!!)
442
unchanged|- broken tea cups
443
new-a|- self-raising flour
446
AB_MERGE=[tuple(l.split('|')) for l in AB_MERGE_TEXT.splitlines(True)]
374
449
def line_delta(from_lines, to_lines):
375
450
"""Generate line-based delta from one text to another"""
376
451
s = difflib.SequenceMatcher(None, from_lines, to_lines)
400
475
offset = offset + (b - a) + c
479
class TestWeaveToKnit(KnitTests):
481
def test_weave_to_knit_matches(self):
482
# check that the WeaveToKnit is_compatible function
483
# registers True for a Weave to a Knit.
485
k = self.make_test_knit()
486
self.failUnless(WeaveToKnit.is_compatible(w, k))
487
self.failIf(WeaveToKnit.is_compatible(k, w))
488
self.failIf(WeaveToKnit.is_compatible(w, w))
489
self.failIf(WeaveToKnit.is_compatible(k, k))