/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_weave.py

  • Committer: Jelmer Vernooij
  • Date: 2018-05-06 11:48:54 UTC
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@jelmer.uk-20180506114854-h4qd9ojaqy8wxjsd
Move .mailmap to root.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
 
38
38
# texts for use in testing
39
 
TEXT_0 = [b"Hello world"]
40
 
TEXT_1 = [b"Hello world",
41
 
          b"A second line"]
 
39
TEXT_0 = ["Hello world"]
 
40
TEXT_1 = ["Hello world",
 
41
          "A second line"]
42
42
 
43
43
 
44
44
class TestBase(TestCase):
69
69
    """Weave __contains__ operator"""
70
70
 
71
71
    def runTest(self):
72
 
        k = Weave(get_scope=lambda: None)
73
 
        self.assertFalse(b'foo' in k)
74
 
        k.add_lines(b'foo', [], TEXT_1)
75
 
        self.assertTrue(b'foo' in k)
 
72
        k = Weave(get_scope=lambda:None)
 
73
        self.assertFalse('foo' in k)
 
74
        k.add_lines('foo', [], TEXT_1)
 
75
        self.assertTrue('foo' in k)
76
76
 
77
77
 
78
78
class Easy(TestBase):
79
79
 
80
80
    def runTest(self):
81
 
        Weave()
 
81
        k = Weave()
82
82
 
83
83
 
84
84
class AnnotateOne(TestBase):
85
85
 
86
86
    def runTest(self):
87
87
        k = Weave()
88
 
        k.add_lines(b'text0', [], TEXT_0)
89
 
        self.assertEqual(k.annotate(b'text0'),
90
 
                         [(b'text0', TEXT_0[0])])
 
88
        k.add_lines('text0', [], TEXT_0)
 
89
        self.assertEqual(k.annotate('text0'),
 
90
                         [('text0', TEXT_0[0])])
91
91
 
92
92
 
93
93
class InvalidAdd(TestBase):
98
98
 
99
99
        self.assertRaises(errors.RevisionNotPresent,
100
100
                          k.add_lines,
101
 
                          b'text0',
102
 
                          [b'69'],
103
 
                          [b'new text!'])
 
101
                          'text0',
 
102
                          ['69'],
 
103
                          ['new text!'])
104
104
 
105
105
 
106
106
class RepeatedAdd(TestBase):
108
108
 
109
109
    def test_duplicate_add(self):
110
110
        k = Weave()
111
 
        idx = k.add_lines(b'text0', [], TEXT_0)
112
 
        idx2 = k.add_lines(b'text0', [], TEXT_0)
 
111
        idx = k.add_lines('text0', [], TEXT_0)
 
112
        idx2 = k.add_lines('text0', [], TEXT_0)
113
113
        self.assertEqual(idx, idx2)
114
114
 
115
115
 
117
117
 
118
118
    def runTest(self):
119
119
        k = Weave()
120
 
        k.add_lines(b'basis', [], TEXT_0)
121
 
        k.add_lines(b'text0', [], TEXT_0)
 
120
        k.add_lines('basis', [], TEXT_0)
 
121
        idx = k.add_lines('text0', [], TEXT_0)
122
122
        self.assertRaises(errors.RevisionAlreadyPresent,
123
123
                          k.add_lines,
124
 
                          b'text0',
 
124
                          'text0',
125
125
                          [],
126
 
                          [b'not the same text'])
 
126
                          ['not the same text'])
127
127
        self.assertRaises(errors.RevisionAlreadyPresent,
128
128
                          k.add_lines,
129
 
                          b'text0',
130
 
                          [b'basis'],         # not the right parents
 
129
                          'text0',
 
130
                          ['basis'],         # not the right parents
131
131
                          TEXT_0)
132
132
 
133
133
 
136
136
 
137
137
    Look at the annotations to make sure that the first line is matched
