~bzr-pqm/bzr/bzr.dev

0.1.55 by Martin Pool
doc
1
#! /usr/bin/python2.4
2
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
3
# Copyright (C) 2005 by Canonical Ltd
4
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
20
21
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
22
"""test suite for weave algorithm"""
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
23
24
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
25
import testsweet
26
from weave import Weave, WeaveFormatError
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
27
from pprint import pformat
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
28
29
0.1.66 by Martin Pool
Cope without set/frozenset classes
30
31
try:
32
    set
33
    frozenset
34
except NameError:
35
    from sets import Set, ImmutableSet
36
    set = Set
37
    frozenset = ImmutableSet
0.1.67 by Martin Pool
More fixes to try to run on python2.3
38
    del Set, ImmutableSet
0.1.66 by Martin Pool
Cope without set/frozenset classes
39
40
41
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
42
# texts for use in testing
0.1.3 by Martin Pool
Change storage of texts for testing
43
TEXT_0 = ["Hello world"]
44
TEXT_1 = ["Hello world",
45
          "A second line"]
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
46
47
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
48
49
class TestBase(testsweet.TestBase):
50
    def check_read_write(self, k):
51
        """Check the weave k can be written & re-read."""
52
        from tempfile import TemporaryFile
53
        from weavefile import write_weave, read_weave
54
        tf = TemporaryFile()
55
56
        write_weave(k, tf)
57
        tf.seek(0)
58
        k2 = read_weave(tf)
59
60
        if k != k2:
61
            tf.seek(0)
62
            self.log('serialized weave:')
63
            self.log(tf.read())
64
            self.fail('read/write check failed')
65
        
66
        
67
68
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
69
class Easy(TestBase):
70
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
71
        k = Weave()
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
72
73
74
class StoreText(TestBase):
75
    """Store and retrieve a simple text."""
76
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
77
        k = Weave()
0.1.26 by Martin Pool
Refactor parameters to add command
78
        idx = k.add([], TEXT_0)
0.1.4 by Martin Pool
Start indexing knits by both integer and version string.
79
        self.assertEqual(k.get(idx), TEXT_0)
80
        self.assertEqual(idx, 0)
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
81
82
0.1.7 by Martin Pool
Add trivial annotate text
83
84
class AnnotateOne(TestBase):
85
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
86
        k = Weave()
0.1.26 by Martin Pool
Refactor parameters to add command
87
        k.add([], TEXT_0)
0.1.7 by Martin Pool
Add trivial annotate text
88
        self.assertEqual(k.annotate(0),
89
                         [(0, TEXT_0[0])])
90
91
0.1.5 by Martin Pool
Add test for storing two text versions.
92
class StoreTwo(TestBase):
93
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
94
        k = Weave()
0.1.5 by Martin Pool
Add test for storing two text versions.
95
0.1.26 by Martin Pool
Refactor parameters to add command
96
        idx = k.add([], TEXT_0)
0.1.5 by Martin Pool
Add test for storing two text versions.
97
        self.assertEqual(idx, 0)
98
0.1.26 by Martin Pool
Refactor parameters to add command
99
        idx = k.add([], TEXT_1)
0.1.5 by Martin Pool
Add test for storing two text versions.
100
        self.assertEqual(idx, 1)
101
102
        self.assertEqual(k.get(0), TEXT_0)
103
        self.assertEqual(k.get(1), TEXT_1)
104
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
105
        k.dump(self.TEST_LOG)
106
107
0.1.21 by Martin Pool
Start computing a delta to insert a new revision
108
0.1.55 by Martin Pool
doc
109
class DeltaAdd(TestBase):
0.1.21 by Martin Pool
Start computing a delta to insert a new revision
110
    """Detection of changes prior to inserting new revision."""
111
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
112
        k = Weave()
0.1.26 by Martin Pool
Refactor parameters to add command
113
        k.add([], ['line 1'])
0.1.21 by Martin Pool
Start computing a delta to insert a new revision
114
0.1.52 by Martin Pool
Update tests for new weave representation
115
        self.assertEqual(k._l,
116
                         [('{', 0),
117
                          'line 1',
118
                          ('}', 0),
119
                          ])
