~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testinv.py

  • Committer: Aaron Bentley
  • Date: 2005-11-24 06:05:20 UTC
  • mto: (1185.33.52 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 1512.
  • Revision ID: aaron.bentley@utoronto.ca-20051124060520-0279acee0f7c1d70
Tweaked tree name generation when applying changesets

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from bzrlib.selftest import TestCase
 
17
from cStringIO import StringIO
 
18
import os
18
19
 
19
 
from bzrlib.inventory import Inventory, InventoryEntry
 
20
from bzrlib.branch import Branch
 
21
from bzrlib.clone import copy_branch
 
22
import bzrlib.errors as errors
 
23
from bzrlib.diff import internal_diff
 
24
from bzrlib.inventory import Inventory, ROOT_ID
 
25
import bzrlib.inventory as inventory
 
26
from bzrlib.osutils import has_symlinks, rename
 
27
from bzrlib.selftest import TestCase, TestCaseInTempDir
20
28
 
21
29
 
22
30
class TestInventory(TestCase):
23
31
 
24
32
    def test_is_within(self):
25
33
        from bzrlib.osutils import is_inside_any
26
 
        
27
 
        for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
28
 
                         (['src'], 'src/foo.c'),
 
34
 
 
35
        SRC_FOO_C = os.path.join('src', 'foo.c')
 
36
        for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
 
37
                         (['src'], SRC_FOO_C),
29
38
                         (['src'], 'src'),
30
39
                         ]:
31
40
            self.assert_(is_inside_any(dirs, fn))
57
66
        ie = inv.add_path('foo.txt', 'file')
58
67
        ## XXX
59
68
 
 
69
 
 
70
class TestInventoryEntry(TestCase):
 
71
 
 
72
    def test_file_kind_character(self):
 
73
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
74
        self.assertEqual(file.kind_character(), '')
 
75
 
 
76
    def test_dir_kind_character(self):
 
77
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
78
        self.assertEqual(dir.kind_character(), '/')
 
79
 
 
80
    def test_link_kind_character(self):
 
81
        dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
82
        self.assertEqual(dir.kind_character(), '')
 
83
 
 
84
    def test_dir_detect_changes(self):
 
85
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
86
        left.text_sha1 = 123
 
87
        left.executable = True
 
88
        left.symlink_target='foo'
 
89
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
90
        right.text_sha1 = 321
 
91
        right.symlink_target='bar'
 
92
        self.assertEqual((False, False), left.detect_changes(right))
 
93
        self.assertEqual((False, False), right.detect_changes(left))
 
94
 
 
95
    def test_file_detect_changes(self):
 
96
        left = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
97
        left.text_sha1 = 123
 
98
        right = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
99
        right.text_sha1 = 123
 
100
        self.assertEqual((False, False), left.detect_changes(right))
 
101
        self.assertEqual((False, False), right.detect_changes(left))
 
102
        left.executable = True
 
103
        self.assertEqual((False, True), left.detect_changes(right))
 
104
        self.assertEqual((False, True), right.detect_changes(left))
 
105
        right.text_sha1 = 321
 
106
        self.assertEqual((True, True), left.detect_changes(right))
 
107
        self.assertEqual((True, True), right.detect_changes(left))
 
108
 
 
109
    def test_symlink_detect_changes(self):
 
110
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
111
        left.text_sha1 = 123
 
112
        left.executable = True
 
113
        left.symlink_target='foo'
 
114
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
115
        right.text_sha1 = 321
 
116
        right.symlink_target='foo'
 
117
        self.assertEqual((False, False), left.detect_changes(right))
 
118
        self.assertEqual((False, False), right.detect_changes(left))
 
119
        left.symlink_target = 'different'
 
120
        self.assertEqual((True, False), left.detect_changes(right))
 
121
        self.assertEqual((True, False), right.detect_changes(left))
 
122
 
 
123
    def test_file_has_text(self):
 
124
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
125
        self.failUnless(file.has_text())
 
126
 
 
127
    def test_directory_has_text(self):
 
128
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
129
        self.failIf(dir.has_text())
 
130
 
 
131
    def test_link_has_text(self):
 
