/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
872 by Martin Pool
- update testweave
26
from bzrlib.weave import Weave, WeaveFormatError
27
from bzrlib.weavefile import write_weave, read_weave
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
28
from pprint import pformat
924 by Martin Pool
- Add IntSet class
29
from bzrlib.intset import IntSet
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
30
0.1.66 by Martin Pool
Cope without set/frozenset classes
31
32
try:
33
    set
34
    frozenset
35
except NameError:
36
    from sets import Set, ImmutableSet
37
    set = Set
38
    frozenset = ImmutableSet
0.1.67 by Martin Pool
More fixes to try to run on python2.3
39
    del Set, ImmutableSet
0.1.66 by Martin Pool
Cope without set/frozenset classes
40
41
42
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
43
# texts for use in testing
0.1.3 by Martin Pool
Change storage of texts for testing
44
TEXT_0 = ["Hello world"]
45
TEXT_1 = ["Hello world",
46
          "A second line"]
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
47
48
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
49
50
class TestBase(testsweet.TestBase):
51
    def check_read_write(self, k):
52
        """Check the weave k can be written & re-read."""
53
        from tempfile import TemporaryFile
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.27 by Martin Pool
Check that version numbers passed in are reasonable
109
class InvalidAdd(TestBase):
110
    """Try to use invalid version number during add."""
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.27 by Martin Pool
Check that version numbers passed in are reasonable
113
872 by Martin Pool
- update testweave
114
        self.assertRaises(ValueError,
0.1.27 by Martin Pool
Check that version numbers passed in are reasonable
115
                          k.add,
116
                          [69],
117
                          ['new text!'])
118
119
0.1.26 by Martin Pool
Refactor parameters to add command
120
class InsertLines(TestBase):
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
121
    """Store a revision that adds one line to the original.
122
123
    Look at the annotations to make sure that the first line is matched
124
    and not stored repeatedly."""
125
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
126
        k = Weave()
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
127
0.1.26 by Martin Pool
Refactor parameters to add command
128
        k.add([], ['line 1'])
129
        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
130
131
        self.assertEqual(k.annotate(0),
132
                         [(0, 'line 1')])
133
0.1.25 by Martin Pool
Handle insertion of new weave layers that insert text on top of the basis
134
        self.assertEqual(k.get(1),
135
                         ['line 1',
136
                          'line 2'])
137
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
138
        self.assertEqual(k.annotate(1),
139
                         [(0, 'line 1'),
140
                          (1, 'line 2')])
141
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
142
        k.add([0], ['line 1', 'diverged line'])
143
144
        self.assertEqual(k.annotate(2),
145
                         [(0, 'line 1'),
146
                          (2, 'diverged line')])
147
0.1.54 by Martin Pool
Fix weave line calculation when making deltas
148
        text3 = ['line 1', 'middle line', 'line 2']
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
149
        k.add([0, 1],
0.1.54 by Martin Pool
Fix weave line calculation when making deltas
150
              text3)
151
152
        self.log("changes to text3: " + pformat(list(k._delta(set([0, 1]), text3))))
153
154
        self.log("k._l=" + pformat(k._l))
0.1.28 by Martin Pool
More tests for insertion of lines in new versions.
155
156
        self.assertEqual(k.annotate(3),
157
                         [(0, 'line 1'),
158
                          (3, 'middle line'),
159
                          (1, 'line 2')])
160
0.1.31 by Martin Pool
Fix insertion of multiple regions, calculating the right line offset as we go.
161
        # now multiple insertions at different places
162
        k.add([0, 1, 3],
163
              ['line 1', 'aaa', 'middle line', 'bbb', 'line 2', 'ccc'])
164
165
        self.assertEqual(k.annotate(4), 
166
                         [(0, 'line 1'),
167
                          (4, 'aaa'),
168
                          (3, 'middle line'),
169
                          (4, 'bbb'),
170
                          (1, 'line 2'),
171
                          (4, 'ccc')])
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
172
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
173
0.1.48 by Martin Pool
Basic parsing of delete instructions.
174
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
175
class DeleteLines(TestBase):
176
    """Deletion of lines from existing text.
177
178
    Try various texts all based on a common ancestor."""
