bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
1  | 
# Copyright (C) 2009 Canonical Ltd
 | 
2  | 
#
 | 
|
3  | 
# This program is free software; you can redistribute it and/or modify
 | 
|
4  | 
# it under the terms of the GNU General Public License as published by
 | 
|
5  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
6  | 
# (at your option) any later version.
 | 
|
7  | 
#
 | 
|
8  | 
# This program is distributed in the hope that it will be useful,
 | 
|
9  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
10  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
11  | 
# GNU General Public License for more details.
 | 
|
12  | 
#
 | 
|
13  | 
# You should have received a copy of the GNU General Public License
 | 
|
14  | 
# along with this program; if not, write to the Free Software
 | 
|
15  | 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
|
16  | 
||
17  | 
"""Tests for Annotators."""
 | 
|
18  | 
||
19  | 
from bzrlib import (  | 
|
| 
4454.3.77
by John Arbash Meinel
 Add support for compatibility with old '_break_annotation_tie' function.  | 
20  | 
annotate,  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
21  | 
_annotator_py,  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
22  | 
errors,  | 
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
23  | 
knit,  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
24  | 
revision,  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
25  | 
tests,  | 
26  | 
    )
 | 
|
27  | 
||
28  | 
||
29  | 
def load_tests(standard_tests, module, loader):  | 
|
30  | 
"""Parameterize tests for all versions of groupcompress."""  | 
|
31  | 
scenarios = [  | 
|
32  | 
('python', {'module': _annotator_py}),  | 
|
33  | 
    ]
 | 
|
34  | 
suite = loader.suiteClass()  | 
|
| 
4913.2.1
by John Arbash Meinel
 Switch Annotator to use the ModuleAvailableFeature  | 
35  | 
if compiled_annotator.available():  | 
36  | 
scenarios.append(('C', {'module': compiled_annotator.module}))  | 
|
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
37  | 
else:  | 
38  | 
        # the compiled module isn't available, so we add a failing test
 | 
|
39  | 
class FailWithoutFeature(tests.TestCase):  | 
|
40  | 
def test_fail(self):  | 
|
| 
4913.2.1
by John Arbash Meinel
 Switch Annotator to use the ModuleAvailableFeature  | 
41  | 
self.requireFeature(compiled_annotator)  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
42  | 
suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))  | 
43  | 
result = tests.multiply_tests(standard_tests, scenarios, suite)  | 
|
44  | 
return result  | 
|
45  | 
||
46  | 
||
| 
4913.2.1
by John Arbash Meinel
 Switch Annotator to use the ModuleAvailableFeature  | 
47  | 
compiled_annotator = tests.ModuleAvailableFeature('bzrlib._annotator_pyx')  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
48  | 
|
49  | 
||
50  | 
class TestAnnotator(tests.TestCaseWithMemoryTransport):  | 
|
51  | 
||
52  | 
module = None # Set by load_tests  | 
|
53  | 
||
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
54  | 
fa_key = ('f-id', 'a-id')  | 
55  | 
fb_key = ('f-id', 'b-id')  | 
|
56  | 
fc_key = ('f-id', 'c-id')  | 
|
57  | 
fd_key = ('f-id', 'd-id')  | 
|
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
58  | 
fe_key = ('f-id', 'e-id')  | 
59  | 
ff_key = ('f-id', 'f-id')  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
60  | 
|
| 
4454.3.66
by John Arbash Meinel
 Implement no-graph support for the Python version.  | 
61  | 
def make_no_graph_texts(self):  | 
62  | 
factory = knit.make_pack_factory(False, False, 2)  | 
|
63  | 
self.vf = factory(self.get_transport())  | 
|
64  | 
self.ann = self.module.Annotator(self.vf)  | 
|
65  | 
self.vf.add_lines(self.fa_key, (), ['simple\n', 'content\n'])  | 
|
66  | 
self.vf.add_lines(self.fb_key, (), ['simple\n', 'new content\n'])  | 
|
67  | 
||
| 
4454.3.2
by John Arbash Meinel
 Start moving bits into helper functions. Add tests for multiple revs.  | 
68  | 
def make_simple_text(self):  | 
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
69  | 
        # TODO: all we really need is a VersionedFile instance, we'd like to
 | 
70  | 
        #       avoid creating all the intermediate stuff
 | 