132
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
133
        self.failIf(link.has_text())
 
134
 
 
135
 
 
136
class TestEntryDiffing(TestCaseInTempDir):
 
137
 
 
138
    def setUp(self):
 
139
        super(TestEntryDiffing, self).setUp()
 
140
        self.branch = Branch.initialize('.')
 
141
        self.wt = self.branch.working_tree()
 
142
        print >> open('file', 'wb'), 'foo'
 
143
        self.branch.add(['file'], ['fileid'])
 
144
        if has_symlinks():
 
145
            os.symlink('target1', 'symlink')
 
146
            self.branch.add(['symlink'], ['linkid'])
 
147
        self.wt.commit('message_1', rev_id = '1')
 
148
        print >> open('file', 'wb'), 'bar'
 
149
        if has_symlinks():
 
150
            os.unlink('symlink')
 
151
            os.symlink('target2', 'symlink')
 
152
        self.tree_1 = self.branch.revision_tree('1')
 
153
        self.inv_1 = self.branch.get_inventory('1')
 
154
        self.file_1 = self.inv_1['fileid']
 
155
        self.tree_2 = self.branch.working_tree()
 
156
        self.inv_2 = self.tree_2.read_working_inventory()
 
157
        self.file_2 = self.inv_2['fileid']
 
158
        if has_symlinks():
 
159
            self.link_1 = self.inv_1['linkid']
 
160
            self.link_2 = self.inv_2['linkid']
 
161
 
 
162
    def test_file_diff_deleted(self):
 
163
        output = StringIO()
 
164
        self.file_1.diff(internal_diff, 
 
165
                          "old_label", self.tree_1,
 
166
                          "/dev/null", None, None,
 
167
                          output)
 
168
        self.assertEqual(output.getvalue(), "--- old_label\t\n"
 
169
                                            "+++ /dev/null\t\n"
 
170
                                            "@@ -1,1 +0,0 @@\n"
 
171
                                            "-foo\n"
 
172
                                            "\n")
 
173
 
 
174
    def test_file_diff_added(self):
 
175
        output = StringIO()
 
176
        self.file_1.diff(internal_diff, 
 
177
                          "new_label", self.tree_1,
 
178
                          "/dev/null", None, None,
 
179
                          output, reverse=True)
 
180
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
181
                                            "+++ new_label\t\n"
 
182
                                            "@@ -0,0 +1,1 @@\n"
 
183
                                            "+foo\n"
 
184
                                            "\n")
 
185
 
 
186
    def test_file_diff_changed(self):
 
187
        output = StringIO()
 
188
        self.file_1.diff(internal_diff, 
 
189
                          "/dev/null", self.tree_1, 
 
190
                          "new_label", self.file_2, self.tree_2,
 
191
                          output)
 
192
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
193
                                            "+++ new_label\t\n"
 
194
                                            "@@ -1,1 +1,1 @@\n"
 
195
                                            "-foo\n"
 
196
                                            "+bar\n"
 
197
                                            "\n")
 
198
        
 
199
    def test_link_diff_deleted(self):
 
200
        if not has_symlinks():
 
201
            return
 
202
        output = StringIO()
 
203
        self.link_1.diff(internal_diff, 
 
204
                          "old_label", self.tree_1,
 
205
                          "/dev/null", None, None,
 
206
                          output)
 
207
        self.assertEqual(output.getvalue(),
 
208
                         "=== target was 'target1'\n")
 
209
 
 
210
    def test_link_diff_added(self):
 
211
        if not has_symlinks():
 
212
            return
 
213
        output = StringIO()
 
214
        self.link_1.diff(internal_diff, 
 
215
                          "new_label", self.tree_1,
 
216
                          "/dev/null", None, None,
 
217
                          output, reverse=True)
 
218
        self.assertEqual(output.getvalue(),
 
219
                         "=== target is 'target1'\n")
 
220
 
 
221
    def test_link_diff_changed(self):
 
222
        if not has_symlinks():
 
223
            return
 
224
        output = StringIO()
 
225
        self.link_1.diff(internal_diff, 
 
226
                          "/dev/null", self.tree_1, 
 
227
                          "new_label", self.link_2, self.tree_2,
 
228
                          output)
 