120
0.1.22 by Martin Pool
Calculate delta for new versions relative to a set of parent versions.
121
        changes = list(k._delta(set([0]),
122
                                ['line 1',
123
                                 'new line']))
0.1.21 by Martin Pool
Start computing a delta to insert a new revision
124
125
        self.log('raw changes: ' + pformat(changes))
126
0.1.52 by Martin Pool
Update tests for new weave representation
127
        # currently there are 3 lines in the weave, and we insert after them
0.1.22 by Martin Pool
Calculate delta for new versions relative to a set of parent versions.
128
        self.assertEquals(changes,
0.1.52 by Martin Pool
Update tests for new weave representation
129
                          [(3, 3, ['new line'])])
0.1.22 by Martin Pool
Calculate delta for new versions relative to a set of parent versions.
130
0.1.24 by Martin Pool
Add another change for delta of new version.
131
        changes = k._delta(set([0]),
132
                           ['top line',
133
                            'line 1'])
134
        
135
        self.assertEquals(list(changes),
0.1.54 by Martin Pool
Fix weave line calculation when making deltas
136
                          [(1, 1, ['top line'])])
0.1.24 by Martin Pool
Add another change for delta of new version.
137
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
138
        self.check_read_write(k)
0.1.24 by Martin Pool
Add another change for delta of new version.
139
0.1.21 by Martin Pool
Start computing a delta to insert a new revision
140
0.1.27 by Martin Pool
Check that version numbers passed in are reasonable
141
class InvalidAdd(TestBase):
142
    """Try to use invalid version number during add."""
143
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
144
        k = Weave()
0.1.27 by Martin Pool
Check that version numbers passed in are reasonable
145
146
        self.assertRaises(IndexError,
147
                          k.add,
148
                          [69],
149
                          ['new text!'])
150
151
0.1.26 by Martin Pool
Refactor parameters to add command
152
class InsertLines(TestBase):
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
153
    """Store a revision that adds one line to the original.
154
155
    Look at the annotations to make sure that the first line is matched
156
    and not stored repeatedly."""
157
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
158
        k = Weave()
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
159
0.1.26 by Martin Pool
Refactor parameters to add command
160
        k.add([], ['line 1'])
161
        k.add([0], ['line 1', 'line 2'])
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
162
163
        self.assertEqual(k.annotate(0),
164
                         [(0, 'line 1')])
165
0.1.25 by Martin Pool
Handle insertion of new weave layers that insert text on top of the basis
166
        self.assertEqual(k.get(1),
167
                         ['line 1',
168
                          'line 2'])
169
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
170
        self.assertEqual(k.annotate(1),
171
                         [(0, 'line 1'),
172
                          (1, 'line 2')])
173
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
174
        k.add([0], ['line 1', 'diverged line'])
175
176
        self.assertEqual(k.annotate(2),
177
                         [(0, 'line 1'),
178
                          (2, 'diverged line')])
179
0.1.54 by Martin Pool
Fix weave line calculation when making deltas
180
        text3 = ['line 1', 'middle line', 'line 2']
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
181
        k.add([0, 1],
0.1.54 by Martin Pool
Fix weave line calculation when making deltas
182
              text3)
183
184
        self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
185
186
        self.log("k._l=" + pformat(k._l))
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
187
188
        self.assertEqual(k.annotate(3),
189
                         [(0, 'line 1'),
190
                          (3, 'middle line'),
191
                          (1, 'line 2')])
192
0.1.31 by Martin Pool
Fix insertion of multiple regions, calculating the right line offset as we go.
193
        # now multiple insertions at different places