|
71  | 
factory = knit.make_pack_factory(True, True, 2)  | 
|
72  | 
self.vf = factory(self.get_transport())  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
73  | 
        # This assumes nothing special happens during __init__, which may be
 | 
74  | 
        # valid
 | 
|
75  | 
self.ann = self.module.Annotator(self.vf)  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
76  | 
        #  A    'simple|content|'
 | 
77  | 
        #  |
 | 
|
78  | 
        #  B    'simple|new content|'
 | 
|
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
79  | 
self.vf.add_lines(self.fa_key, [], ['simple\n', 'content\n'])  | 
80  | 
self.vf.add_lines(self.fb_key, [self.fa_key],  | 
|
81  | 
['simple\n', 'new content\n'])  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
82  | 
|
83  | 
def make_merge_text(self):  | 
|
84  | 
self.make_simple_text()  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
85  | 
        #  A    'simple|content|'
 | 
86  | 
        #  |\
 | 
|
87  | 
        #  B |  'simple|new content|'
 | 
|
88  | 
        #  | |
 | 
|
89  | 
        #  | C  'simple|from c|content|'
 | 
|
90  | 
        #  |/
 | 
|
91  | 
        #  D    'simple|from c|new content|introduced in merge|'
 | 
|
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
92  | 
self.vf.add_lines(self.fc_key, [self.fa_key],  | 
93  | 
['simple\n', 'from c\n', 'content\n'])  | 
|
94  | 
self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],  | 
|
95  | 
['simple\n', 'from c\n', 'new content\n',  | 
|
96  | 
'introduced in merge\n'])  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
97  | 
|
98  | 
def make_common_merge_text(self):  | 
|
99  | 
"""Both sides of the merge will have introduced a line."""  | 
|
100  | 
self.make_simple_text()  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
101  | 
        #  A    'simple|content|'
 | 
102  | 
        #  |\
 | 
|
103  | 
        #  B |  'simple|new content|'
 | 
|
104  | 
        #  | |
 | 
|
105  | 
        #  | C  'simple|new content|'
 | 
|
106  | 
        #  |/
 | 
|
107  | 
        #  D    'simple|new content|'
 | 
|
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
108  | 
self.vf.add_lines(self.fc_key, [self.fa_key],  | 
109  | 
['simple\n', 'new content\n'])  | 
|
110  | 
self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],  | 
|
111  | 
['simple\n', 'new content\n'])  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
112  | 
|
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
113  | 
def make_many_way_common_merge_text(self):  | 
114  | 
self.make_simple_text()  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
115  | 
        #  A-.    'simple|content|'
 | 
116  | 
        #  |\ \
 | 
|
117  | 
        #  B | |  'simple|new content|'
 | 
|
118  | 
        #  | | |
 | 
|
119  | 
        #  | C |  'simple|new content|'
 | 
|
120  | 
        #  |/  |
 | 
|
121  | 
        #  D   |  'simple|new content|'
 | 
|
122  | 
        #  |   |
 | 
|
123  | 
        #  |   E  'simple|new content|'
 | 
|
124  | 
        #  |  /
 | 
|
125  | 
        #  F-'    'simple|new content|'
 | 
|
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
126  | 
self.vf.add_lines(self.fc_key, [self.fa_key],  | 
127  | 
['simple\n', 'new content\n'])  | 
|
128  | 
self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],  | 
|
129  | 
['simple\n', 'new content\n'])  | 
|
130  | 
self.vf.add_lines(self.fe_key, [self.fa_key],  | 
|
131  | 
['simple\n', 'new content\n'])  | 
|
132  | 
self.vf.add_lines(self.ff_key, [self.fd_key, self.fe_key],  | 
|
133  | 
['simple\n', 'new content\n'])  | 
|
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
134  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
135  | 
def make_merge_and_restored_text(self):  | 
136  | 
self.make_simple_text()  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
137  | 
        #  A    'simple|content|'
 | 
138  | 
        #  |\
 | 
|
139  | 
        #  B |  'simple|new content|'
 | 
|
140  | 
        #  | |
 | 
|
141  | 
        #  C |  'simple|content|' # reverted to A
 | 
|
142  | 
        #   \|
 | 
|
143  | 
        #    D  'simple|content|'
 | 
|
| 
4454.3.27
by John Arbash Meinel
 Simplify the test__annotator tests by avoiding having a real repository.  | 
144  | 
        # c reverts back to 'a' for the new content line
 | 