138
138
    and not stored repeatedly."""
139
 
 
140
139
    def runTest(self):
141
140
        k = Weave()
142
141
 
143
 
        k.add_lines(b'text0', [], [b'line 1'])
144
 
        k.add_lines(b'text1', [b'text0'], [b'line 1', b'line 2'])
 
142
        k.add_lines('text0', [], ['line 1'])
 
143
        k.add_lines('text1', ['text0'], ['line 1', 'line 2'])
145
144
 
146
 
        self.assertEqual(k.annotate(b'text0'),
147
 
                         [(b'text0', b'line 1')])
 
145
        self.assertEqual(k.annotate('text0'),
 
146
                         [('text0', 'line 1')])
148
147
 
149
148
        self.assertEqual(k.get_lines(1),
150
 
                         [b'line 1',
151
 
                          b'line 2'])
152
 
 
153
 
        self.assertEqual(k.annotate(b'text1'),
154
 
                         [(b'text0', b'line 1'),
155
 
                          (b'text1', b'line 2')])
156
 
 
157
 
        k.add_lines(b'text2', [b'text0'], [b'line 1', b'diverged line'])
158
 
 
159
 
        self.assertEqual(k.annotate(b'text2'),
160
 
                         [(b'text0', b'line 1'),
161
 
                          (b'text2', b'diverged line')])
162
 
 
163
 
        text3 = [b'line 1', b'middle line', b'line 2']
164
 
        k.add_lines(b'text3',
165
 
                    [b'text0', b'text1'],
166
 
                    text3)
167
 
 
168
 
        # self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]),
169
 
        # text3))))
 
149
                         ['line 1',
 
150
                          'line 2'])
 
151
 
 
152
        self.assertEqual(k.annotate('text1'),
 
153
                         [('text0', 'line 1'),
 
154
                          ('text1', 'line 2')])
 
155
 
 
156
        k.add_lines('text2', ['text0'], ['line 1', 'diverged line'])
 
157
 
 
158
        self.assertEqual(k.annotate('text2'),
 
159
                         [('text0', 'line 1'),
 
160
                          ('text2', 'diverged line')])
 
161
 
 
162
        text3 = ['line 1', 'middle line', 'line 2']
 
163
        k.add_lines('text3',
 
164
              ['text0', 'text1'],
 
165
              text3)
 
166
 
 
167
        # self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
170
168
 
171
169
        self.log("k._weave=" + pformat(k._weave))
172
170
 
173
 
        self.assertEqual(k.annotate(b'text3'),
174
 
                         [(b'text0', b'line 1'),
175
 
                          (b'text3', b'middle line'),
176
 
                          (b'text1', b'line 2')])
 
171
        self.assertEqual(k.annotate('text3'),
 
172
                         [('text0', 'line 1'),
 
173
                          ('text3', 'middle line'),
 
174
                          ('text1', 'line 2')])
177
175
 
178
176
        # now multiple insertions at different places
179
 
        k.add_lines(
180
 
            b'text4', [b'text0', b'text1', b'text3'],
181
 
            [b'line 1', b'aaa', b'middle line', b'bbb', b'line 2', b'ccc'])
 
177
        k.add_lines('text4',
 
178
              ['text0', 'text1', 'text3'],
 
179
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
182
180
 
183
 
        self.assertEqual(k.annotate(b'text4'),
184
 
                         [(b'text0', b'line 1'),
185
 
                          (b'text4', b'aaa'),
186
 
                          (b'text3', b'middle line'),
187
 
                          (b'text4', b'bbb'),
188
 
                          (b'text1', b'line 2'),
189
 
                          (b'text4', b'ccc')])
 
181
        self.assertEqual(k.annotate('text4'),
 
182
                         [('text0', 'line 1'),
 
183
                          ('text4', 'aaa'),
 
184
                          ('text3', 'middle line'),
 
185
                          ('text4', 'bbb'),
 
186
                          ('text1', 'line 2'),
 
187
                          ('text4', 'ccc')])
190
188
 
191
189
 
192
190
class DeleteLines(TestBase):
193
191
    """Deletion of lines from existing text.
194
192
 