229
        self.assertEqual(output.getvalue(),
 
230
                         "=== target changed 'target1' => 'target2'\n")
 
231
 
 
232
 
 
233
class TestSnapshot(TestCaseInTempDir):
 
234
 
 
235
    def setUp(self):
 
236
        # for full testing we'll need a branch
 
237
        # with a subdir to test parent changes.
 
238
        # and a file, link and dir under that.
 
239
        # but right now I only need one attribute
 
240
        # to change, and then test merge patterns
 
241
        # with fake parent entries.
 
242
        super(TestSnapshot, self).setUp()
 
243
        self.branch = Branch.initialize('.')
 
244
        self.build_tree(['subdir/', 'subdir/file'], line_endings='binary')
 
245
        self.branch.add(['subdir', 'subdir/file'], ['dirid', 'fileid'])
 
246
        if has_symlinks():
 
247
            pass
 
248
        self.wt = self.branch.working_tree()
 
249
        self.wt.commit('message_1', rev_id = '1')
 
250
        self.tree_1 = self.branch.revision_tree('1')
 
251
        self.inv_1 = self.branch.get_inventory('1')
 
252
        self.file_1 = self.inv_1['fileid']
 
253
        self.work_tree = self.branch.working_tree()
 
254
        self.file_active = self.work_tree.inventory['fileid']
 
255
 
 
256
    def test_snapshot_new_revision(self):
 
257
        # This tests that a simple commit with no parents makes a new
 
258
        # revision value in the inventory entry
 
259
        self.file_active.snapshot('2', 'subdir/file', {}, self.work_tree, 
 
260
                                  self.branch.weave_store,
 
261
                                  self.branch.get_transaction())
 
262
        # expected outcome - file_1 has a revision id of '2', and we can get
 
263
        # its text of 'file contents' out of the weave.
 
264
        self.assertEqual(self.file_1.revision, '1')
 
265
        self.assertEqual(self.file_active.revision, '2')
 
266
        # this should be a separate test probably, but lets check it once..
 
267
        lines = self.branch.weave_store.get_lines('fileid','2',
 
268
            self.branch.get_transaction())
 
269
        self.assertEqual(lines, ['contents of subdir/file\n'])
 
270
 
 
271
    def test_snapshot_unchanged(self):
 
272
        #This tests that a simple commit does not make a new entry for
 
273
        # an unchanged inventory entry
 
274
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
 
275
                                  self.work_tree, self.branch.weave_store,
 
276
                                  self.branch.get_transaction())
 
277
        self.assertEqual(self.file_1.revision, '1')
 
278
        self.assertEqual(self.file_active.revision, '1')
 
279
        self.assertRaises(errors.WeaveError,
 
280
                          self.branch.weave_store.get_lines, 'fileid', '2',
 
281
                          self.branch.get_transaction())
 
282
 
 
283
    def test_snapshot_merge_identical_different_revid(self):
 
284
        # This tests that a commit with two identical parents, one of which has
 
285
        # a different revision id, results in a new revision id in the entry.
 
286
        # 1->other, commit a merge of other against 1, results in 2.
 
287
        other_ie = inventory.InventoryFile('fileid', 'newname', self.file_1.parent_id)
 
288
        other_ie = inventory.InventoryFile('fileid', 'file', self.file_1.parent_id)
 
289
        other_ie.revision = '1'
 
290
        other_ie.text_sha1 = self.file_1.text_sha1
 
291
        other_ie.text_size = self.file_1.text_size
 
292
        self.assertEqual(self.file_1, other_ie)
 
293
        other_ie.revision = 'other'
 
294
        self.assertNotEqual(self.file_1, other_ie)
 
295
        self.branch.weave_store.add_identical_text('fileid', '1', 'other', ['1'],
 
296
            self.branch.get_transaction())
 
297
        self.file_active.snapshot('2', 'subdir/file', 
 
298
                                  {'1':self.file_1, 'other':other_ie},
 
299
                                  self.work_tree, self.branch.weave_store,
 
300
                                  self.branch.get_transaction())
 