145  | 
self.vf.add_lines(self.fc_key, [self.fb_key],  | 
|
146  | 
['simple\n', 'content\n'])  | 
|
147  | 
        # d merges 'a' and 'c', to find both claim last modified
 | 
|
148  | 
self.vf.add_lines(self.fd_key, [self.fa_key, self.fc_key],  | 
|
149  | 
['simple\n', 'content\n'])  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
150  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
151  | 
def assertAnnotateEqual(self, expected_annotation, key, exp_text=None):  | 
152  | 
annotation, lines = self.ann.annotate(key)  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
153  | 
self.assertEqual(expected_annotation, annotation)  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
154  | 
if exp_text is None:  | 
155  | 
record = self.vf.get_record_stream([key], 'unordered', True).next()  | 
|
156  | 
exp_text = record.get_bytes_as('fulltext')  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
157  | 
self.assertEqualDiff(exp_text, ''.join(lines))  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
158  | 
|
159  | 
def test_annotate_missing(self):  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
160  | 
self.make_simple_text()  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
161  | 
self.assertRaises(errors.RevisionNotPresent,  | 
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
162  | 
self.ann.annotate, ('not', 'present'))  | 
| 
4454.3.1
by John Arbash Meinel
 Initial api for Annotator.  | 
163  | 
|
164  | 
def test_annotate_simple(self):  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
165  | 
self.make_simple_text()  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
166  | 
self.assertAnnotateEqual([(self.fa_key,)]*2, self.fa_key)  | 
167  | 
self.assertAnnotateEqual([(self.fa_key,), (self.fb_key,)], self.fb_key)  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
168  | 
|
169  | 
def test_annotate_merge_text(self):  | 
|
170  | 
self.make_merge_text()  | 
|
171  | 
self.assertAnnotateEqual([(self.fa_key,), (self.fc_key,),  | 
|
172  | 
(self.fb_key,), (self.fd_key,)],  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
173  | 
self.fd_key)  | 
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
174  | 
|
175  | 
def test_annotate_common_merge_text(self):  | 
|
176  | 
self.make_common_merge_text()  | 
|
177  | 
self.assertAnnotateEqual([(self.fa_key,), (self.fb_key, self.fc_key)],  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
178  | 
self.fd_key)  | 
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
179  | 
|
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
180  | 
def test_annotate_many_way_common_merge_text(self):  | 
181  | 
self.make_many_way_common_merge_text()  | 
|
182  | 
self.assertAnnotateEqual([(self.fa_key,),  | 
|
183  | 
(self.fb_key, self.fc_key, self.fe_key)],  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
184  | 
self.ff_key)  | 
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
185  | 
|
| 
4454.3.4
by John Arbash Meinel
 New work on how to resolve conflict lines.  | 
186  | 
def test_annotate_merge_and_restored(self):  | 
187  | 
self.make_merge_and_restored_text()  | 
|
188  | 
self.assertAnnotateEqual([(self.fa_key,), (self.fa_key, self.fc_key)],  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
189  | 
self.fd_key)  | 
| 
4454.3.10
by John Arbash Meinel
 Start working on 'annotate_flat' which conforms to the original spec.  | 
190  | 
|
191  | 
def test_annotate_flat_simple(self):  | 
|
192  | 
self.make_simple_text()  | 
|
193  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
|
194  | 
(self.fa_key, 'content\n'),  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
195  | 
], self.ann.annotate_flat(self.fa_key))  | 
| 
4454.3.10
by John Arbash Meinel
 Start working on 'annotate_flat' which conforms to the original spec.  | 
196  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
197  | 
(self.fb_key, 'new content\n'),  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
198  | 
], self.ann.annotate_flat(self.fb_key))  | 
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
199  | 
|
200  | 
def test_annotate_flat_merge_and_restored_text(self):  | 
|
201  | 
self.make_merge_and_restored_text()  | 
|
202  | 
        # fc is a simple dominator of fa
 | 
|
203  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
|
204  | 
(self.fc_key, 'content\n'),  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
205  | 
], self.ann.annotate_flat(self.fd_key))  | 
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
206  | 
|
207  | 
def test_annotate_common_merge_text(self):  | 
|
208  | 
self.make_common_merge_text()  | 
|
209  | 
        # there is no common point, so we just pick the lexicographical lowest
 | 
|
210  | 
        # and 'b-id' comes before 'c-id'
 | 