195
193
    Try various texts all based on a common ancestor."""
196
 
 
197
194
    def runTest(self):
198
195
        k = Weave()
199
196
 
200
 
        base_text = [b'one', b'two', b'three', b'four']
201
 
 
202
 
        k.add_lines(b'text0', [], base_text)
203
 
 
204
 
        texts = [[b'one', b'two', b'three'],
205
 
                 [b'two', b'three', b'four'],
206
 
                 [b'one', b'four'],
207
 
                 [b'one', b'two', b'three', b'four'],
 
197
        base_text = ['one', 'two', 'three', 'four']
 
198
 
 
199
        k.add_lines('text0', [], base_text)
 
200
 
 
201
        texts = [['one', 'two', 'three'],
 
202
                 ['two', 'three', 'four'],
 
203
                 ['one', 'four'],
 
204
                 ['one', 'two', 'three', 'four'],
208
205
                 ]
209
206
 
210
207
        i = 1
211
208
        for t in texts:
212
 
            k.add_lines(b'text%d' % i, [b'text0'], t)
 
209
            ver = k.add_lines('text%d' % i,
 
210
                        ['text0'], t)
213
211
            i += 1
214
212
 
215
213
        self.log('final weave:')
216
214
        self.log('k._weave=' + pformat(k._weave))
217
215
 
218
216
        for i in range(len(texts)):
219
 
            self.assertEqual(k.get_lines(i + 1),
 
217
            self.assertEqual(k.get_lines(i+1),
220
218
                             texts[i])
221
219
 
222
220
 
223
221
class SuicideDelete(TestBase):
224
222
    """Invalid weave which tries to add and delete simultaneously."""
225
 
 
226
223
    def runTest(self):
227
224
        k = Weave()
228
225
 
229
226
        k._parents = [(),
230
 
                      ]
231
 
        k._weave = [(b'{', 0),
232
 
                    b'first line',
233
 
                    (b'[', 0),
234
 
                    b'deleted in 0',
235
 
                    (b']', 0),
236
 
                    (b'}', 0),
237
 
                    ]
238
 
        # SKIPPED
 
227
                ]
 
228
        k._weave = [('{', 0),
 
229
                'first line',
 
230
                ('[', 0),
 
231
                'deleted in 0',
 
232
                (']', 0),
 
233
                ('}', 0),
 
234
                ]
 
235
        ################################### SKIPPED
239
236
        # Weave.get doesn't trap this anymore
240
237
        return
241
238
 
246
243
 
247
244
class CannedDelete(TestBase):
248
245
    """Unpack canned weave with deleted lines."""
249
 
 
250
246
    def runTest(self):
251
247
        k = Weave()
252
248
 
253
249
        k._parents = [(),
254
 
                      frozenset([0]),
255
 
                      ]
256
 
        k._weave = [(b'{', 0),
257
 
                    b'first line',
258
 
                    (b'[', 1),
259
 
                    b'line to be deleted',
260
 
                    (b']', 1),
261
 
                    b'last line',
262
 
                    (b'}', 0),
263
 
                    ]
264
 
        k._sha1s = [
265
 
            sha_string(b'first lineline to be deletedlast line'),
266
 
            sha_string(b'first linelast line')]
 
250
                frozenset([0]),
 
251
                ]
 
252
        k._weave = [('{', 0),
 
253
                'first line',
 
254
                ('[', 1),
 
255
                'line to be deleted',
 
256
                (']', 1),
 
257
                'last line',
 
258
                ('}', 0),
 
259
                ]
 
260
        k._sha1s = [sha_string('first lineline to be deletedlast line')
 
261
                  , sha_string('first linelast line')]
267
262
 
268
263
        self.assertEqual(k.get_lines(0),
269
 
                         [b'first line',
270
 
                          b'line to be deleted',
271
 
                          b'last line',
 
264
                         ['first line',
 
265
                          'line to be deleted',
 
266
                          'last line',
272
267
                          ])
273
268
 
274
269
        self.assertEqual(k.get_lines(1),
275
 
                         [b'first line',
276
 
                          b'last line',
 
270
                         ['first line',
 
271
                          'last line',
277
272
                          ])
278
273
 
279
274
 
280
275
class CannedReplacement(TestBase):
281
276
    """Unpack canned weave with deleted lines."""
282
 
 
283
277
    def runTest(self):
284
278
        k = Weave()
285
279
 
286
280
        k._parents = [frozenset(),
287
 
                      frozenset([0]),
288
 
                      ]
289
 
        k._weave = [(b'{', 0),
290
 
                    b'first line',
291
 
                    (b'[', 1),
292
 
                    b'line to be deleted',
293
 
                    (b']', 1),
294
 
                    (b'{', 1),
295
 
                    b'replacement line',
296
 
                    (b'}', 1),
297
 
                    b'last line',
298
 
                    (b'}', 0),
299
 
                    ]
300
 
        k._sha1s = [
301
 
            sha_string(b'first lineline to be deletedlast line'),
302
 
            sha_string(b'first linereplacement linelast line')]
 
281
                frozenset([0]),
 
282
                ]
 
283
        k._weave = [('{', 0),
 
284
                'first line',
 
285
                ('[', 1),
 
286
                'line to be deleted',
 
287
                (']', 1),
 
288
                ('{', 1),
 
289
                'replacement line',
 
290
                ('}', 1),
 
291
                'last line',
 
292
                ('}', 0),
 
293
                ]
 
294
        k._sha1s = [sha_string('first lineline to be deletedlast line')
 
295
                  , sha_string('first linereplacement linelast line')]
303
296
 
304
297
        self.assertEqual(k.get_lines(0),
305
 
                         [b'first line',
306
 
                          b'line to be deleted',
307
 
                          b'last line',
 
298
                         ['first line',
 
299
                          'line to be deleted',
 
300
                          'last line',
308
301
                          ])
309
302
 
310
303
        self.assertEqual(k.get_lines(1),
311
 
                         [b'first line',
312
 
                          b'replacement line',
313
 
                          b'last line',
 
304
                         ['first line',
 
305
                          'replacement line',
 
306
                          'last line',
314
307
                          ])
315
308
 
316
309
 
317
310
class BadWeave(TestBase):
318
311
    """Test that we trap an insert which should not occur."""
319
 
 
320
312
    def runTest(self):
321
313
        k = Weave()
322
314
 
323
315
        k._parents = [frozenset(),
324
 
                      ]
325
 
        k._weave = [b'bad line',
326
 
                    (b'{', 0),
327
 
                    b'foo {',
328
 
                    (b'{', 1),
329
 
                    b'  added in version 1',
330
 
                    (b'{', 2),
331
 
                    b'  added in v2',
332
 
                    (b'}', 2),
333
 
                    b'  also from v1',
334
 
                    (b'}', 1),
335
 
                    b'}',
336
 
                    (b'}', 0)]
 
316
                ]
 
317
        k._weave = ['bad line',
 
318
                ('{', 0),
 
319
                'foo {',
 
320
                ('{', 1),
 
321
                '  added in version 1',
 
322
                ('{', 2),
 
323
                '  added in v2',
 
324
                ('}', 2),
 
325
                '  also from v1',
 
326
                ('}', 1),
 
327
                '}',
 
328
                ('}', 0)]
337
329
 
338
 
        # SKIPPED
 
330
        ################################### SKIPPED
339
331
        # Weave.get doesn't trap this anymore
340
332
        return
341
333
 
 
334
 
342
335
        self.assertRaises(WeaveFormatError,
343
336
                          k.get,
344
337
                          0)
346
339
 
347
340
class BadInsert(TestBase):
348
341
    """Test that we trap an insert which should not occur."""
349
 
 
350
342
    def runTest(self):
351
343
        k = Weave()
352
344
 
353
345
        k._parents = [frozenset(),
354
 
                      frozenset([0]),
355
 
                      frozenset([0]),
356
 
                      frozenset([0, 1, 2]),
357
 
                      ]
358
 
        k._weave = [(b'{', 0),
359
 
                    b'foo {',
360
 
                    (b'{', 1),
361
 
                    b'  added in version 1',
362
 
                    (b'{', 1),
363
 
                    b'  more in 1',
364
 
                    (b'}', 1),
365
 
                    (b'}', 1),
366
 
                    (b'}', 0)]
 
346
                frozenset([0]),
 
347
                frozenset([0]),
 
348
                frozenset([0, 1, 2]),
 
349
                ]
 
350
        k._weave = [('{', 0),
 
351
                'foo {',
 
352
                ('{', 1),
 
353
                '  added in version 1',
 
354
                ('{', 1),
 
355
                '  more in 1',
 
356
                ('}', 1),
 
357
                ('}', 1),
 
358
                ('}', 0)]
 
359
 
367
360
 
368
361
        # this is not currently enforced by get
369
 
        return
 
362
        return  ##########################################
370
363
 
371
364
        self.assertRaises(WeaveFormatError,
372
365
                          k.get,
379
372
 
380
373
class InsertNested(TestBase):
381
374
    """Insertion with nested instructions."""
382
 
 
383
375
    def runTest(self):
384
376
        k = Weave()
385
377
 
386
378
        k._parents = [frozenset(),
387
 
                      frozenset([0]),
388
 
                      frozenset([0]),
389
 
                      frozenset([0, 1, 2]),
390
 
                      ]
391
 
        k._weave = [(b'{', 0),
392
 
                    b'foo {',
393
 
                    (b'{', 1),
394
 
                    b'  added in version 1',
395
 
                    (b'{', 2),
396
 
                    b'  added in v2',
397
 
                    (b'}', 2),
398
 
                    b'  also from v1',
399
 
                    (b'}', 1),
400
 
                    b'}',
401
 
                    (b'}', 0)]
 
379
                frozenset([0]),
 
380
                frozenset([0]),
 
381
                frozenset([0, 1, 2]),
 
382
                ]
 
383
        k._weave = [('{', 0),
 
384
                'foo {',
 
385
                ('{', 1),
 
386
                '  added in version 1',
 
387
                ('{', 2),
 
388
                '  added in v2',
 
389
                ('}', 2),
 
390
                '  also from v1',
 
391
                ('}', 1),
 
392
                '}',
 
393
                ('}', 0)]
402
394
 
403
 
        k._sha1s = [
404
 
            sha_string(b'foo {}'),
405
 
            sha_string(b'foo {  added in version 1  also from v1}'),
406
 
            sha_string(b'foo {  added in v2}'),
407
 
            sha_string(
408
 
                b'foo {  added in version 1  added in v2  also from v1}')
409
 
            ]
 
395
        k._sha1s = [sha_string('foo {}')
 
396
                  , sha_string('foo {  added in version 1  also from v1}')
 
397
                  , sha_string('foo {  added in v2}')
 
398
                  , sha_string('foo {  added in version 1  added in v2  also from v1}')
 
399
                  ]
410
400
 
411
401
        self.assertEqual(k.get_lines(0),
412
 
                         [b'foo {',
413
 
                          b'}'])
 
402
                         ['foo {',
 
403
                          '}'])
414
404
 
415
405
        self.assertEqual(k.get_lines(1),
416
 
                         [b'foo {',
417
 
                          b'  added in version 1',
418
 
                          b'  also from v1',
419
 
                          b'}'])
 
406
                         ['foo {',
 
407
                          '  added in version 1',
 
408
                          '  also from v1',
 
409
                          '}'])
420
410
 
421
411
        self.assertEqual(k.get_lines(2),
422
 
                         [b'foo {',
423
 
                          b'  added in v2',
424
 
                          b'}'])
 
412
                         ['foo {',
 
413
                          '  added in v2',
 
414
                          '}'])
425
415
 
426
416
        self.assertEqual(k.get_lines(3),
427
 
                         [b'foo {',
428
 
                          b'  added in version 1',
429
 
                          b'  added in v2',
430
 
                          b'  also from v1',
431
 
                          b'}'])
 
417
                         ['foo {',
 
418
                          '  added in version 1',
 
419
                          '  added in v2',
 
420
                          '  also from v1',
 
421
                          '}'])
432
422
 
433
423
 
434
424
class DeleteLines2(TestBase):
436
426
 
437
427
    This relies on the weave having a way to represent lines knocked
438
428
    out by a later revision."""
