76
78
CompiledKnitFeature = _CompiledKnitFeature()
79
class KnitContentTests(TestCase):
81
class KnitContentTestsMixin(object):
81
83
def test_constructor(self):
82
content = KnitContent([])
84
content = self._make_content([])
84
86
def test_text(self):
85
content = KnitContent([])
87
content = self._make_content([])
86
88
self.assertEqual(content.text(), [])
88
content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
90
content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
89
91
self.assertEqual(content.text(), ["text1", "text2"])
91
def test_annotate(self):
92
content = KnitContent([])
93
self.assertEqual(content.annotate(), [])
95
content = KnitContent([("origin1", "text1"), ("origin2", "text2")])
94
content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
96
self.assertIsInstance(copy, content.__class__)
97
self.assertEqual(copy.annotate(), content.annotate())
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)
104
if noeol and not line.endswith('\n'):
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)
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')
129
def test_get_line_delta_blocks_noeol(self):
130
"""Handle historical knit deltas safely
132
Some existing knit deltas don't consider the last line to differ
133
when the only difference whether it has a final newline.
135
New knit deltas appear to always consider the last line to differ
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)
144
class TestPlainKnitContent(TestCase, KnitContentTestsMixin):
146
def _make_content(self, lines):
147
annotated_content = AnnotatedKnitContent(lines)
148
return PlainKnitContent(annotated_content.text(), 'bogus')
150
def test_annotate(self):
151
content = self._make_content([])
152
self.assertEqual(content.annotate(), [])
154
content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
155
self.assertEqual(content.annotate(),
156
[("bogus", "text1"), ("bogus", "text2")])
158
def test_annotate_iter(self):
159
content = self._make_content([])
160
it = content.annotate_iter()
161
self.assertRaises(StopIteration, it.next)
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)
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"])])
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)
183
class TestAnnotatedKnitContent(TestCase, KnitContentTestsMixin):
185
def _make_content(self, lines):
186
return AnnotatedKnitContent(lines)
188
def test_annotate(self):
189
content = self._make_content([])
190
self.assertEqual(content.annotate(), [])
192
content = self._make_content([("origin1", "text1"), ("origin2", "text2")])
96
193
self.assertEqual(content.annotate(),
97
194
[("origin1", "text1"), ("origin2", "text2")])
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)
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)
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")])
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")])])
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()
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)
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)
1089
if noeol and not line.endswith('\n'):
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)
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')
1114
def test_get_line_delta_blocks_noeol(self):
1115
"""Handle historical knit deltas safely
1117
Some existing knit deltas don't consider the last line to differ
1118
when the only difference whether it has a final newline.
1120
New knit deltas appear to always consider the last line to differ
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)
1128
1173
def test_add_with_parents(self):
1129
1174
"""Store in knit with parents"""
1130
1175
k = self.make_test_knit()