|
211  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
|
212  | 
(self.fb_key, 'new content\n'),  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
213  | 
], self.ann.annotate_flat(self.fd_key))  | 
| 
4454.3.12
by John Arbash Meinel
 Finish fleshing out the ability to determine a revision after conflicts.  | 
214  | 
|
215  | 
def test_annotate_many_way_common_merge_text(self):  | 
|
216  | 
self.make_many_way_common_merge_text()  | 
|
| 
4454.3.14
by John Arbash Meinel
 Had a slightly bogus test.  | 
217  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
218  | 
(self.fb_key, 'new content\n')],  | 
|
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
219  | 
self.ann.annotate_flat(self.ff_key))  | 
220  | 
||
| 
4454.3.77
by John Arbash Meinel
 Add support for compatibility with old '_break_annotation_tie' function.  | 
221  | 
def test_annotate_flat_respects_break_ann_tie(self):  | 
222  | 
tiebreaker = annotate._break_annotation_tie  | 
|
223  | 
try:  | 
|
224  | 
calls = []  | 
|
225  | 
def custom_tiebreaker(annotated_lines):  | 
|
226  | 
self.assertEqual(2, len(annotated_lines))  | 
|
227  | 
left = annotated_lines[0]  | 
|
228  | 
self.assertEqual(2, len(left))  | 
|
229  | 
self.assertEqual('new content\n', left[1])  | 
|
230  | 
right = annotated_lines[1]  | 
|
231  | 
self.assertEqual(2, len(right))  | 
|
232  | 
self.assertEqual('new content\n', right[1])  | 
|
233  | 
calls.append((left[0], right[0]))  | 
|
234  | 
                # Our custom tiebreaker takes the *largest* value, rather than
 | 
|
235  | 
                # the *smallest* value
 | 
|
236  | 
if left[0] < right[0]:  | 
|
237  | 
return right  | 
|
238  | 
else:  | 
|
239  | 
return left  | 
|
240  | 
annotate._break_annotation_tie = custom_tiebreaker  | 
|
241  | 
self.make_many_way_common_merge_text()  | 
|
242  | 
self.assertEqual([(self.fa_key, 'simple\n'),  | 
|
243  | 
(self.fe_key, 'new content\n')],  | 
|
244  | 
self.ann.annotate_flat(self.ff_key))  | 
|
245  | 
self.assertEqual([(self.fe_key, self.fc_key),  | 
|
246  | 
(self.fe_key, self.fb_key)], calls)  | 
|
247  | 
finally:  | 
|
248  | 
annotate._break_annotation_tie = tiebreaker  | 
|
249  | 
||
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
250  | 
|
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
251  | 
def test_needed_keys_simple(self):  | 
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
252  | 
self.make_simple_text()  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
253  | 
keys, ann_keys = self.ann._get_needed_keys(self.fb_key)  | 
| 
4454.3.18
by John Arbash Meinel
 Start tracking the number of children that need a given text.  | 
254  | 
self.assertEqual([self.fa_key, self.fb_key], sorted(keys))  | 
255  | 
self.assertEqual({self.fa_key: 1, self.fb_key: 1},  | 
|
256  | 
self.ann._num_needed_children)  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
257  | 
self.assertEqual(set(), ann_keys)  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
258  | 
|
259  | 
def test_needed_keys_many(self):  | 
|
260  | 
self.make_many_way_common_merge_text()  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
261  | 
keys, ann_keys = self.ann._get_needed_keys(self.ff_key)  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
262  | 
self.assertEqual([self.fa_key, self.fb_key, self.fc_key,  | 
263  | 
self.fd_key, self.fe_key, self.ff_key,  | 
|
264  | 
], sorted(keys))  | 
|
265  | 
self.assertEqual({self.fa_key: 3,  | 
|
266  | 
self.fb_key: 1,  | 
|
267  | 
self.fc_key: 1,  | 
|
268  | 
self.fd_key: 1,  | 
|
269  | 
self.fe_key: 1,  | 
|
270  | 
self.ff_key: 1,  | 
|
271  | 
}, self.ann._num_needed_children)  | 
|
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
272  | 
self.assertEqual(set(), ann_keys)  | 
273  | 
||
274  | 
def test_needed_keys_with_special_text(self):  | 
|
275  | 
self.make_many_way_common_merge_text()  | 
|
276  | 
spec_key = ('f-id', revision.CURRENT_REVISION)  | 
|
277  | 
spec_text = 'simple\nnew content\nlocally modified\n'  | 
|
278  | 
self.ann.add_special_text(spec_key, [self.fd_key, self.fe_key],  | 
|
279  | 
spec_text)  | 
|
280  | 
keys, ann_keys = self.ann._get_needed_keys(spec_key)  | 
|
281  | 
self.assertEqual([self.fa_key, self.fb_key, self.fc_key,  | 
|
282  | 
self.fd_key, self.fe_key,  | 
|
283  | 
], sorted(keys))  | 
|
284  | 
self.assertEqual([spec_key], sorted(ann_keys))  | 
|
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
285  | 
|
| 
4454.3.62
by John Arbash Meinel
 Add a test that shows when parent texts, etc, are present, we don't request again.  | 
