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