439
 
 
440
429
    def runTest(self):
441
430
        k = Weave()
442
431
 
443
 
        k.add_lines(b'text0', [], [b"line the first",
444
 
                                   b"line 2",
445
 
                                   b"line 3",
446
 
                                   b"fine"])
 
432
        k.add_lines('text0', [], ["line the first",
 
433
                   "line 2",
 
434
                   "line 3",
 
435
                   "fine"])
447
436
 
448
437
        self.assertEqual(len(k.get_lines(0)), 4)
449
438
 
450
 
        k.add_lines(b'text1', [b'text0'], [b"line the first",
451
 
                                           b"fine"])
 
439
        k.add_lines('text1', ['text0'], ["line the first",
 
440
                   "fine"])
452
441
 
453
442
        self.assertEqual(k.get_lines(1),
454
 
                         [b"line the first",
455
 
                          b"fine"])
 
443
                         ["line the first",
 
444
                          "fine"])
456
445
 
457
 
        self.assertEqual(k.annotate(b'text1'),
458
 
                         [(b'text0', b"line the first"),
459
 
                          (b'text0', b"fine")])
 
446
        self.assertEqual(k.annotate('text1'),
 
447
                         [('text0', "line the first"),
 
448
                          ('text0', "fine")])
460
449
 
461
450
 