286  | 
def test_needed_keys_with_parent_texts(self):  | 
287  | 
self.make_many_way_common_merge_text()  | 
|
288  | 
        # If 'D' and 'E' are already annotated, we don't need to extract all
 | 
|
289  | 
        # the texts
 | 
|
290  | 
        #  D   |  'simple|new content|'
 | 
|
291  | 
        #  |   |
 | 
|
292  | 
        #  |   E  'simple|new content|'
 | 
|
293  | 
        #  |  /
 | 
|
294  | 
        #  F-'    'simple|new content|'
 | 
|
295  | 
self.ann._parent_map[self.fd_key] = (self.fb_key, self.fc_key)  | 
|
296  | 
self.ann._text_cache[self.fd_key] = ['simple\n', 'new content\n']  | 
|
297  | 
self.ann._annotations_cache[self.fd_key] = [  | 
|
298  | 
(self.fa_key,),  | 
|
299  | 
(self.fb_key, self.fc_key),  | 
|
300  | 
            ]
 | 
|
301  | 
self.ann._parent_map[self.fe_key] = (self.fa_key,)  | 
|
302  | 
self.ann._text_cache[self.fe_key] = ['simple\n', 'new content\n']  | 
|
303  | 
self.ann._annotations_cache[self.fe_key] = [  | 
|
304  | 
(self.fa_key,),  | 
|
305  | 
(self.fe_key,),  | 
|
306  | 
            ]
 | 
|
307  | 
keys, ann_keys = self.ann._get_needed_keys(self.ff_key)  | 
|
308  | 
self.assertEqual([self.ff_key], sorted(keys))  | 
|
309  | 
self.assertEqual({self.fd_key: 1,  | 
|
310  | 
self.fe_key: 1,  | 
|
311  | 
self.ff_key: 1,  | 
|
312  | 
}, self.ann._num_needed_children)  | 
|
313  | 
self.assertEqual([], sorted(ann_keys))  | 
|
314  | 
||
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
315  | 
def test_record_annotation_removes_texts(self):  | 
316  | 
self.make_many_way_common_merge_text()  | 
|
317  | 
        # Populate the caches
 | 
|
318  | 
for x in self.ann._get_needed_texts(self.ff_key):  | 
|
319  | 
            continue
 | 
|
320  | 
self.assertEqual({self.fa_key: 3,  | 
|
321  | 
self.fb_key: 1,  | 
|
322  | 
self.fc_key: 1,  | 
|
323  | 
self.fd_key: 1,  | 
|
324  | 
self.fe_key: 1,  | 
|
325  | 
self.ff_key: 1,  | 
|
326  | 
}, self.ann._num_needed_children)  | 
|
327  | 
self.assertEqual([self.fa_key, self.fb_key, self.fc_key,  | 
|
328  | 
self.fd_key, self.fe_key, self.ff_key,  | 
|
329  | 
], sorted(self.ann._text_cache.keys()))  | 
|
| 
4454.3.22
by John Arbash Meinel
 Need to record the other annotations before we can record this,  | 
330  | 
self.ann._record_annotation(self.fa_key, [], [])  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
331  | 
self.ann._record_annotation(self.fb_key, [self.fa_key], [])  | 
332  | 
self.assertEqual({self.fa_key: 2,  | 
|
333  | 
self.fb_key: 1,  | 
|
334  | 
self.fc_key: 1,  | 
|
335  | 
self.fd_key: 1,  | 
|
336  | 
self.fe_key: 1,  | 
|
337  | 
self.ff_key: 1,  | 
|
338  | 
}, self.ann._num_needed_children)  | 
|
339  | 
self.assertTrue(self.fa_key in self.ann._text_cache)  | 
|
| 
4454.3.21
by John Arbash Meinel
 Assert that entries in the annotation cache also get cleaned up.  | 