179
    def runTest(self):
180
        k = Weave()
181
182
        base_text = ['one', 'two', 'three', 'four']
183
184
        k.add([], base_text)
185
        
186
        texts = [['one', 'two', 'three'],
187
                 ['two', 'three', 'four'],
188
                 ['one', 'four'],
189
                 ['one', 'two', 'three', 'four'],
190
                 ]
191
192
        for t in texts:
193
            ver = k.add([0], t)
194
195
        self.log('final weave:')
196
        self.log('k._l=' + pformat(k._l))
197
198
        for i in range(len(texts)):
199
            self.assertEqual(k.get(i+1),
200
                             texts[i])
201
            
202
203
204
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
205
class SuicideDelete(TestBase):
0.1.55 by Martin Pool
doc
206
    """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
207
    def runTest(self):
208
        k = Weave()
209
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
210
        k._v = [(),
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
211
                ]
212
        k._l = [('{', 0),
213
                'first line',
214
                ('[', 0),
215
                'deleted in 0',
216
                (']', 0),
217
                ('}', 0),
218
                ]
891 by Martin Pool
- fix up refactoring of weave
219
        ################################### SKIPPED
220
        # Weave.get doesn't trap this anymore
221
        return 
0.1.49 by Martin Pool
Add another constraint: revisions should not delete text that they
222
223
        self.assertRaises(WeaveFormatError,
224
                          k.get,
225
                          0)        
226
227
228
0.1.48 by Martin Pool
Basic parsing of delete instructions.
229
class CannedDelete(TestBase):
230
    """Unpack canned weave with deleted lines."""
231
    def runTest(self):
232
        k = Weave()
233
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
234
        k._v = [(),
235
                frozenset([0]),
0.1.48 by Martin Pool
Basic parsing of delete instructions.
236
                ]
237
        k._l = [('{', 0),
238
                'first line',
239
                ('[', 1),
240
                'line to be deleted',
241
                (']', 1),
242
                'last line',
243
                ('}', 0),
244
                ]
245
246
        self.assertEqual(k.get(0),
247
                         ['first line',
248
                          'line to be deleted',
249
                          'last line',
250
                          ])
251
0.1.50 by Martin Pool
Basic implementation of deletion markers
252
        self.assertEqual(k.get(1),
253
                         ['first line',
254
                          'last line',
255
                          ])
256
0.1.48 by Martin Pool
Basic parsing of delete instructions.
257
258
0.1.51 by Martin Pool
Add test for replacement lines
259
class CannedReplacement(TestBase):
260
    """Unpack canned weave with deleted lines."""
261
    def runTest(self):
262
        k = Weave()
263
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
264
        k._v = [frozenset(),
265
                frozenset([0]),
0.1.51 by Martin Pool
Add test for replacement lines
266
                ]
267
        k._l = [('{', 0),
268
                'first line',
269
                ('[', 1),
270
                'line to be deleted',
271
                (']', 1),
272
                ('{', 1),
273
                'replacement line',                
274
                ('}', 1),
275
                'last line',
276
                ('}', 0),
277
                ]
278
279
        self.assertEqual(k.get(0),
280
                         ['first line',
281
                          'line to be deleted',
282
                          'last line',
283
                          ])
284
285
        self.assertEqual(k.get(1),
286
                         ['first line',
287
                          'replacement line',
288
                          'last line',
289
                          ])
290
291
292
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
293
class BadWeave(TestBase):
294
    """Test that we trap an insert which should not occur."""
295
    def runTest(self):
296
        k = Weave()
297
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
298
        k._v = [frozenset(),
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
299
                ]
300
        k._l = ['bad line',
301
                ('{', 0),
302
                'foo {',
303
                ('{', 1),
304
                '  added in version 1',
305
                ('{', 2),
306
                '  added in v2',
307
                ('}', 2),
308
                '  also from v1',
309
                ('}', 1),
310
                '}',
311
                ('}', 0)]
312
891 by Martin Pool
- fix up refactoring of weave
313
        ################################### SKIPPED
314
        # Weave.get doesn't trap this anymore
315
        return 
316
317
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
318
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
319
                          k.get,
320
                          0)
321
322
323
class BadInsert(TestBase):
324
    """Test that we trap an insert which should not occur."""
325
    def runTest(self):
326
        k = Weave()
327
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
328
        k._v = [frozenset(),
329
                frozenset([0]),
330
                frozenset([0]),
331
                frozenset([0,1,2]),
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
332
                ]
333
        k._l = [('{', 0),
334
                'foo {',
335
                ('{', 1),
336
                '  added in version 1',
337
                ('{', 1),
338
                '  more in 1',
339
                ('}', 1),
340
                ('}', 1),
341
                ('}', 0)]
342
891 by Martin Pool
- fix up refactoring of weave
343
344
        # this is not currently enforced by get
345
        return  ##########################################
346
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
347
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
348
                          k.get,
349
                          0)
350
0.1.47 by Martin Pool
New WeaveError and WeaveFormatError rather than assertions.
351
        self.assertRaises(WeaveFormatError,
0.1.46 by Martin Pool
More constraints on structure of weave, and checks that they work
352
                          k.get,
353
                          1)
354
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
355
356
class InsertNested(TestBase):
357
    """Insertion with nested instructions."""
358
    def runTest(self):
359
        k = Weave()
360
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
361
        k._v = [frozenset(),
362
                frozenset([0]),
363
                frozenset([0]),
364
                frozenset([0,1,2]),
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
365
                ]
366
        k._l = [('{', 0),
367
                'foo {',
368
                ('{', 1),
369
                '  added in version 1',
0.1.42 by Martin Pool
More tests for nested insert instructions
370
                ('{', 2),
371
                '  added in v2',
372
                ('}', 2),
373
                '  also from v1',
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
374
                ('}', 1),
375
                '}',
376
                ('}', 0)]
377
378
        self.assertEqual(k.get(0),
379
                         ['foo {',
380
                          '}'])
381
382
        self.assertEqual(k.get(1),
383
                         ['foo {',
384
                          '  added in version 1',
0.1.42 by Martin Pool
More tests for nested insert instructions
385
                          '  also from v1',
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
386
                          '}'])
387
                       
0.1.44 by Martin Pool
More tests for nested insert instructions
388
        self.assertEqual(k.get(2),
389
                         ['foo {',
390
                          '  added in v2',
391
                          '}'])
392
393
        self.assertEqual(k.get(3),
394
                         ['foo {',
395
                          '  added in version 1',
396
                          '  added in v2',
397
                          '  also from v1',
398
                          '}'])
399
                         
0.1.45 by Martin Pool
doc
400
0.1.40 by Martin Pool
Add test for extracting from weave with nested insertions
401
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
402
class DeleteLines2(TestBase):
0.1.30 by Martin Pool
Start adding tests for line deletion
403
    """Test recording revisions that delete lines.