462
451
class IncludeVersions(TestBase):
473
462
        k = Weave()
474
463
 
475
464
        k._parents = [frozenset(), frozenset([0])]
476
 
        k._weave = [(b'{', 0),
477
 
                    b"first line",
478
 
                    (b'}', 0),
479
 
                    (b'{', 1),
480
 
                    b"second line",
481
 
                    (b'}', 1)]
 
465
        k._weave = [('{', 0),
 
466
                "first line",
 
467
                ('}', 0),
 
468
                ('{', 1),
 
469
                "second line",
 
470
                ('}', 1)]
482
471
 
483
 
        k._sha1s = [sha_string(b'first line'), sha_string(
484
 
            b'first linesecond line')]
 
472
        k._sha1s = [sha_string('first line')
 
473
                  , sha_string('first linesecond line')]
485
474
 
486
475
        self.assertEqual(k.get_lines(1),
487
 
                         [b"first line",
488
 
                          b"second line"])
 
476
                         ["first line",
 
477
                          "second line"])
489
478
 
490
479
        self.assertEqual(k.get_lines(0),
491
 
                         [b"first line"])
 
480
                         ["first line"])
492
481
 
493
482
 
494
483
class DivergedIncludes(TestBase):
495
484
    """Weave with two diverged texts based on version 0.
496
485
    """
497
 
 
498
486
    def runTest(self):
499
487
        # FIXME make the weave, dont poke at it.
500
488
        k = Weave()
501
489
 
502
 
        k._names = [b'0', b'1', b'2']
503
 
        k._name_map = {b'0': 0, b'1': 1, b'2': 2}
 
490
        k._names = ['0', '1', '2']
 
491
        k._name_map = {'0':0, '1':1, '2':2}
504
492
        k._parents = [frozenset(),
505
 
                      frozenset([0]),
506
 
                      frozenset([0]),
507
 
                      ]
508
 
        k._weave = [(b'{', 0),
509
 
                    b"first line",
510
 
                    (b'}', 0),
511
 
                    (b'{', 1),
512
 
                    b"second line",
513
 
                    (b'}', 1),
514
 
                    (b'{', 2),
515
 
                    b"alternative second line",
516
 
                    (b'}', 2),
517
 
                    ]
 
493
                frozenset([0]),
 
494
                frozenset([0]),
 
495
                ]
 
496
        k._weave = [('{', 0),
 
497
                "first line",
 
498
                ('}', 0),
 
499
                ('{', 1),
 
500
                "second line",
 
501
                ('}', 1),
 
502
                ('{', 2),
 
503
                "alternative second line",
 
504
                ('}', 2),
 
505
                ]
518
506
 
