~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__annotator.py

  • Committer: John Arbash Meinel
  • Date: 2009-07-06 18:59:24 UTC
  • mto: This revision was merged to the branch mainline in revision 4522.
  • Revision ID: john@arbash-meinel.com-20090706185924-qlhn1j607117lgdj
Start implementing an Annotator.add_special_text functionality.

The Python implementation supports it. Basically, it is meant to allow things
like WT and PreviewTree to insert the 'current' content into the graph, so that
we can get local modifications into the annotations.
There is also some work here to get support for texts that are already cached
in the annotator. So that we avoid extracting them, and can shortcut the
history.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for Annotators."""
18
18
 
19
19
from bzrlib import (
 
20
    _annotator_py,
20
21
    errors,
21
22
    knit,
22
 
    _annotator_py,
 
23
    revision,
23
24
    tests,
24
25
    )
25
26
 
77
78
        # This assumes nothing special happens during __init__, which may be
78
79
        # valid
79
80
        self.ann = self.module.Annotator(self.vf)
 
81
        #  A    'simple|content|'
 
82
        #  |
 
83
        #  B    'simple|new content|'
80
84
        self.vf.add_lines(self.fa_key, [], ['simple\n', 'content\n'])
81
85
        self.vf.add_lines(self.fb_key, [self.fa_key],
82
86
                          ['simple\n', 'new content\n'])
83
87
 
84
88
    def make_merge_text(self):
85
89
        self.make_simple_text()
 
90
        #  A    'simple|content|'
 
91
        #  |\
 
92
        #  B |  'simple|new content|'
 
93
        #  | |
 
94
        #  | C  'simple|from c|content|'
 
95
        #  |/
 
96
        #  D    'simple|from c|new content|introduced in merge|'
86
97
        self.vf.add_lines(self.fc_key, [self.fa_key],
87
98
                          ['simple\n', 'from c\n', 'content\n'])
88
99
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
92
103
    def make_common_merge_text(self):
93
104
        """Both sides of the merge will have introduced a line."""
94
105
        self.make_simple_text()
 
106
        #  A    'simple|content|'
 
107
        #  |\
 
108
        #  B |  'simple|new content|'
 
109
        #  | |
 
110
        #  | C  'simple|new content|'
 
111
        #  |/
 
112
        #  D    'simple|new content|'
95
113
        self.vf.add_lines(self.fc_key, [self.fa_key],
96
114
                          ['simple\n', 'new content\n'])
97
115
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
99
117
 
100
118
    def make_many_way_common_merge_text(self):
101
119
        self.make_simple_text()
 
120
        #  A-.    'simple|content|'
 
121
        #  |\ \
 
122
        #  B | |  'simple|new content|'
 
123
        #  | | |
 
124
        #  | C |  'simple|new content|'
 
125
        #  |/  |
 
126
        #  D   |  'simple|new content|'
 
127
        #  |   |
 
128
        #  |   E  'simple|new content|'
 
129
        #  |  /
 
130
        #  F-'    'simple|new content|'
102
131
        self.vf.add_lines(self.fc_key, [self.fa_key],
103
132
                          ['simple\n', 'new content\n'])
104
133
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
110
139
 
111
140
    def make_merge_and_restored_text(self):
112
141
        self.make_simple_text()
 
142
        #  A    'simple|content|'
 
143
        #  |\
 
144
        #  B |  'simple|new content|'
 
145
        #  | |
 
146
        #  C |  'simple|content|' # reverted to A
 
147
        #   \|
 
148
        #    D  'simple|content|'
113
149
        # c reverts back to 'a' for the new content line
114
150
        self.vf.add_lines(self.fc_key, [self.fb_key],
115
151
                          ['simple\n', 'content\n'])
117
153
        self.vf.add_lines(self.fd_key, [self.fa_key, self.fc_key],
118
154
                          ['simple\n', 'content\n'])
119
155
 
120
 
    def assertAnnotateEqual(self, expected_annotation, annotator, key):
121
 
        annotation, lines = annotator.annotate(key)
 
156
    def assertAnnotateEqual(self, expected_annotation, key, exp_text=None):
 
157
        annotation, lines = self.ann.annotate(key)
122
158
        self.assertEqual(expected_annotation, annotation)
123
 
        record = self.vf.get_record_stream([key], 'unordered', True).next()
124
 
        exp_text = record.get_bytes_as('fulltext')
 
159
        if exp_text is None:
 
160
            record = self.vf.get_record_stream([key], 'unordered', True).next()
 
161
            exp_text = record.get_bytes_as('fulltext')
125
162
        self.assertEqualDiff(exp_text, ''.join(lines))
126
163
 
127
164
    def test_annotate_missing(self):
131
168
 
132
169
    def test_annotate_simple(self):
133
170
        self.make_simple_text()
134
 
        self.assertAnnotateEqual([(self.fa_key,)]*2, self.ann, self.fa_key)
135
 
        self.assertAnnotateEqual([(self.fa_key,), (self.fb_key,)],
136
 
                                 self.ann, self.fb_key)
 
171
        self.assertAnnotateEqual([(self.fa_key,)]*2, self.fa_key)
 
172
        self.assertAnnotateEqual([(self.fa_key,), (self.fb_key,)], self.fb_key)
137
173
 
138
174
    def test_annotate_merge_text(self):
139
175
        self.make_merge_text()
140
176
        self.assertAnnotateEqual([(self.fa_key,), (self.fc_key,),
141
177
                                  (self.fb_key,), (self.fd_key,)],
142
 
                                 self.ann, self.fd_key)
 
178
                                 self.fd_key)
143
179
 
144
180
    def test_annotate_common_merge_text(self):
145
181
        self.make_common_merge_text()
146
182
        self.assertAnnotateEqual([(self.fa_key,), (self.fb_key, self.fc_key)],
147
 
                                 self.ann, self.fd_key)
 
183
                                 self.fd_key)
148
184
 
149
185
    def test_annotate_many_way_common_merge_text(self):
150
186
        self.make_many_way_common_merge_text()
151
187
        self.assertAnnotateEqual([(self.fa_key,),
152
188
                                  (self.fb_key, self.fc_key, self.fe_key)],
153
 
                                 self.ann, self.ff_key)
 
189
                                 self.ff_key)
154
190
 
155
191
    def test_annotate_merge_and_restored(self):
156
192
        self.make_merge_and_restored_text()
157
193
        self.assertAnnotateEqual([(self.fa_key,), (self.fa_key, self.fc_key)],
158
 
                                 self.ann, self.fd_key)
 
194
                                 self.fd_key)
159
195
 
160
196
    def test_annotate_flat_simple(self):
161
197
        self.make_simple_text()
190
226
 
191
227
    def test_needed_keys_simple(self):
192
228
        self.make_simple_text()
193
 
        keys = self.ann._get_needed_keys(self.fb_key)
 
229
        keys, ann_keys = self.ann._get_needed_keys(self.fb_key)
194
230
        self.assertEqual([self.fa_key, self.fb_key], sorted(keys))
195
231
        self.assertEqual({self.fa_key: 1, self.fb_key: 1},
196
232
                         self.ann._num_needed_children)
 
233
        self.assertEqual(set(), ann_keys)
197
234
 
198
235
    def test_needed_keys_many(self):
199
236
        self.make_many_way_common_merge_text()
200
 
        keys = self.ann._get_needed_keys(self.ff_key)
 
237
        keys, ann_keys = self.ann._get_needed_keys(self.ff_key)
201
238
        self.assertEqual([self.fa_key, self.fb_key, self.fc_key,
202
239
                          self.fd_key, self.fe_key, self.ff_key,
203
240
                         ], sorted(keys))
208
245
                          self.fe_key: 1,
209
246
                          self.ff_key: 1,
210
247
                         }, self.ann._num_needed_children)
 
248
        self.assertEqual(set(), ann_keys)
 
249
 
 
250
    def test_needed_keys_with_special_text(self):
 
251
        self.make_many_way_common_merge_text()
 
252
        spec_key = ('f-id', revision.CURRENT_REVISION)
 
253
        spec_text = 'simple\nnew content\nlocally modified\n'
 
254
        self.ann.add_special_text(spec_key, [self.fd_key, self.fe_key],
 
255
                                  spec_text)
 
256
        keys, ann_keys = self.ann._get_needed_keys(spec_key)
 
257
        self.assertEqual([self.fa_key, self.fb_key, self.fc_key,
 
258
                          self.fd_key, self.fe_key,
 
259
                         ], sorted(keys))
 
260
        self.assertEqual([spec_key], sorted(ann_keys))
211
261
 
212
262
    def test_record_annotation_removes_texts(self):
213
263
        self.make_many_way_common_merge_text()
250
300
        self.assertFalse(self.fb_key in self.ann._annotations_cache)
251
301
        self.assertFalse(self.fc_key in self.ann._text_cache)
252
302
        self.assertFalse(self.fc_key in self.ann._annotations_cache)
 
303
 
 
304
    def test_annotate_special_text(self):
 
305
        # Things like WT and PreviewTree want to annotate an arbitrary text
 
306
        # ('current:') so we need a way to add that to the group of files to be
 
307
        # annotated.
 
308
        self.make_many_way_common_merge_text()
 
309
        #  A-.    'simple|content|'
 
310
        #  |\ \
 
311
        #  B | |  'simple|new content|'
 
312
        #  | | |
 
313
        #  | C |  'simple|new content|'
 
314
        #  |/  |
 
315
        #  D   |  'simple|new content|'
 
316
        #  |   |
 
317
        #  |   E  'simple|new content|'
 
318
        #  |  /
 
319
        #  SPEC   'simple|new content|locally modified|'
 
320
        spec_key = ('f-id', revision.CURRENT_REVISION)
 
321
        spec_text = 'simple\nnew content\nlocally modified\n'
 
322
        self.ann.add_special_text(spec_key, [self.fd_key, self.fe_key],
 
323
                                  spec_text)
 
324
        self.assertAnnotateEqual([(self.fa_key,),
 
325
                                  (self.fb_key, self.fc_key, self.fe_key),
 
326
                                  (spec_key,)
 
327
                                 ], spec_key,
 
328
                                 exp_text=spec_text)