~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_knit.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-09-06 03:41:24 UTC
  • mfrom: (2794.1.3 knits)
  • Revision ID: pqm@pqm.ubuntu.com-20070906034124-gf4re7orinpud4to
(robertc) Nuke VersionedFile add/get delta support which was never used, and reduce memory copies during commits of unannotated file such as inventory. (Robert Collins).

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
    )
37
37
from bzrlib.index import *
38
38
from bzrlib.knit import (
 
39
    AnnotatedKnitContent,
39
40
    KnitContent,
40
41
    KnitGraphIndex,
41
42
    KnitVersionedFile,
45
46
    _KnitData,
46
47
    _KnitIndex,
47
48
    _PackAccess,
 
49
    PlainKnitContent,
48
50
    WeaveToKnit,
49
51
    KnitSequenceMatcher,
50
52
    )
76
78
CompiledKnitFeature = _CompiledKnitFeature()
77
79
 
78
80
 
79
 
class KnitContentTests(TestCase):
 
81
class KnitContentTestsMixin(object):
80
82
 
81
83
    def test_constructor(self):
82
 
        content = KnitContent([])
 
84
        content = self._make_content([])
83
85
 
84
86
    def test_text(self):
85
 
        content = KnitContent([])
 
87
        content = self._make_content([])
86
88
        self.assertEqual(content.text(), [])
87
89
 
88
 
        content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
 
90
        content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
89
91
        self.assertEqual(content.text(), ["text1", "text2"])
90
92
 
91
 
    def test_annotate(self):
92
 
        content = KnitContent([])
93
 
        self.assertEqual(content.annotate(), [])
94
 
 
95
 
        content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
 
93
    def test_copy(self):
 
94
        content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
 
95
        copy = content.copy()
 
96
        self.assertIsInstance(copy, content.__class__)
 
97
        self.assertEqual(copy.annotate(), content.annotate())
 
98
 
 
99
    def assertDerivedBlocksEqual(self, source, target, noeol=False):
 
100
        """Assert that the derived matching blocks match real output"""
 
101
        source_lines = source.splitlines(True)
 
102
        target_lines = target.splitlines(True)
 
103
        def nl(line):
 
104
            if noeol and not line.endswith('\n'):
 
105
                return line + '\n'
 
106
            else:
 
107
                return line
 
108
        source_content = self._make_content([(None, nl(l)) for l in source_lines])
 
109
        target_content = self._make_content([(None, nl(l)) for l in target_lines])
 
110
        line_delta = source_content.line_delta(target_content)
 
111
        delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta,
 
112
            source_lines, target_lines))
 
113
        matcher = KnitSequenceMatcher(None, source_lines, target_lines)
 
114
        matcher_blocks = list(list(matcher.get_matching_blocks()))
 
115
        self.assertEqual(matcher_blocks, delta_blocks)
 
116
 
 
117
    def test_get_line_delta_blocks(self):
 
118
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'q\nc\n')
 
119
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1)
 
120
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1A)
 
121
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1B)
 
122
        self.assertDerivedBlocksEqual(TEXT_1B, TEXT_1A)
 
123
        self.assertDerivedBlocksEqual(TEXT_1A, TEXT_1B)
 
124
        self.assertDerivedBlocksEqual(TEXT_1A, '')
 
125
        self.assertDerivedBlocksEqual('', TEXT_1A)
 
126
        self.assertDerivedBlocksEqual('', '')
 
127
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd')
 
128
 
 
129
    def test_get_line_delta_blocks_noeol(self):
 
130
        """Handle historical knit deltas safely
 
131
 
 
132
        Some existing knit deltas don't consider the last line to differ
 
133
        when the only difference whether it has a final newline.
 
134
 
 
135
        New knit deltas appear to always consider the last line to differ
 
136
        in this case.
 
137
        """
 
138
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd\n', noeol=True)
 
139
        self.assertDerivedBlocksEqual('a\nb\nc\nd\n', 'a\nb\nc', noeol=True)
 
140
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'a\nb\nc', noeol=True)
 
141
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\n', noeol=True)
 
142
 
 
143
 
 
144
class TestPlainKnitContent(TestCase, KnitContentTestsMixin):
 
145
 
 
146
    def _make_content(self, lines):
 
147
        annotated_content = AnnotatedKnitContent(lines)
 
148
        return PlainKnitContent(annotated_content.text(), 'bogus')
 
149
 
 
150
    def test_annotate(self):
 
151
        content = self._make_content([])
 
152
        self.assertEqual(content.annotate(), [])
 
153
 
 
154
        content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
 
155
        self.assertEqual(content.annotate(),
 
156
            [("bogus", "text1"), ("bogus", "text2")])
 
157
 
 
158
    def test_annotate_iter(self):
 
159
        content = self._make_content([])
 
160
        it = content.annotate_iter()
 
161
        self.assertRaises(StopIteration, it.next)
 
162
 
 
163
        content = self._make_content([("bogus", "text1"), ("bogus", "text2")])
 
164
        it = content.annotate_iter()
 
165
        self.assertEqual(it.next(), ("bogus", "text1"))
 
166
        self.assertEqual(it.next(), ("bogus", "text2"))
 
167
        self.assertRaises(StopIteration, it.next)
 
168
 
 
169
    def test_line_delta(self):
 
170
        content1 = self._make_content([("", "a"), ("", "b")])
 
171
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
 
172
        self.assertEqual(content1.line_delta(content2),
 
173
            [(1, 2, 2, ["a", "c"])])
 
174
 
 
175
    def test_line_delta_iter(self):
 
176
        content1 = self._make_content([("", "a"), ("", "b")])
 
177
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
 
178
        it = content1.line_delta_iter(content2)
 
179
        self.assertEqual(it.next(), (1, 2, 2, ["a", "c"]))
 