194
        k.add([0, 1, 3],
195
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
196
197
        self.assertEqual(k.annotate(4), 
198
                         [(0, 'line 1'),
199
                          (4, 'aaa'),
200
                          (3, 'middle line'),
201
                          (4, 'bbb'),
202
                          (1, 'line 2'),
203
                          (4, 'ccc')])
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
204
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
205
0.1.48 by Martin Pool
Basic parsing of delete instructions.
206
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
207
class DeleteLines(TestBase):
208
    """Deletion of lines from existing text.
209
210
    Try various texts all based on a common ancestor."""
211
    def runTest(self):
212
        k = Weave()
213
214
        base_text = ['one', 'two', 'three', 'four']
215
216
        k.add([], base_text)
217
        
218
        texts = [['one', 'two', 'three'],
219
                 ['two', 'three', 'four'],
220
                 ['one', 'four'],
221
                 ['one', 'two', 'three', 'four'],
222
                 ]
223
224
        for t in texts:
225
            ver = k.add([0], t)
226
227
        self.log('final weave:')
228
        self.log('k._l=' + pformat(k._l))
229
230
        for i in range(len(texts)):
231
            self.assertEqual(k.get(i+1),
232
                             texts[i])
233
            
234
235
236
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
237
class SuicideDelete(TestBase):
0.1.55 by Martin Pool
doc
238
    """Invalid weave which tries to add and delete simultaneously."""
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
239
    def runTest(self):
240
        k = Weave()
241
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
242
        k._v = [(),
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
243
                ]
244
        k._l = [('{', 0),
245
                'first line',
246
                ('[', 0),
247
                'deleted in 0',
248
                (']', 0),
249
                ('}', 0),
250
                ]
251
252
        self.assertRaises(WeaveFormatError,
253
                          k.get,
254
                          0)        
255
256
257
0.1.48 by Martin Pool
Basic parsing of delete instructions.
258
class CannedDelete(TestBase):
259
    """Unpack canned weave with deleted lines."""
260
    def runTest(self):
261
        k = Weave()
262
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
263
        k._v = [(),
264
                frozenset([0]),
0.1.48 by Martin Pool
Basic parsing of delete instructions.
265
                ]
266
        k._l = [('{', 0),
267
                'first line',
268
                ('[', 1),
269
                'line to be deleted',
270
                (']', 1),
271
                'last line',
272
                ('}', 0),
273
                ]
274
275
        self.assertEqual(k.get(0),
276
                         ['first line',
277
                          'line to be deleted',
278
                          'last line',
279
                          ])
280
0.1.50 by Martin Pool
Basic implementation of deletion markers
281
        self.assertEqual(k.get(1),
282
                         ['first line',
283
                          'last line',
284
                          ])
285
0.1.48 by Martin Pool
Basic parsing of delete instructions.
286
287
0.1.51 by Martin Pool
Add test for replacement lines
288
class CannedReplacement(TestBase):
289
    """Unpack canned weave with deleted lines."""
290
    def runTest(self):
291
        k = Weave()
292
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
293
        k._v = [frozenset(),
294
                frozenset([0]),
0.1.51 by Martin Pool
Add test for replacement lines
295
                ]
296
        k._l = [('{', 0),
297
                'first line',
298
                ('[', 1),
299
                'line to be deleted',
300
                (']', 1),
301
                ('{', 1),
302
                'replacement line',                
303
                ('}', 1),
304
                'last line',
305
                ('}', 0),
306
                ]
307
308
        self.assertEqual(k.get(0),
309
                         ['first line',
310
                          'line to be deleted',
311
                          'last line',
312
                          ])
313
314
        self.assertEqual(k.get(1),
315
                         ['first line',
316
                          'replacement line',
317
                          'last line',
318
                          ])
319
320
321
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
322
class BadWeave(TestBase):
323
    """Test that we trap an insert which should not occur."""
324
    def runTest(self):
325
        k = Weave()
326
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
327
        k._v = [frozenset(),
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
328
                ]
329
        k._l = ['bad line',
330
                ('{', 0),
331
                'foo {',
332
                ('{', 1),
333
                '  added in version 1',
334
                ('{', 2),
335
                '  added in v2',
336
                ('}', 2),
337
                '  also from v1',
338
                ('}', 1),
339
                '}',
340
                ('}', 0)]
341
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
342
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
343
                          k.get,
344
                          0)