519
 
        k._sha1s = [
520
 
            sha_string(b'first line'),
521
 
            sha_string(b'first linesecond line'),
522
 
            sha_string(b'first linealternative second line')]
 
507
        k._sha1s = [sha_string('first line')
 
508
                  , sha_string('first linesecond line')
 
509
                  , sha_string('first linealternative second line')]
523
510
 
524
511
        self.assertEqual(k.get_lines(0),
525
 
                         [b"first line"])
 
512
                         ["first line"])
526
513
 
527
514
        self.assertEqual(k.get_lines(1),
528
 
                         [b"first line",
529
 
                          b"second line"])
530
 
 
531
 
        self.assertEqual(k.get_lines(b'2'),
532
 
                         [b"first line",
533
 
                          b"alternative second line"])
534
 
 
535
 
        self.assertEqual(list(k.get_ancestry([b'2'])),
536
 
                         [b'0', b'2'])
 
515
                         ["first line",
 
516
                          "second line"])
 
517
 
 
518
        self.assertEqual(k.get_lines('2'),
 
519
                         ["first line",
 
520
                          "alternative second line"])
 
521
 
 
522
        self.assertEqual(list(k.get_ancestry(['2'])),
 
523
                         ['0', '2'])
537
524
 
538
525
 
539
526
class ReplaceLine(TestBase):
540
527
    def runTest(self):
541
528
        k = Weave()
542
529
 
543
 
        text0 = [b'cheddar', b'stilton', b'gruyere']
544
 
        text1 = [b'cheddar', b'blue vein', b'neufchatel', b'chevre']
 
530
        text0 = ['cheddar', 'stilton', 'gruyere']
 
531
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
545
532
 
546
 
        k.add_lines(b'text0', [], text0)
547
 
        k.add_lines(b'text1', [b'text0'], text1)
 
533
        k.add_lines('text0', [], text0)
 
534
        k.add_lines('text1', ['text0'], text1)
548
535
 
549
536
        self.log('k._weave=' + pformat(k._weave))
550
537
 
558
545
    def runTest(self):
559
546
        k = Weave()
560
547
 
561
 
        texts = [
562
 
            [b'header'],
563
 
            [b'header', b'', b'line from 1'],
564
 
            [b'header', b'', b'line from 2', b'more from 2'],
565
 
            [b'header', b'', b'line from 1', b'fixup line', b'line from 2'],
566
 
            ]
 
548
        texts = [['header'],
 
549
                 ['header', '', 'line from 1'],
 
550
                 ['header', '', 'line from 2', 'more from 2'],
 
551
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
 
552
                 ]
567
553
 
568
 
        k.add_lines(b'text0', [], texts[0])
569
 
        k.add_lines(b'text1', [b'text0'], texts[1])
570
 
        k.add_lines(b'text2', [b'text0'], texts[2])
571
 
        k.add_lines(b'merge', [b'text0', b'text1', b'text2'], texts[3])
 
554
        k.add_lines('text0', [], texts[0])
 
555
        k.add_lines('text1', ['text0'], texts[1])
 
556
        k.add_lines('text2', ['text0'], texts[2])
 
557
        k.add_lines('merge', ['text0', 'text1', 'text2'], texts[3])
572
558
 
573
559
        for i, t in enumerate(texts):
574
560
            self.assertEqual(k.get_lines(i), t)
575
561
 