180
        self.assertRaises(StopIteration, it.next)
 
181
 
 
182
 
 
183
class TestAnnotatedKnitContent(TestCase, KnitContentTestsMixin):
 
184
 
 
185
    def _make_content(self, lines):
 
186
        return AnnotatedKnitContent(lines)
 
187
 
 
188
    def test_annotate(self):
 
189
        content = self._make_content([])
 
190
        self.assertEqual(content.annotate(), [])
 
191
 
 
192
        content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
96
193
        self.assertEqual(content.annotate(),
97
194
            [("origin1", "text1"), ("origin2", "text2")])
98
195
 
99
196
    def test_annotate_iter(self):
100
 
        content = KnitContent([])
 
197
        content = self._make_content([])
101
198
        it = content.annotate_iter()
102
199
        self.assertRaises(StopIteration, it.next)
103
200
 
104
 
        content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
 
201
        content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
105
202
        it = content.annotate_iter()
106
203
        self.assertEqual(it.next(), ("origin1", "text1"))
107
204
        self.assertEqual(it.next(), ("origin2", "text2"))
108
205
        self.assertRaises(StopIteration, it.next)
109
206
 
110
 
    def test_copy(self):
111
 
        content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
112
 
        copy = content.copy()
113
 
        self.assertIsInstance(copy, KnitContent)
114
 
        self.assertEqual(copy.annotate(),
115
 
            [("origin1", "text1"), ("origin2", "text2")])
116
 
 
117
207
    def test_line_delta(self):
118
 
        content1 = KnitContent([("", "a"), ("", "b")])
119
 
        content2 = KnitContent([("", "a"), ("", "a"), ("", "c")])
 
208
        content1 = self._make_content([("", "a"), ("", "b")])
 
209
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
120
210
        self.assertEqual(content1.line_delta(content2),
121
211
            [(1, 2, 2, [("", "a"), ("", "c")])])
122
212
 
123
213
    def test_line_delta_iter(self):
124
 
        content1 = KnitContent([("", "a"), ("", "b")])
125
 
        content2 = KnitContent([("", "a"), ("", "a"), ("", "c")])
 
214
        content1 = self._make_content([("", "a"), ("", "b")])
 
215
        content2 = self._make_content([("", "a"), ("", "a"), ("", "c")])
126
216
        it = content1.line_delta_iter(content2)
127
217
        self.assertEqual(it.next(), (1, 2, 2, [("", "a"), ("", "c")]))
128
218
        self.assertRaises(StopIteration, it.next)
1074
1164
    def test_delta(self):
1075
1165
        """Expression of knit delta as lines"""
1076
1166
        k = self.make_test_knit()
1077
 
        KnitContent
1078
1167
        td = list(line_delta(TEXT_1.splitlines(True),
1079
1168
                             TEXT_1A.splitlines(True)))
1080
1169
        self.assertEqualDiff(''.join(td), delta_1_1a)
1081
1170
        out = apply_line_delta(TEXT_1.splitlines(True), td)
1082
1171
        self.assertEqualDiff(''.join(out), TEXT_1A)
1083
1172
 
1084
 
    def assertDerivedBlocksEqual(self, source, target, noeol=False):
1085
 
        """Assert that the derived matching blocks match real output"""
1086
 
        source_lines = source.splitlines(True)
1087
 
        target_lines = target.splitlines(True)
1088
 
        def nl(line):
1089
 
            if noeol and not line.endswith('\n'):
1090
 
                return line + '\n'
1091
 
            else:
1092
 
                return line
1093
 
        source_content = KnitContent([(None, nl(l)) for l in source_lines])
1094
 
        target_content = KnitContent([(None, nl(l)) for l in target_lines])
1095
 
        line_delta = source_content.line_delta(target_content)
1096
 
        delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta,
1097
 
            source_lines, target_lines))
1098
 
        matcher = KnitSequenceMatcher(None, source_lines, target_lines)
1099
 
        matcher_blocks = list(list(matcher.get_matching_blocks()))
1100
 
        self.assertEqual(matcher_blocks, delta_blocks)
1101
 
 
1102
 
    def test_get_line_delta_blocks(self):
1103
 
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'q\nc\n')
1104
 
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1)
1105
 
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1A)
1106
 
        self.assertDerivedBlocksEqual(TEXT_1, TEXT_1B)
1107
 
        self.assertDerivedBlocksEqual(TEXT_1B, TEXT_1A)
1108
 
        self.assertDerivedBlocksEqual(TEXT_1A, TEXT_1B)
1109
 
        self.assertDerivedBlocksEqual(TEXT_1A, '')
1110
 
        self.assertDerivedBlocksEqual('', TEXT_1A)
1111
 
        self.assertDerivedBlocksEqual('', '')
1112
 
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd')
1113
 
 
1114
 
    def test_get_line_delta_blocks_noeol(self):
1115
 
        """Handle historical knit deltas safely
1116
 
 
1117
 
        Some existing knit deltas don't consider the last line to differ
1118
 
        when the only difference whether it has a final newline.
1119
 
 
1120
 
        New knit deltas appear to always consider the last line to differ
1121
 
        in this case.
1122
 
        """
1123
 
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\nd\n', noeol=True)
1124
 
        self.assertDerivedBlocksEqual('a\nb\nc\nd\n', 'a\nb\nc', noeol=True)
1125
 
        self.assertDerivedBlocksEqual('a\nb\nc\n', 'a\nb\nc', noeol=True)
1126
 
        self.assertDerivedBlocksEqual('a\nb\nc', 'a\nb\nc\n', noeol=True)
1127
 
 
1128
1173
    def test_add_with_parents(self):
1129
1174
        """Store in knit with parents"""
1130
1175
        k = self.make_test_knit()