345
346
347
class BadInsert(TestBase):
348
    """Test that we trap an insert which should not occur."""
349
    def runTest(self):
350
        k = Weave()
351
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
352
        k._v = [frozenset(),
353
                frozenset([0]),
354
                frozenset([0]),
355
                frozenset([0,1,2]),
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
356
                ]
357
        k._l = [('{', 0),
358
                'foo {',
359
                ('{', 1),
360
                '  added in version 1',
361
                ('{', 1),
362
                '  more in 1',
363
                ('}', 1),
364
                ('}', 1),
365
                ('}', 0)]
366
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
367
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
368
                          k.get,
369
                          0)
370
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
371
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
372
                          k.get,
373
                          1)
374
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
375
376
class InsertNested(TestBase):
377
    """Insertion with nested instructions."""
378
    def runTest(self):
379
        k = Weave()
380
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
381
        k._v = [frozenset(),
382
                frozenset([0]),
383
                frozenset([0]),
384
                frozenset([0,1,2]),
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
385
                ]
386
        k._l = [('{', 0),
387
                'foo {',
388
                ('{', 1),
389
                '  added in version 1',
0.1.42 by Martin Pool
More tests for nested insert instructions
390
                ('{', 2),
391
                '  added in v2',
392
                ('}', 2),
393
                '  also from v1',
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
394
                ('}', 1),
395
                '}',
396
                ('}', 0)]
397
398
        self.assertEqual(k.get(0),
399
                         ['foo {',
400
                          '}'])
401
402
        self.assertEqual(k.get(1),
403
                         ['foo {',
404
                          '  added in version 1',
0.1.42 by Martin Pool
More tests for nested insert instructions
405
                          '  also from v1',
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
406
                          '}'])
407
                       
0.1.44 by Martin Pool
More tests for nested insert instructions
408
        self.assertEqual(k.get(2),
409
                         ['foo {',
410
                          '  added in v2',
411
                          '}'])
412
413
        self.assertEqual(k.get(3),
414
                         ['foo {',
415
                          '  added in version 1',
416
                          '  added in v2',
417
                          '  also from v1',
418
                          '}'])
419
                         
0.1.45 by Martin Pool
doc
420
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
421
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
422
class DeleteLines2(TestBase):
0.1.30 by Martin Pool
Start adding tests for line deletion
423
    """Test recording revisions that delete lines.
424
425
    This relies on the weave having a way to represent lines knocked
426
    out by a later revision."""
427
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
428
        k = Weave()
0.1.30 by Martin Pool
Start adding tests for line deletion
429
430
        k.add([], ["line the first",
431
                   "line 2",
432
                   "line 3",
433
                   "fine"])
434
435
        self.assertEqual(len(k.get(0)), 4)
436
437
        k.add([0], ["line the first",
438
                   "fine"])
439
440
        self.assertEqual(k.get(1),
441
                         ["line the first",
442
                          "fine"])
443
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
444
        self.assertEqual(k.annotate(1),
445
                         [(0, "line the first"),
446
                          (0, "fine")])
447
0.1.30 by Martin Pool
Start adding tests for line deletion
448
0.1.26 by Martin Pool
Refactor parameters to add command
449
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
450
class IncludeVersions(TestBase):
451
    """Check texts that are stored across multiple revisions.
452
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
453
    Here we manually create a weave with particular encoding and make
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
454
    sure it unpacks properly.
455
456
    Text 0 includes nothing; text 1 includes text 0 and adds some
457
    lines.
458
    """
459
460
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
461
        k = Weave()
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
462
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
463
        k._v = [frozenset(), frozenset([0])]
0.1.39 by Martin Pool
Change to a more realistic weave structure which can represent insertions and
464
        k._l = [('{', 0),
465
                "first line",
466
                ('}', 0),
467
                ('{', 1),
468
                "second line",
469
                ('}', 1)]
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
470
471
        self.assertEqual(k.get(1),
472
                         ["first line",
473
                          "second line"])
474
475
        self.assertEqual(k.get(0),
476
                         ["first line"])
