~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/interversionedfile_implementations/test_join.py

  • Committer: Robert Collins
  • Date: 2006-03-02 03:12:34 UTC
  • mto: (1594.2.4 integration)
  • mto: This revision was merged to the branch mainline in revision 1596.
  • Revision ID: robertc@robertcollins.net-20060302031234-cf6b75961f27c5df
InterVersionedFile implemented.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for join between versioned files."""
18
18
 
19
19
 
 
20
import bzrlib.errors as errors
20
21
from bzrlib.tests import TestCaseWithTransport
21
22
from bzrlib.transport import get_transport
 
23
import bzrlib.versionedfile as versionedfile
22
24
 
23
25
 
24
26
class TestJoin(TestCaseWithTransport):
30
32
        return self.versionedfile_factory(name,
31
33
                                          get_transport(self.get_url()))
32
34
 
33
 
    def get_target(self, name='source'):
 
35
    def get_target(self, name='target'):
34
36
        """"Get an empty versioned file to join into."""
35
37
        return self.versionedfile_factory_to(name,
36
38
                                             get_transport(self.get_url()))
47
49
        verify_file(f2)
48
50
        verify_file(self.get_target())
49
51
 
50
 
        self.assertRaises(RevisionNotPresent,
 
52
        self.assertRaises(errors.RevisionNotPresent,
51
53
            f2.join, f1, version_ids=['r3'])
52
54
 
53
55
        #f3 = self.get_file('1')
58
60
        #self.assertTrue(f4.has_version('r0'))
59
61
        #self.assertFalse(f4.has_version('r1'))
60
62
 
 
63
    def test_gets_expected_inter_worker(self):
 
64
        source = self.get_source()
 
65
        target = self.get_target()
 
66
        inter = versionedfile.InterVersionedFile.get(source, target)
 
67
        self.assertTrue(isinstance(inter, self.interversionedfile_class))
 
68
        
 
69
    def test_join_add_parents(self):
 
70
        """Join inserting new parents into existing versions
 
71
        
 
72
        The new version must have the right parent list and must identify
 
73
        lines originating in another parent.
 
74
        """
 
75
        w1 = self.get_target('w1')
 
76
        w2 = self.get_source('w2')
 
77
        w1.add_lines('v-1', [], ['line 1\n'])
 
78
        w2.add_lines('v-2', [], ['line 2\n'])
 
79
        w1.add_lines('v-3', ['v-1'], ['line 1\n'])
 
80
        w2.add_lines('v-3', ['v-2'], ['line 1\n'])
 
81
        w1.join(w2)
 
82
        self.assertEqual(sorted(w1.versions()),
 
83
                         'v-1 v-2 v-3'.split())
 
84
        self.assertEqualDiff(w1.get_text('v-3'),
 
85
                'line 1\n')
 
86
        self.assertEqual(sorted(w1.get_parents('v-3')),
 
87
                ['v-1', 'v-2'])
 
88
        ann = list(w1.annotate('v-3'))
 
89
        self.assertEqual(len(ann), 1)
 
90
        self.assertEqual(ann[0][0], 'v-1')
 
91
        self.assertEqual(ann[0][1], 'line 1\n')
 
92
        
 
93
    def build_weave1(self):
 
94
        weave1 = self.get_source()
 
95
        self.lines1 = ['hello\n']
 
96
        self.lines3 = ['hello\n', 'cruel\n', 'world\n']
 
97
        weave1.add_lines('v1', [], self.lines1)
 
98
        weave1.add_lines('v2', ['v1'], ['hello\n', 'world\n'])
 
99
        weave1.add_lines('v3', ['v2'], self.lines3)
 
100
        return weave1
 
101
        
 
102
    def test_join_with_empty(self):
 
103
        """Reweave adding empty weave"""
 
104
        wb = self.get_target()
 
105
        w1 = self.build_weave1()
 
106
        w1.join(wb)
 
107
        self.verify_weave1(w1)
 
108
 
 
109
    def verify_weave1(self, w1):
 
110
        self.assertEqual(sorted(w1.versions()), ['v1', 'v2', 'v3'])
 
111
        self.assertEqual(w1.get_lines('v1'), ['hello\n'])
 
112
        self.assertEqual([], w1.get_parents('v1'))
 
113
        self.assertEqual(w1.get_lines('v2'), ['hello\n', 'world\n'])
 
114
        self.assertEqual(['v1'], w1.get_parents('v2'))
 
115
        self.assertEqual(w1.get_lines('v3'), ['hello\n', 'cruel\n', 'world\n'])
 
116
        self.assertEqual(['v2'], w1.get_parents('v3'))
 
117
 
 
118
    def test_join_with_ghosts_merges_parents(self):
 
119
        """Join combined parent lists"""
 
120
        wa = self.build_weave1()
 
121
        wb = self.get_target()
 
122
        wb.add_lines('x1', [], ['line from x1\n'])
 
123
        wb.add_lines('v1', [], ['hello\n'])
 
124
        wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
 
125
        wa.join(wb)
 
126
        self.assertEqual(['v1','x1'], wa.get_parents('v2'))
 
127
 
 
128
    def test_join_with_ghosts(self):
 
129
        """Join that inserts parents of an existing revision.
 
130
 
 
131
        This can happen when merging from another branch who
 
132
        knows about revisions the destination does not.  In 
 
133
        this test the second weave knows of an additional parent of 
 
134
        v2.  Any revisions which are in common still have to have the 
 
135
        same text.
 
136
        """
 
137
        w1 = self.build_weave1()
 
138
        wb = self.get_target()
 
139
        wb.add_lines('x1', [], ['line from x1\n'])
 
140
        wb.add_lines('v1', [], ['hello\n'])
 
141
        wb.add_lines('v2', ['v1', 'x1'], ['hello\n', 'world\n'])
 
142
        w1.join(wb)
 
143
        eq = self.assertEquals
 
144
        eq(sorted(w1.versions()), ['v1', 'v2', 'v3', 'x1',])
 
145
        eq(w1.get_text('x1'), 'line from x1\n')
 
146
        eq(w1.get_lines('v2'), ['hello\n', 'world\n'])
 
147
        eq(w1.get_parents('v2'), ['v1', 'x1'])
 
148
 
 
149
    def build_source_weave(self, name, *pattern):
 
150
        w = self.get_source(name)
 
151
        for version, parents in pattern:
 
152
            w.add_lines(version, parents, [])
 
153
        return w
 
154
 
 
155
    def build_target_weave(self, name, *pattern):
 
156
        w = self.get_target(name)
 
157
        for version, parents in pattern:
 
158
            w.add_lines(version, parents, [])
 
159
        return w
 
160
 
 
161
    def test_join_reorder(self):
 
162
        """Reweave requiring reordering of versions.
 
163
 
 
164
        Weaves must be stored such that parents come before children.  When
 
165
        reweaving, we may add new parents to some children, but it is required
 
166
        that there must be *some* valid order that can be found, otherwise the
 
167
        ancestries are contradictory.  (For the specific case of inserting
 
168
        ghost revisions there will be no disagreement, only partial knowledge
 
169
        of the history.)
 
170
 
 
171
        Note that the weaves are only partially ordered: when there are two
 
172
        versions where neither is an ancestor of the other the order in which
 
173
        they occur is unconstrained.  When we join those versions into
 
174
        another weave, they may become more constrained and it may be
 
175
        necessary to change their order.
 
176
 
 
177
        One simple case of this is 
 
178
 
 
179
        w1: (c[], a[], b[a])
 
180
        w2: (b[], c[b], a[])
 
181
        
 
182
        We need to recognize that the final weave must show the ordering
 
183
        a[], b[a], c[b].  The version that must be first in the result is 
 
184
        not first in either of the input weaves.
 
185
        """
 
186
        w1 = self.build_target_weave('1', ('c', []), ('a', []), ('b', ['a']))
 
187
        w2 = self.build_source_weave('2', ('b', []), ('c', ['b']), ('a', []))
 
188
        w1.join(w2)
 
189
        self.assertEqual([], w1.get_parents('a'))
 
190
        self.assertEqual(['a'], w1.get_parents('b'))
 
191
        self.assertEqual(['b'], w1.get_parents('c'))