340  | 
self.assertTrue(self.fa_key in self.ann._annotations_cache)  | 
| 
4454.3.22
by John Arbash Meinel
 Need to record the other annotations before we can record this,  | 
341  | 
self.ann._record_annotation(self.fc_key, [self.fa_key], [])  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
342  | 
self.ann._record_annotation(self.fd_key, [self.fb_key, self.fc_key], [])  | 
| 
4454.3.22
by John Arbash Meinel
 Need to record the other annotations before we can record this,  | 
343  | 
self.assertEqual({self.fa_key: 1,  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
344  | 
self.fb_key: 0,  | 
345  | 
self.fc_key: 0,  | 
|
346  | 
self.fd_key: 1,  | 
|
347  | 
self.fe_key: 1,  | 
|
348  | 
self.ff_key: 1,  | 
|
349  | 
}, self.ann._num_needed_children)  | 
|
350  | 
self.assertTrue(self.fa_key in self.ann._text_cache)  | 
|
| 
4454.3.21
by John Arbash Meinel
 Assert that entries in the annotation cache also get cleaned up.  | 
351  | 
self.assertTrue(self.fa_key in self.ann._annotations_cache)  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
352  | 
self.assertFalse(self.fb_key in self.ann._text_cache)  | 
| 
4454.3.22
by John Arbash Meinel
 Need to record the other annotations before we can record this,  | 
353  | 
self.assertFalse(self.fb_key in self.ann._annotations_cache)  | 
| 
4454.3.19
by John Arbash Meinel
 Have _record_annotation start to remove texts when they are no longer needed.  | 
354  | 
self.assertFalse(self.fc_key in self.ann._text_cache)  | 
| 
4454.3.22
by John Arbash Meinel
 Need to record the other annotations before we can record this,  | 
355  | 
self.assertFalse(self.fc_key in self.ann._annotations_cache)  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
356  | 
|
357  | 
def test_annotate_special_text(self):  | 
|
358  | 
        # Things like WT and PreviewTree want to annotate an arbitrary text
 | 
|
359  | 
        # ('current:') so we need a way to add that to the group of files to be
 | 
|
360  | 
        # annotated.
 | 
|
361  | 
self.make_many_way_common_merge_text()  | 
|
362  | 
        #  A-.    'simple|content|'
 | 
|
363  | 
        #  |\ \
 | 
|
364  | 
        #  B | |  'simple|new content|'
 | 
|
365  | 
        #  | | |
 | 
|
366  | 
        #  | C |  'simple|new content|'
 | 
|
367  | 
        #  |/  |
 | 
|
368  | 
        #  D   |  'simple|new content|'
 | 
|
369  | 
        #  |   |
 | 
|
370  | 
        #  |   E  'simple|new content|'
 | 
|
371  | 
        #  |  /
 | 
|
372  | 
        #  SPEC   'simple|new content|locally modified|'
 | 
|
373  | 
spec_key = ('f-id', revision.CURRENT_REVISION)  | 
|
374  | 
spec_text = 'simple\nnew content\nlocally modified\n'  | 
|
375  | 
self.ann.add_special_text(spec_key, [self.fd_key, self.fe_key],  | 
|
376  | 
spec_text)  | 
|
377  | 
self.assertAnnotateEqual([(self.fa_key,),  | 
|
378  | 
(self.fb_key, self.fc_key, self.fe_key),  | 
|
| 
4454.3.66
by John Arbash Meinel
 Implement no-graph support for the Python version.  | 
379  | 
(spec_key,),  | 
| 
4454.3.61
by John Arbash Meinel
 Start implementing an Annotator.add_special_text functionality.  | 
380  | 
], spec_key,  | 
381  | 
exp_text=spec_text)  | 
|
| 
4454.3.66
by John Arbash Meinel
 Implement no-graph support for the Python version.  | 
382  | 
|
383  | 
def test_no_graph(self):  | 
|
384  | 
self.make_no_graph_texts()  | 
|
385  | 
self.assertAnnotateEqual([(self.fa_key,),  | 
|
386  | 
(self.fa_key,),  | 
|
387  | 
], self.fa_key)  | 
|
388  | 
self.assertAnnotateEqual([(self.fb_key,),  | 
|
389  | 
(self.fb_key,),  | 
|
390  | 
], self.fb_key)  |