301
        self.assertEqual(self.file_active.revision, '2')
 
302
 
 
303
    def test_snapshot_changed(self):
 
304
        # This tests that a commit with one different parent results in a new
 
305
        # revision id in the entry.
 
306
        self.file_active.name='newname'
 
307
        rename('subdir/file', 'subdir/newname')
 
308
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
 
309
                                  self.work_tree, 
 
310
                                  self.branch.weave_store,
 
311
                                  self.branch.get_transaction())
 
312
        # expected outcome - file_1 has a revision id of '2'
 
313
        self.assertEqual(self.file_active.revision, '2')
 
314
 
 
315
 
 
316
class TestPreviousHeads(TestCaseInTempDir):
 
317
 
 
318
    def setUp(self):
 
319
        # we want several inventories, that respectively
 
320
        # give use the following scenarios:
 
321
        # A) fileid not in any inventory (A),
 
322
        # B) fileid present in one inventory (B) and (A,B)
 
323
        # C) fileid present in two inventories, and they
 
324
        #   are not mutual descendents (B, C)
 
325
        # D) fileid present in two inventories and one is
 
326
        #   a descendent of the other. (B, D)
 
327
        super(TestPreviousHeads, self).setUp()
 
328
        self.build_tree(['file'])
 
329
        self.branch = Branch.initialize('.')
 
330
        self.wt = self.branch.working_tree()
 
331
        self.wt.commit('new branch', allow_pointless=True, rev_id='A')
 
332
        self.inv_A = self.branch.get_inventory('A')
 
333
        self.branch.add(['file'], ['fileid'])
 
334
        self.wt.commit('add file', rev_id='B')
 
335
        self.inv_B = self.branch.get_inventory('B')
 
336
        self.branch.put_controlfile('revision-history', 'A\n')
 
337
        self.assertEqual(self.branch.revision_history(), ['A'])
 
338
        self.wt.commit('another add of file', rev_id='C')
 
339
        self.inv_C = self.branch.get_inventory('C')
 
340
        self.wt.add_pending_merge('B')
 
341
        self.wt.commit('merge in B', rev_id='D')
 
342
        self.inv_D = self.branch.get_inventory('D')
 
343
        self.file_active = self.wt.inventory['fileid']
 
344
        self.weave = self.branch.weave_store.get_weave('fileid',
 
345
            self.branch.get_transaction())
 
346
        
 
347
    def get_previous_heads(self, inventories):
 
348
        return self.file_active.find_previous_heads(inventories, self.weave)
 
349
        
 
350
    def test_fileid_in_no_inventory(self):
 
351
        self.assertEqual({}, self.get_previous_heads([self.inv_A]))
 
352
 
 
353
    def test_fileid_in_one_inventory(self):
 
354
        self.assertEqual({'B':self.inv_B['fileid']},
 
355
                         self.get_previous_heads([self.inv_B]))
 
356
        self.assertEqual({'B':self.inv_B['fileid']},
 
357
                         self.get_previous_heads([self.inv_A, self.inv_B]))
 
358
        self.assertEqual({'B':self.inv_B['fileid']},
 
359
                         self.get_previous_heads([self.inv_B, self.inv_A]))
 
360
 
 
361
    def test_fileid_in_two_inventories_gives_both_entries(self):
 
362
        self.assertEqual({'B':self.inv_B['fileid'],
 
363
                          'C':self.inv_C['fileid']},
 
364
                          self.get_previous_heads([self.inv_B, self.inv_C]))
 
365
        self.assertEqual({'B':self.inv_B['fileid'],
 
366
                          'C':self.inv_C['fileid']},
 
367
                          self.get_previous_heads([self.inv_C, self.inv_B]))
 
368
 
 
369
    def test_fileid_in_two_inventories_already_merged_gives_head(self):
 
370
        self.assertEqual({'D':self.inv_D['fileid']},
 
371
                         self.get_previous_heads([self.inv_B, self.inv_D]))
 
372
        self.assertEqual({'D':self.inv_D['fileid']},
 
373
                         self.get_previous_heads([self.inv_D, self.inv_B]))
 
374
 
 
375
    # TODO: test two inventories with the same file revision