576
 
        self.assertEqual(k.annotate(b'merge'),
577
 
                         [(b'text0', b'header'),
578
 
                          (b'text1', b''),
579
 
                          (b'text1', b'line from 1'),
580
 
                          (b'merge', b'fixup line'),
581
 
                          (b'text2', b'line from 2'),
 
562
        self.assertEqual(k.annotate('merge'),
 
563
                         [('text0', 'header'),
 
564
                          ('text1', ''),
 
565
                          ('text1', 'line from 1'),
 
566
                          ('merge', 'fixup line'),
 
567
                          ('text2', 'line from 2'),
582
568
                          ])
583
569
 
584
 
        self.assertEqual(list(k.get_ancestry([b'merge'])),
585
 
                         [b'text0', b'text1', b'text2', b'merge'])
 
570
        self.assertEqual(list(k.get_ancestry(['merge'])),
 
571
                         ['text0', 'text1', 'text2', 'merge'])
586
572
 
587
573
        self.log('k._weave=' + pformat(k._weave))
588
574
 
595
581
    A base version is inserted, then two descendents try to
596
582
    insert different lines in the same place.  These should be
597
583
    reported as a possible conflict and forwarded to the user."""
598
 
 
599
584
    def runTest(self):
600
585
        return  # NOT RUN
601
586
        k = Weave()
602
587
 
603
 
        k.add_lines([], [b'aaa', b'bbb'])
604
 
        k.add_lines([0], [b'aaa', b'111', b'bbb'])
605
 
        k.add_lines([1], [b'aaa', b'222', b'bbb'])
606
 
 
607
 
        k.merge([1, 2])
608
 
 
609
 
        self.assertEqual([[[b'aaa']],
610
 
                          [[b'111'], [b'222']],
611
 
                          [[b'bbb']]])
 
588
        k.add_lines([], ['aaa', 'bbb'])
 
589
        k.add_lines([0], ['aaa', '111', 'bbb'])
 
590
        k.add_lines([1], ['aaa', '222', 'bbb'])
 
591
 
 
592
        merged = k.merge([1, 2])
 
593
 
 
594
        self.assertEqual([[['aaa']],
 
595
                           [['111'], ['222']],
 
596
                           [['bbb']]])
612
597
 
613
598
 
614
599
class NonConflict(TestBase):
615
600
    """Two descendants insert compatible changes.
616
601
 
617
602
    No conflict should be reported."""
618
 
 
619
603
    def runTest(self):
620
604
        return  # NOT RUN
621
605
        k = Weave()
622
606
 
623
 
        k.add_lines([], [b'aaa', b'bbb'])
624
 
        k.add_lines([0], [b'111', b'aaa', b'ccc', b'bbb'])
625
 
        k.add_lines([1], [b'aaa', b'ccc', b'bbb', b'222'])
 
607
        k.add_lines([], ['aaa', 'bbb'])
 
608
        k.add_lines([0], ['111', 'aaa', 'ccc', 'bbb'])
 
609
        k.add_lines([1], ['aaa', 'ccc', 'bbb', '222'])
626
610
 
627
611
 
628
612
class Khayyam(TestBase):
630
614
 
631
615
    def test_multi_line_merge(self):
632
616
        rawtexts = [
633
 
            b"""A Book of Verses underneath the Bough,
 
617
            """A Book of Verses underneath the Bough,
634
618
            A Jug of Wine, a Loaf of Bread, -- and Thou
635
619
            Beside me singing in the Wilderness --
636
620
            Oh, Wilderness were Paradise enow!""",
637
621
 
638
 
            b"""A Book of Verses underneath the Bough,
 
622
            """A Book of Verses underneath the Bough,
639
623
            A Jug of Wine, a Loaf of Bread, -- and Thou
640
624
            Beside me singing in the Wilderness --
641
625
            Oh, Wilderness were Paradise now!""",
642
626
 
643
 
            b"""A Book of poems underneath the tree,
 
627
            """A Book of poems underneath the tree,
644
628
            A Jug of Wine, a Loaf of Bread,
645
629
            and Thou
646
630
            Beside me singing in the Wilderness --
648
632
 
649
633
            -- O. Khayyam""",
650
634
 
651
 
            b"""A Book of Verses underneath the Bough,
 
635
            """A Book of Verses underneath the Bough,
652
636
            A Jug of Wine, a Loaf of Bread,
653
637
            and Thou
654
638
            Beside me singing in the Wilderness --
655
639
            Oh, Wilderness were Paradise now!""",
656
640
            ]
657
 
        texts = [[l.strip() for l in t.split(b'\n')] for t in rawtexts]
 
641
        texts = [[l.strip() for l in t.split('\n')] for t in rawtexts]
658
642
 
659
643
        k = Weave()
660
644
        parents = set()
661
645
        i = 0
662
646
        for t in texts:
663
 
            k.add_lines(b'text%d' % i, list(parents), t)
664
 
            parents.add(b'text%d' % i)
 
647
            ver = k.add_lines('text%d' % i,
 
648
                        list(parents), t)
 
649
            parents.add('text%d' % i)
665
650
            i += 1
666
651
 
667
652
        self.log("k._weave=" + pformat(k._weave))
677
662
    def setUp(self):
678
663
        super(JoinWeavesTests, self).setUp()
679
664
        self.weave1 = Weave()
680
 
        self.lines1 = [b'hello\n']
681
 
        self.lines3 = [b'hello\n', b'cruel\n', b'world\n']
682
 
        self.weave1.add_lines(b'v1', [], self.lines1)
683
 
        self.weave1.add_lines(b'v2', [b'v1'], [b'hello\n', b'world\n'])
684
 
        self.weave1.add_lines(b'v3', [b'v2'], self.lines3)
 
665
        self.lines1 = ['hello\n']
 
666
        self.lines3 = ['hello\n', 'cruel\n', 'world\n']
 
667
        self.weave1.add_lines('v1', [], self.lines1)
 
668
        self.weave1.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
 
669
        self.weave1.add_lines('v3', ['v2'], self.lines3)
685
670
 
686
671
    def test_written_detection(self):
687
672
        # Test detection of weave file corruption.
691
676
        # but it at least helps verify the data you get, is what you want.
692
677
 
693
678
        w = Weave()
694
 
        w.add_lines(b'v1', [], [b'hello\n'])
695
 
        w.add_lines(b'v2', [b'v1'], [b'hello\n', b'there\n'])
 
679
        w.add_lines('v1', [], ['hello\n'])
 
680
        w.add_lines('v2', ['v1'], ['hello\n', 'there\n'])
696
681
 
697
682
        tmpf = BytesIO()
698
683
        write_weave(w, tmpf)
699
684
 
700
 
        # Because we are corrupting, we need to make sure we have the exact
701
 
        # text
702
 
        self.assertEqual(
703
 
            b'# bzr weave file v5\n'
704
 
            b'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
705
 
            b'i 0\n1 90f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
706
 
            b'w\n{ 0\n. hello\n}\n{ 1\n. there\n}\nW\n',
707
 
            tmpf.getvalue())
 
685
        # Because we are corrupting, we need to make sure we have the exact text
 
686
        self.assertEqual('# bzr weave file v5\n'
 
687
                          'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
 
688
                          'i 0\n1 90f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
 
689
                          'w\n{ 0\n. hello\n}\n{ 1\n. there\n}\nW\n',
 
690
                          tmpf.getvalue())
708
691
 
709
692
        # Change a single letter
710
 
        tmpf = BytesIO(
711
 
            b'# bzr weave file v5\n'
712
 
            b'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
713
 
            b'i 0\n1 90f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
714
 
            b'w\n{ 0\n. hello\n}\n{ 1\n. There\n}\nW\n')
 
693
        tmpf = BytesIO(b'# bzr weave file v5\n'
 
694
                       b'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
 
695
                       b'i 0\n1 90f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
 
696
                       b'w\n{ 0\n. hello\n}\n{ 1\n. There\n}\nW\n')
715
697
 
716
698
        w = read_weave(tmpf)
717
699
 
718
 
        self.assertEqual(b'hello\n', w.get_text(b'v1'))
719
 
        self.assertRaises(WeaveInvalidChecksum, w.get_text, b'v2')
720
 
        self.assertRaises(WeaveInvalidChecksum, w.get_lines, b'v2')
 
700
        self.assertEqual('hello\n', w.get_text('v1'))
 
701
        self.assertRaises(WeaveInvalidChecksum, w.get_text, 'v2')
 
702
        self.assertRaises(WeaveInvalidChecksum, w.get_lines, 'v2')
721
703
        self.assertRaises(WeaveInvalidChecksum, w.check)
722
704
 
723
705
        # Change the sha checksum
724
 
        tmpf = BytesIO(
725
 
            b'# bzr weave file v5\n'
726
 
            b'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
727
 
            b'i 0\n1 f0f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
728
 
            b'w\n{ 0\n. hello\n}\n{ 1\n. there\n}\nW\n')
 
706
        tmpf = BytesIO(b'# bzr weave file v5\n'
 
707
                       b'i\n1 f572d396fae9206628714fb2ce00f72e94f2258f\nn v1\n\n'
 
708
                       b'i 0\n1 f0f265c6e75f1c8f9ab76dcf85528352c5f215ef\nn v2\n\n'
 
709
                       b'w\n{ 0\n. hello\n}\n{ 1\n. there\n}\nW\n')
729
710
 
730
711
        w = read_weave(tmpf)
731
712
 
732
 
        self.assertEqual(b'hello\n', w.get_text(b'v1'))
733
 
        self.assertRaises(WeaveInvalidChecksum, w.get_text, b'v2')
734
 
        self.assertRaises(WeaveInvalidChecksum, w.get_lines, b'v2')
 
713
        self.assertEqual('hello\n', w.get_text('v1'))
 
714
        self.assertRaises(WeaveInvalidChecksum, w.get_text, 'v2')
 
715
        self.assertRaises(WeaveInvalidChecksum, w.get_lines, 'v2')
735
716
        self.assertRaises(WeaveInvalidChecksum, w.check)
736
717
 
737
718
 
740
721
    def test_allow_reserved_false(self):
741
722
        w = Weave('name', allow_reserved=False)
742
723
        # Add lines is checked at the WeaveFile level, not at the Weave level
743
 
        w.add_lines(b'name:', [], TEXT_1)
 
724
        w.add_lines('name:', [], TEXT_1)
744
725
        # But get_lines is checked at this level
745
 
        self.assertRaises(errors.ReservedId, w.get_lines, b'name:')
 
726
        self.assertRaises(errors.ReservedId, w.get_lines, 'name:')
746
727
 
747
728
    def test_allow_reserved_true(self):
748
729
        w = Weave('name', allow_reserved=True)
749
 
        w.add_lines(b'name:', [], TEXT_1)
750
 
        self.assertEqual(TEXT_1, w.get_lines(b'name:'))
 
730
        w.add_lines('name:', [], TEXT_1)
 
731
        self.assertEqual(TEXT_1, w.get_lines('name:'))
751
732
 
752
733
 
753
734
class InstrumentedWeave(Weave):