404
405
    This relies on the weave having a way to represent lines knocked
406
    out by a later revision."""
407
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
408
        k = Weave()
0.1.30 by Martin Pool
Start adding tests for line deletion
409
410
        k.add([], ["line the first",
411
                   "line 2",
412
                   "line 3",
413
                   "fine"])
414
415
        self.assertEqual(len(k.get(0)), 4)
416
417
        k.add([0], ["line the first",
418
                   "fine"])
419
420
        self.assertEqual(k.get(1),
421
                         ["line the first",
422
                          "fine"])
423
0.1.56 by Martin Pool
Handle deletion of lines by marking the region with a deletion
424
        self.assertEqual(k.annotate(1),
425
                         [(0, "line the first"),
426
                          (0, "fine")])
427
0.1.30 by Martin Pool
Start adding tests for line deletion
428
0.1.26 by Martin Pool
Refactor parameters to add command
429
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
430
class IncludeVersions(TestBase):
431
    """Check texts that are stored across multiple revisions.
432
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
433
    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
434
    sure it unpacks properly.
435
436
    Text 0 includes nothing; text 1 includes text 0 and adds some
437
    lines.
438
    """
439
440
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
441
        k = Weave()
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
442
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
443
        k._v = [frozenset(), frozenset([0])]
0.1.39 by Martin Pool
Change to a more realistic weave structure which can represent insertions and
444
        k._l = [('{', 0),
445
                "first line",
446
                ('}', 0),
447
                ('{', 1),
448
                "second line",
449
                ('}', 1)]
0.1.13 by Martin Pool
Knit structure now allows for versions to include the lines present in other
450
451
        self.assertEqual(k.get(1),
452
                         ["first line",
453
                          "second line"])
454
455
        self.assertEqual(k.get(0),
456
                         ["first line"])
457
458
        k.dump(self.TEST_LOG)
459
0.1.5 by Martin Pool
Add test for storing two text versions.
460
0.1.14 by Martin Pool
Another test for version inclusion
461
class DivergedIncludes(TestBase):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
462
    """Weave with two diverged texts based on version 0.
