260
241
class LowLevelKnitIndexTests(TestCase):
262
def get_knit_index(self, *args, **kwargs):
263
orig = knit._load_data
265
knit._load_data = orig
266
self.addCleanup(reset)
267
from bzrlib._knit_load_data_py import _load_data_py
268
knit._load_data = _load_data_py
269
return _KnitIndex(*args, **kwargs)
271
243
def test_no_such_file(self):
272
244
transport = MockTransport()
274
self.assertRaises(NoSuchFile, self.get_knit_index,
275
transport, "filename", "r")
276
self.assertRaises(NoSuchFile, self.get_knit_index,
277
transport, "filename", "w", create=False)
246
self.assertRaises(NoSuchFile, _KnitIndex, transport, "filename", "r")
247
self.assertRaises(NoSuchFile, _KnitIndex, transport,
248
"filename", "w", create=False)
279
250
def test_create_file(self):
280
251
transport = MockTransport()
282
index = self.get_knit_index(transport, "filename", "w",
253
index = _KnitIndex(transport, "filename", "w",
283
254
file_mode="wb", create=True)
284
255
self.assertEqual(
285
256
("put_bytes_non_atomic",
700
671
self.assertRaises(RevisionNotPresent, check, ["c"])
701
672
self.assertRaises(RevisionNotPresent, check, ["a", "b", "c"])
703
def test_impossible_parent(self):
704
"""Test we get KnitCorrupt if the parent couldn't possibly exist."""
705
transport = MockTransport([
708
"b option 0 1 4 :" # We don't have a 4th record
711
self.assertRaises(errors.KnitCorrupt,
712
self.get_knit_index, transport, 'filename', 'r')
714
if (str(e) == ('exceptions must be strings, classes, or instances,'
715
' not exceptions.IndexError')
716
and sys.version_info[0:2] >= (2,5)):
717
self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
718
' raising new style exceptions with python'
723
def test_corrupted_parent(self):
724
transport = MockTransport([
728
"c option 0 1 1v :", # Can't have a parent of '1v'
731
self.assertRaises(errors.KnitCorrupt,
732
self.get_knit_index, transport, 'filename', 'r')
734
if (str(e) == ('exceptions must be strings, classes, or instances,'
735
' not exceptions.ValueError')
736
and sys.version_info[0:2] >= (2,5)):
737
self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
738
' raising new style exceptions with python'
743
def test_corrupted_parent_in_list(self):
744
transport = MockTransport([
748
"c option 0 1 1 v :", # Can't have a parent of 'v'
751
self.assertRaises(errors.KnitCorrupt,
752
self.get_knit_index, transport, 'filename', 'r')
754
if (str(e) == ('exceptions must be strings, classes, or instances,'
755
' not exceptions.ValueError')
756
and sys.version_info[0:2] >= (2,5)):
757
self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
758
' raising new style exceptions with python'
763
def test_invalid_position(self):
764
transport = MockTransport([
769
self.assertRaises(errors.KnitCorrupt,
770
self.get_knit_index, transport, 'filename', 'r')
772
if (str(e) == ('exceptions must be strings, classes, or instances,'
773
' not exceptions.ValueError')
774
and sys.version_info[0:2] >= (2,5)):
775
self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
776
' raising new style exceptions with python'
781
def test_invalid_size(self):
782
transport = MockTransport([
787
self.assertRaises(errors.KnitCorrupt,
788
self.get_knit_index, transport, 'filename', 'r')
790
if (str(e) == ('exceptions must be strings, classes, or instances,'
791
' not exceptions.ValueError')
792
and sys.version_info[0:2] >= (2,5)):
793
self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
794
' raising new style exceptions with python'
799
def test_short_line(self):
800
transport = MockTransport([
803
"b option 10 10 0", # This line isn't terminated, ignored
805
index = self.get_knit_index(transport, "filename", "r")
806
self.assertEqual(['a'], index.get_versions())
808
def test_skip_incomplete_record(self):
809
# A line with bogus data should just be skipped
810
transport = MockTransport([
813
"b option 10 10 0", # This line isn't terminated, ignored
814
"c option 20 10 0 :", # Properly terminated, and starts with '\n'
816
index = self.get_knit_index(transport, "filename", "r")
817
self.assertEqual(['a', 'c'], index.get_versions())
819
def test_trailing_characters(self):
820
# A line with bogus data should just be skipped
821
transport = MockTransport([
824
"b option 10 10 0 :a", # This line has extra trailing characters
825
"c option 20 10 0 :", # Properly terminated, and starts with '\n'
827
index = self.get_knit_index(transport, "filename", "r")
828
self.assertEqual(['a', 'c'], index.get_versions())
831
class LowLevelKnitIndexTests_c(LowLevelKnitIndexTests):
833
_test_needs_features = [CompiledKnitFeature]
835
def get_knit_index(self, *args, **kwargs):
836
orig = knit._load_data
838
knit._load_data = orig
839
self.addCleanup(reset)
840
from bzrlib._knit_load_data_c import _load_data_c
841
knit._load_data = _load_data_c
842
return _KnitIndex(*args, **kwargs)
846
675
class KnitTests(TestCaseWithTransport):
847
676
"""Class containing knit test helper routines."""
917
746
def test_delta(self):
918
747
"""Expression of knit delta as lines"""
919
748
k = self.make_test_knit()
921
749
td = list(line_delta(TEXT_1.splitlines(True),
922
750
TEXT_1A.splitlines(True)))
923
751
self.assertEqualDiff(''.join(td), delta_1_1a)
924
752
out = apply_line_delta(TEXT_1.splitlines(True), td)
925
753
self.assertEqualDiff(''.join(out), TEXT_1A)
927
def assertDerivedBlocksEqual(self, source, target, noeol=False):
928
"""Assert that the derived matching blocks match real output"""
929
source_lines = source.splitlines(True)
930
target_lines = target.splitlines(True)
932
if noeol and not line.endswith('\n'):
936
source_content = KnitContent([(None, nl(l)) for l in source_lines])
937
target_content = KnitContent([(None, nl(l)) for l in target_lines])
938
line_delta = source_content.line_delta(target_content)
939
delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta,
940
source_lines, target_lines))
941
matcher = KnitSequenceMatcher(None, source_lines, target_lines)
942
matcher_blocks = list(list(matcher.get_matching_blocks()))
943
self.assertEqual(matcher_blocks, delta_blocks)
945
def test_get_line_delta_blocks(self):
946
self.assertDerivedBlocksEqual('a\nb\nc\n', 'q\nc\n')
947
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1)
948
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1A)
949
self.assertDerivedBlocksEqual(TEXT_1, TEXT_1B)
950
self.assertDerivedBlocksEqual(TEXT_1B, TEXT_1A)
951
self.assertDerivedBlocksEqual(TEXT_1A, TEXT_1B)
952
self.assertDerivedBlocksEqual(TEXT_1A, '')
953
self.assertDerivedBlocksEqual('', TEXT_1A)
954
self.assertDerivedBlocksEqual('', '')
955
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd')
957
def test_get_line_delta_blocks_noeol(self):
958
"""Handle historical knit deltas safely
960
Some existing knit deltas don't consider the last line to differ
961
when the only difference whether it has a final newline.
963
New knit deltas appear to always consider the last line to differ
966
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd\n', noeol=True)
967
self.assertDerivedBlocksEqual('a\nb\nc\nd\n', 'a\nb\nc', noeol=True)
968
self.assertDerivedBlocksEqual('a\nb\nc\n', 'a\nb\nc', noeol=True)
969
self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\n', noeol=True)
971
755
def test_add_with_parents(self):
972
756
"""Store in knit with parents"""
973
757
k = self.make_test_knit()