477
478
        k.dump(self.TEST_LOG)
479
0.1.5 by Martin Pool
Add test for storing two text versions.
480
0.1.14 by Martin Pool
Another test for version inclusion
481
class DivergedIncludes(TestBase):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
482
    """Weave with two diverged texts based on version 0.
0.1.14 by Martin Pool
Another test for version inclusion
483
    """
484
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
485
        k = Weave()
0.1.14 by Martin Pool
Another test for version inclusion
486
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
487
        k._v = [frozenset(),
488
                frozenset([0]),
489
                frozenset([0]),
0.1.17 by Martin Pool
Use objects rather than tuples for tracking VerInfo for
490
                ]
0.1.39 by Martin Pool
Change to a more realistic weave structure which can represent insertions and
491
        k._l = [('{', 0),
492
                "first line",
493
                ('}', 0),
494
                ('{', 1),
495
                "second line",
496
                ('}', 1),
497
                ('{', 2),
498
                "alternative second line",
499
                ('}', 2),                
500
                ]
0.1.14 by Martin Pool
Another test for version inclusion
501
502
        self.assertEqual(k.get(0),
503
                         ["first line"])
504
505
        self.assertEqual(k.get(1),
506
                         ["first line",
507
                          "second line"])
508
509
        self.assertEqual(k.get(2),
510
                         ["first line",
511
                          "alternative second line"])
512
0.1.78 by Martin Pool
Rename Weave.get_included to inclusions and getiter to get_iter
513
        self.assertEqual(k.inclusions([2]),
0.1.77 by Martin Pool
New Weave.get_included() does transitive expansion
514
                         set([0, 2]))
515
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
516
517
518
class ReplaceLine(TestBase):
519
    def runTest(self):
520
        k = Weave()
521
522
        text0 = ['cheddar', 'stilton', 'gruyere']
523
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
524
        
525
        k.add([], text0)
526
        k.add([0], text1)
527
528
        self.log('k._l=' + pformat(k._l))
529
0.1.59 by Martin Pool
More modification tests
530
        self.assertEqual(k.get(0), text0)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
531
        self.assertEqual(k.get(1), text1)
532
0.1.64 by Martin Pool
Add test for merging versions
533
534
535
class Merge(TestBase):
0.1.95 by Martin Pool
- preliminary merge conflict detection
536
    """Storage of versions that merge diverged parents"""
0.1.64 by Martin Pool
Add test for merging versions
537
    def runTest(self):
538
        k = Weave()
539
540
        texts = [['header'],
541
                 ['header', '', 'line from 1'],
542
                 ['header', '', 'line from 2', 'more from 2'],
543
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
544
                 ]
545
546
        k.add([], texts[0])
547
        k.add([0], texts[1])
548
        k.add([0], texts[2])
549
        k.add([0, 1, 2], texts[3])
550
551
        for i, t in enumerate(texts):
552
            self.assertEqual(k.get(i), t)
553
554
        self.assertEqual(k.annotate(3),
555
                         [(0, 'header'),
556
                          (1, ''),
557
                          (1, 'line from 1'),
558
                          (3, 'fixup line'),
559
                          (2, 'line from 2'),
560
                          ])
561
0.1.78 by Martin Pool
Rename Weave.get_included to inclusions and getiter to get_iter
562
        self.assertEqual(k.inclusions([3]),
0.1.77 by Martin Pool
New Weave.get_included() does transitive expansion
563
                         set([0, 1, 2, 3]))
564
0.1.64 by Martin Pool
Add test for merging versions
565
        self.log('k._l=' + pformat(k._l))
566
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
567
        self.check_read_write(k)
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
568
569
0.1.95 by Martin Pool
- preliminary merge conflict detection
570
class Conflicts(TestBase):
571
    """Test detection of conflicting regions during a merge.
572
573
    A base version is inserted, then two descendents try to
574
    insert different lines in the same place.  These should be
575
    reported as a possible conflict and forwarded to the user."""
576
    def runTest(self):
577
        return  # NOT RUN