0.1.14 by Martin Pool
Another test for version inclusion
463
    """
464
    def runTest(self):
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
465
        k = Weave()
0.1.14 by Martin Pool
Another test for version inclusion
466
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
467
        k._v = [frozenset(),
468
                frozenset([0]),
469
                frozenset([0]),
0.1.17 by Martin Pool
Use objects rather than tuples for tracking VerInfo for
470
                ]
0.1.39 by Martin Pool
Change to a more realistic weave structure which can represent insertions and
471
        k._l = [('{', 0),
472
                "first line",
473
                ('}', 0),
474
                ('{', 1),
475
                "second line",
476
                ('}', 1),
477
                ('{', 2),
478
                "alternative second line",
479
                ('}', 2),                
480
                ]
0.1.14 by Martin Pool
Another test for version inclusion
481
482
        self.assertEqual(k.get(0),
483
                         ["first line"])
484
485
        self.assertEqual(k.get(1),
486
                         ["first line",
487
                          "second line"])
488
489
        self.assertEqual(k.get(2),
490
                         ["first line",
491
                          "alternative second line"])
492
924 by Martin Pool
- Add IntSet class
493
        self.assertEqual(list(k.inclusions([2])),
494
                         [0, 2])
0.1.77 by Martin Pool
New Weave.get_included() does transitive expansion
495
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
496
497
498
class ReplaceLine(TestBase):
499
    def runTest(self):
500
        k = Weave()
501
502
        text0 = ['cheddar', 'stilton', 'gruyere']
503
        text1 = ['cheddar', 'blue vein', 'neufchatel', 'chevre']
504
        
505
        k.add([], text0)
506
        k.add([0], text1)
507
508
        self.log('k._l=' + pformat(k._l))
509
0.1.59 by Martin Pool
More modification tests
510
        self.assertEqual(k.get(0), text0)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
511
        self.assertEqual(k.get(1), text1)
512
0.1.64 by Martin Pool
Add test for merging versions
513
514
515
class Merge(TestBase):
0.1.95 by Martin Pool
- preliminary merge conflict detection
516
    """Storage of versions that merge diverged parents"""
0.1.64 by Martin Pool
Add test for merging versions
517
    def runTest(self):
518
        k = Weave()
519
520
        texts = [['header'],
521
                 ['header', '', 'line from 1'],
522
                 ['header', '', 'line from 2', 'more from 2'],
523
                 ['header', '', 'line from 1', 'fixup line', 'line from 2'],
524
                 ]
525
526
        k.add([], texts[0])
527
        k.add([0], texts[1])
528
        k.add([0], texts[2])
529
        k.add([0, 1, 2], texts[3])
530
531
        for i, t in enumerate(texts):
532
            self.assertEqual(k.get(i), t)
533
534
        self.assertEqual(k.annotate(3),
535
                         [(0, 'header'),
536
                          (1, ''),
537
                          (1, 'line from 1'),
538
                          (3, 'fixup line'),
539
                          (2, 'line from 2'),
540
                          ])
541
924 by Martin Pool
- Add IntSet class
542
        self.assertEqual(list(k.inclusions([3])),
543
                         [0, 1, 2, 3])
0.1.77 by Martin Pool
New Weave.get_included() does transitive expansion
544
0.1.64 by Martin Pool
Add test for merging versions
545
        self.log('k._l=' + pformat(k._l))
546
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
547
        self.check_read_write(k)
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
548
549
0.1.95 by Martin Pool
- preliminary merge conflict detection
550
class Conflicts(TestBase):
551
    """Test detection of conflicting regions during a merge.
552
553
    A base version is inserted, then two descendents try to
554
    insert different lines in the same place.  These should be
555
    reported as a possible conflict and forwarded to the user."""
556
    def runTest(self):
557
        return  # NOT RUN
558
        k = Weave()
559
560
        k.add([], ['aaa', 'bbb'])
561
        k.add([0], ['aaa', '111', 'bbb'])
562
        k.add([1], ['aaa', '222', 'bbb'])
563
564
        merged = k.merge([1, 2])
565
566
        self.assertEquals([[['aaa']],
567
                           [['111'], ['222']],
568
                           [['bbb']]])
569
570
571
572
class NonConflict(TestBase):
573
    """Two descendants insert compatible changes.
574
575
    No conflict should be reported."""
576
    def runTest(self):
577
        return  # NOT RUN
578
        k = Weave()
579
580
        k.add([], ['aaa', 'bbb'])
581
        k.add([0], ['111', 'aaa', 'ccc', 'bbb'])
582
        k.add([1], ['aaa', 'ccc', 'bbb', '222'])
583
584
    
585
    
586
587
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
588
class AutoMerge(TestBase):
589
    def runTest(self):
590
        k = Weave()
591
592
        texts = [['header', 'aaa', 'bbb'],
593
                 ['header', 'aaa', 'line from 1', 'bbb'],
594
                 ['header', 'aaa', 'bbb', 'line from 2', 'more from 2'],
595
                 ]
596
597
        k.add([], texts[0])
598
        k.add([0], texts[1])
599
        k.add([0], texts[2])
600
601
        self.log('k._l=' + pformat(k._l))
602
0.1.95 by Martin Pool
- preliminary merge conflict detection
603
        m = list(k.mash_iter([0, 1, 2]))
0.1.65 by Martin Pool
Add Weave.merge_iter to get automerged lines
604
605
        self.assertEqual(m,
606
                         ['header', 'aaa',
607
                          'line from 1',
608
                          'bbb',
609
                          'line from 2', 'more from 2'])
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
610
        
611
612
613
class Khayyam(TestBase):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
614
    """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
615
    def runTest(self):
616
        rawtexts = [
617
            """A Book of Verses underneath the Bough,
618
            A Jug of Wine, a Loaf of Bread, -- and Thou
619
            Beside me singing in the Wilderness --
620
            Oh, Wilderness were Paradise enow!""",
621
            
622
            """A Book of Verses underneath the Bough,
623
            A Jug of Wine, a Loaf of Bread, -- and Thou
624
            Beside me singing in the Wilderness --
625
            Oh, Wilderness were Paradise now!""",
0.1.59 by Martin Pool
More modification tests
626
627
            """A Book of poems underneath the tree,
628
            A Jug of Wine, a Loaf of Bread,
629
            and Thou
630
            Beside me singing in the Wilderness --
631
            Oh, Wilderness were Paradise now!
632
633
            -- O. Khayyam""",
634
635
            """A Book of Verses underneath the Bough,
636
            A Jug of Wine, a Loaf of Bread,
637
            and Thou
638
            Beside me singing in the Wilderness --
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
639
            Oh, Wilderness were Paradise now!""",
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
640
            ]
641
        texts = [[l.strip() for l in t.split('\n')] for t in rawtexts]
642
643
        k = Weave()
644
        parents = set()
645
        for t in texts:
0.1.78 by Martin Pool
Rename Weave.get_included to inclusions and getiter to get_iter
646
            ver = k.add(list(parents), t)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
647
            parents.add(ver)
648
0.1.59 by Martin Pool
More modification tests
649
        self.log("k._l=" + pformat(k._l))
650
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
651
        for i, t in enumerate(texts):
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
652
            self.assertEqual(k.get(i), t)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