578
        k = Weave()
579
580
        k.add([], ['aaa', 'bbb'])
581
        k.add([0], ['aaa', '111', 'bbb'])
582
        k.add([1], ['aaa', '222', 'bbb'])
583
584
        merged = k.merge([1, 2])
585
586
        self.assertEquals([[['aaa']],
587
                           [['111'], ['222']],
588
                           [['bbb']]])
589
590
591
592
class NonConflict(TestBase):
593
    """Two descendants insert compatible changes.
594
595
    No conflict should be reported."""
596
    def runTest(self):
597
        return  # NOT RUN
598
        k = Weave()
599
600
        k.add([], ['aaa', 'bbb'])
601
        k.add([0], ['111', 'aaa', 'ccc', 'bbb'])
602
        k.add([1], ['aaa', 'ccc', 'bbb', '222'])
603
604
    
605
    
606
607
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
608
class AutoMerge(TestBase):
609
    def runTest(self):
610
        k = Weave()
611
612
        texts = [['header', 'aaa', 'bbb'],
613
                 ['header', 'aaa', 'line from 1', 'bbb'],
614
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
615
                 ]
616
617
        k.add([], texts[0])
618
        k.add([0], texts[1])
619
        k.add([0], texts[2])
620
621
        self.log('k._l=' + pformat(k._l))
622
0.1.95 by Martin Pool
- preliminary merge conflict detection
623
        m = list(k.mash_iter([0, 1, 2]))
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
624
625
        self.assertEqual(m,
626
                         ['header', 'aaa',
627
                          'line from 1',
628
                          'bbb',
629
                          'line from 2', 'more from 2'])
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
630
        
631
632
633
class Khayyam(TestBase):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
634
    """Test changes to multi-line texts, and read/write"""
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
635
    def runTest(self):
636
        rawtexts = [
637
            """A Book of Verses underneath the Bough,
638
            A Jug of Wine, a Loaf of Bread, -- and Thou
639
            Beside me singing in the Wilderness --
640
            Oh, Wilderness were Paradise enow!""",
641
            
642
            """A Book of Verses underneath the Bough,
643
            A Jug of Wine, a Loaf of Bread, -- and Thou
644
            Beside me singing in the Wilderness --
645
            Oh, Wilderness were Paradise now!""",
0.1.59 by Martin Pool
More modification tests
646
647
            """A Book of poems underneath the tree,
648
            A Jug of Wine, a Loaf of Bread,
649
            and Thou
650
            Beside me singing in the Wilderness --
651
            Oh, Wilderness were Paradise now!
652
653
            -- O. Khayyam""",
654
655
            """A Book of Verses underneath the Bough,
656
            A Jug of Wine, a Loaf of Bread,
657
            and Thou
658
            Beside me singing in the Wilderness --
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
659
            Oh, Wilderness were Paradise now!""",
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
660
            ]
661
        texts = [[l.strip() for l in t.split('\n')] for t in rawtexts]
662
663
        k = Weave()
664
        parents = set()
665
        for t in texts:
0.1.78 by Martin Pool
Rename Weave.get_included to inclusions and getiter to get_iter
666
            ver = k.add(list(parents), t)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
667
            parents.add(ver)
668
0.1.59 by Martin Pool
More modification tests
669
        self.log("k._l=" + pformat(k._l))
670
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
671
        for i, t in enumerate(texts):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
672
            self.assertEqual(k.get(i), t)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
673
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
674
        self.check_read_write(k)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
675
676
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
677
def testweave():
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
678
    import testsweet
679
    from unittest import TestSuite, TestLoader
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
680
    import testweave
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
681
 
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
682
    tl = TestLoader()
683
    suite = TestSuite()
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
684
    suite.addTest(tl.loadTestsFromModule(testweave))
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
685
    
0.1.15 by Martin Pool
Fix inverted shell return code for testknit
686
    return int(not testsweet.run_suite(suite)) # for shell 0=true
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
687
688
689
if __name__ == '__main__':
690
    import sys
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
691
    sys.exit(testweave())
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
692