653
0.1.75 by Martin Pool
Remove VerInfo class; just store sets directly in the list of
654
        self.check_read_write(k)
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
655
656
920 by Martin Pool
- add more test cases for weave_merge
657
658
class MergeCases(TestBase):
659
    def doMerge(self, base, a, b, mp):
660
        from cStringIO import StringIO
661
        from textwrap import dedent
662
663
        def addcrlf(x):
664
            return x + '\n'
665
        
666
        w = Weave()
667
        w.add([], map(addcrlf, base))
668
        w.add([0], map(addcrlf, a))
669
        w.add([0], map(addcrlf, b))
670
935 by Martin Pool
- log weave for merge tests to help debugging
671
        self.log('weave is:')
672
        tmpf = StringIO()
673
        write_weave(w, tmpf)
674
        self.log(tmpf.getvalue())
675
920 by Martin Pool
- add more test cases for weave_merge
676
        self.log('merge plan:')
677
        p = list(w.plan_merge(1, 2))
678
        for state, line in p:
679
            if line:
680
                self.log('%12s | %s' % (state, line[:-1]))
681
682
        self.log('merge:')
683
        mt = StringIO()
684
        mt.writelines(w.weave_merge(p))
685
        mt.seek(0)
686
        self.log(mt.getvalue())
687
688
        mp = map(addcrlf, mp)
689
        self.assertEqual(mt.readlines(), mp)
690
        
691
        
692
    def testOneInsert(self):
693
        self.doMerge([],
694
                     ['aa'],
695
                     [],
696
                     ['aa'])
697
698
    def testSeparateInserts(self):
699
        self.doMerge(['aaa', 'bbb', 'ccc'],
700
                     ['aaa', 'xxx', 'bbb', 'ccc'],
701
                     ['aaa', 'bbb', 'yyy', 'ccc'],
702
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
703
704
    def testSameInsert(self):
705
        self.doMerge(['aaa', 'bbb', 'ccc'],
706
                     ['aaa', 'xxx', 'bbb', 'ccc'],
707
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'],
708
                     ['aaa', 'xxx', 'bbb', 'yyy', 'ccc'])
709
710
    def testOverlappedInsert(self):
711
        self.doMerge(['aaa', 'bbb'],
712
                     ['aaa', 'xxx', 'yyy', 'bbb'],
713
                     ['aaa', 'xxx', 'bbb'],
714
                     ['aaa', '<<<<', 'xxx', 'yyy', '====', 'xxx', '>>>>', 'bbb'])
715
716
        # really it ought to reduce this to 
717
        # ['aaa', 'xxx', 'yyy', 'bbb']
718
719
720
    def testClashReplace(self):
721
        self.doMerge(['aaa'],
722
                     ['xxx'],
723
                     ['yyy', 'zzz'],
724
                     ['<<<<', 'xxx', '====', 'yyy', 'zzz', '>>>>'])
725
726
    def testNonClashInsert(self):
727
        self.doMerge(['aaa'],
728
                     ['xxx', 'aaa'],
729
                     ['yyy', 'zzz'],
730
                     ['<<<<', 'xxx', 'aaa', '====', 'yyy', 'zzz', '>>>>'])
731
732
        self.doMerge(['aaa'],
733
                     ['aaa'],
734
                     ['yyy', 'zzz'],
735
                     ['yyy', 'zzz'])
736
    
737
738
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
739
def testweave():
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
740
    import testsweet
741
    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.)
742
    import testweave
0.1.57 by Martin Pool
Fix bug in an update edit that both deletes and inserts -- previously
743
 
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
744
    tl = TestLoader()
745
    suite = TestSuite()
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
746
    suite.addTest(tl.loadTestsFromModule(testweave))
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
747
    
0.1.15 by Martin Pool
Fix inverted shell return code for testknit
748
    return int(not testsweet.run_suite(suite)) # for shell 0=true
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
749
750
751
if __name__ == '__main__':
752
    import sys
0.1.38 by Martin Pool
Rename knit to weave. (I don't think there's an existing module called weave.)
753
    sys.exit(testweave())
0.1.2 by Martin Pool
Import testsweet module adapted from bzr.
754