~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testinv.py

  • Committer: Jelmer Vernooij
  • Date: 2005-11-04 17:26:05 UTC
  • mfrom: (1185.16.146)
  • mto: (1185.33.1)
  • mto: This revision was merged to the branch mainline in revision 1509.
  • Revision ID: jelmer@samba.org-20051104172605-9288f261492667fd
MergeĀ fromĀ Martin

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
        print >> open('file', 'wb'), 'foo'
 
142
        self.branch.add(['file'], ['fileid'])
 
143
        if has_symlinks():
 
144
            os.symlink('target1', 'symlink')
 
145
            self.branch.add(['symlink'], ['linkid'])
 
146
        self.branch.commit('message_1', rev_id = '1')
 
147
        print >> open('file', 'wb'), 'bar'
 
148
        if has_symlinks():
 
149
            os.unlink('symlink')
 
150
            os.symlink('target2', 'symlink')
 
151
        self.tree_1 = self.branch.revision_tree('1')
 
152
        self.inv_1 = self.branch.get_inventory('1')
 
153
        self.file_1 = self.inv_1['fileid']
 
154
        self.tree_2 = self.branch.working_tree()
 
155
        self.inv_2 = self.tree_2.read_working_inventory()
 
156
        self.file_2 = self.inv_2['fileid']
 
157
        if has_symlinks():
 
158
            self.link_1 = self.inv_1['linkid']
 
159
            self.link_2 = self.inv_2['linkid']
 
160
 
 
161
    def test_file_diff_deleted(self):
 
162
        output = StringIO()
 
163
        self.file_1.diff(internal_diff, 
 
164
                          "old_label", self.tree_1,
 
165
                          "/dev/null", None, None,
 
166
                          output)
 
167
        self.assertEqual(output.getvalue(), "--- old_label\n"
 
168
                                            "+++ /dev/null\n"
 
169
                                            "@@ -1,1 +0,0 @@\n"
 
170
                                            "-foo\n"
 
171
                                            "\n")
 
172
 
 
173
    def test_file_diff_added(self):
 
174
        output = StringIO()
 
175
        self.file_1.diff(internal_diff, 
 
176
                          "new_label", self.tree_1,
 
177
                          "/dev/null", None, None,
 
178
                          output, reverse=True)
 
179
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
 
180
                                            "+++ new_label\n"
 
181
                                            "@@ -0,0 +1,1 @@\n"
 
182
                                            "+foo\n"
 
183
                                            "\n")
 
184
 
 
185
    def test_file_diff_changed(self):
 
186
        output = StringIO()
 
187
        self.file_1.diff(internal_diff, 
 
188
                          "/dev/null", self.tree_1, 
 
189
                          "new_label", self.file_2, self.tree_2,
 
190
                          output)
 
191
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
 
192
                                            "+++ new_label\n"
 
193
                                            "@@ -1,1 +1,1 @@\n"
 
194
                                            "-foo\n"
 
195
                                            "+bar\n"
 
196
                                            "\n")
 
197
        
 
198
    def test_link_diff_deleted(self):
 
199
        if not has_symlinks():
 
200
            return
 
201
        output = StringIO()
 
202
        self.link_1.diff(internal_diff, 
 
203
                          "old_label", self.tree_1,
 
204
                          "/dev/null", None, None,
 
205
                          output)
 
206
        self.assertEqual(output.getvalue(),
 
207
                         "=== target was 'target1'\n")
 
208
 
 
209
    def test_link_diff_added(self):
 
210
        if not has_symlinks():
 
211
            return
 
212
        output = StringIO()
 
213
        self.link_1.diff(internal_diff, 
 
214
                          "new_label", self.tree_1,
 
215
                          "/dev/null", None, None,
 
216
                          output, reverse=True)
 
217
        self.assertEqual(output.getvalue(),
 
218
                         "=== target is 'target1'\n")
 
219
 
 
220
    def test_link_diff_changed(self):
 
221
        if not has_symlinks():
 
222
            return
 
223
        output = StringIO()
 
224
        self.link_1.diff(internal_diff, 
 
225
                          "/dev/null", self.tree_1, 
 
226
                          "new_label", self.link_2, self.tree_2,
 
227
                          output)
 
228
        self.assertEqual(output.getvalue(),
 
229
                         "=== target changed 'target1' => 'target2'\n")
 
230
 
 
231
 
 
232
class TestSnapshot(TestCaseInTempDir):
 
233
 
 
234
    def setUp(self):
 
235
        # for full testing we'll need a branch
 
236
        # with a subdir to test parent changes.
 
237
        # and a file, link and dir under that.
 
238
        # but right now I only need one attribute
 
239
        # to change, and then test merge patterns
 
240
        # with fake parent entries.
 
241
        super(TestSnapshot, self).setUp()
 
242
        self.branch = Branch.initialize('.')
 
243
        self.build_tree(['subdir/', 'subdir/file'])
 
244
        self.branch.add(['subdir', 'subdir/file'], ['dirid', 'fileid'])
 
245
        if has_symlinks():
 
246
            pass
 
247
        self.branch.commit('message_1', rev_id = '1')
 
248
        self.tree_1 = self.branch.revision_tree('1')
 
249
        self.inv_1 = self.branch.get_inventory('1')
 
250
        self.file_1 = self.inv_1['fileid']
 
251
        self.work_tree = self.branch.working_tree()
 
252
        self.file_active = self.work_tree.inventory['fileid']
 
253
 
 
254
    def test_snapshot_new_revision(self):
 
255
        # This tests that a simple commit with no parents makes a new
 
256
        # revision value in the inventory entry
 
257
        self.file_active.snapshot('2', 'subdir/file', {}, self.work_tree, 
 
258
                                  self.branch.weave_store,
 
259
                                  self.branch.get_transaction())
 
260
        # expected outcome - file_1 has a revision id of '2', and we can get
 
261
        # its text of 'file contents' out of the weave.
 
262
        self.assertEqual(self.file_1.revision, '1')
 
263
        self.assertEqual(self.file_active.revision, '2')
 
264
        # this should be a separate test probably, but lets check it once..
 
265
        lines = self.branch.weave_store.get_lines('fileid','2',
 
266
            self.branch.get_transaction())
 
267
        self.assertEqual(lines, ['contents of subdir/file\n'])
 
268
 
 
269
    def test_snapshot_unchanged(self):
 
270
        #This tests that a simple commit does not make a new entry for
 
271
        # an unchanged inventory entry
 
272
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
 
273
                                  self.work_tree, self.branch.weave_store,
 
274
                                  self.branch.get_transaction())
 
275
        self.assertEqual(self.file_1.revision, '1')
 
276
        self.assertEqual(self.file_active.revision, '1')
 
277
        self.assertRaises(errors.WeaveError,
 
278
                          self.branch.weave_store.get_lines, 'fileid', '2',
 
279
                          self.branch.get_transaction())
 
280
 
 
281
    def test_snapshot_merge_identical_different_revid(self):
 
282
        # This tests that a commit with two identical parents, one of which has
 
283
        # a different revision id, results in a new revision id in the entry.
 
284
        # 1->other, commit a merge of other against 1, results in 2.
 
285
        other_ie = inventory.InventoryFile('fileid', 'newname', self.file_1.parent_id)
 
286
        other_ie = inventory.InventoryFile('fileid', 'file', self.file_1.parent_id)
 
287
        other_ie.revision = '1'
 
288
        other_ie.text_sha1 = self.file_1.text_sha1
 
289
        other_ie.text_size = self.file_1.text_size
 
290
        self.assertEqual(self.file_1, other_ie)
 
291
        other_ie.revision = 'other'
 
292
        self.assertNotEqual(self.file_1, other_ie)
 
293
        self.branch.weave_store.add_identical_text('fileid', '1', 'other', ['1'],
 
294
            self.branch.get_transaction())
 
295
        self.file_active.snapshot('2', 'subdir/file', 
 
296
                                  {'1':self.file_1, 'other':other_ie},
 
297
                                  self.work_tree, self.branch.weave_store,
 
298
                                  self.branch.get_transaction())
 
299
        self.assertEqual(self.file_active.revision, '2')
 
300
 
 
301
    def test_snapshot_changed(self):
 
302
        # This tests that a commit with one different parent results in a new
 
303
        # revision id in the entry.
 
304
        self.file_active.name='newname'
 
305
        rename('subdir/file', 'subdir/newname')
 
306
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
 
307
                                  self.work_tree, 
 
308
                                  self.branch.weave_store,
 
309
                                  self.branch.get_transaction())
 
310
        # expected outcome - file_1 has a revision id of '2'
 
311
        self.assertEqual(self.file_active.revision, '2')
 
312
 
 
313
 
 
314
class TestPreviousHeads(TestCaseInTempDir):
 
315
 
 
316
    def setUp(self):
 
317
        # we want several inventories, that respectively
 
318
        # give use the following scenarios:
 
319
        # A) fileid not in any inventory (A),
 
320
        # B) fileid present in one inventory (B) and (A,B)
 
321
        # C) fileid present in two inventories, and they
 
322
        #   are not mutual descendents (B, C)
 
323
        # D) fileid present in two inventories and one is
 
324
        #   a descendent of the other. (B, D)
 
325
        super(TestPreviousHeads, self).setUp()
 
326
        self.build_tree(['file'])
 
327
        self.branch = Branch.initialize('.')
 
328
        self.branch.commit('new branch', allow_pointless=True, rev_id='A')
 
329
        self.inv_A = self.branch.get_inventory('A')
 
330
        self.branch.add(['file'], ['fileid'])
 
331
        self.branch.commit('add file', rev_id='B')
 
332
        self.inv_B = self.branch.get_inventory('B')
 
333
        self.branch.put_controlfile('revision-history', 'A\n')
 
334
        self.assertEqual(self.branch.revision_history(), ['A'])
 
335
        self.branch.commit('another add of file', rev_id='C')
 
336
        self.inv_C = self.branch.get_inventory('C')
 
337
        self.branch.add_pending_merge('B')
 
338
        self.branch.commit('merge in B', rev_id='D')
 
339
        self.inv_D = self.branch.get_inventory('D')
 
340
        self.file_active = self.branch.working_tree().inventory['fileid']
 
341
        self.weave = self.branch.weave_store.get_weave('fileid',
 
342
            self.branch.get_transaction())
 
343
        
 
344
    def get_previous_heads(self, inventories):
 
345
        return self.file_active.find_previous_heads(inventories, self.weave)
 
346
        
 
347
    def test_fileid_in_no_inventory(self):
 
348
        self.assertEqual({}, self.get_previous_heads([self.inv_A]))
 
349
 
 
350
    def test_fileid_in_one_inventory(self):
 
351
        self.assertEqual({'B':self.inv_B['fileid']},
 
352
                         self.get_previous_heads([self.inv_B]))
 
353
        self.assertEqual({'B':self.inv_B['fileid']},
 
354
                         self.get_previous_heads([self.inv_A, self.inv_B]))
 
355
        self.assertEqual({'B':self.inv_B['fileid']},
 
356
                         self.get_previous_heads([self.inv_B, self.inv_A]))
 
357
 
 
358
    def test_fileid_in_two_inventories_gives_both_entries(self):
 
359
        self.assertEqual({'B':self.inv_B['fileid'],
 
360
                          'C':self.inv_C['fileid']},
 
361
                          self.get_previous_heads([self.inv_B, self.inv_C]))
 
362
        self.assertEqual({'B':self.inv_B['fileid'],
 
363
                          'C':self.inv_C['fileid']},
 
364
                          self.get_previous_heads([self.inv_C, self.inv_B]))
 
365
 
 
366
    def test_fileid_in_two_inventories_already_merged_gives_head(self):
 
367
        self.assertEqual({'D':self.inv_D['fileid']},
 
368
                         self.get_previous_heads([self.inv_B, self.inv_D]))
 
369
        self.assertEqual({'D':self.inv_D['fileid']},
 
370
                         self.get_previous_heads([self.inv_D, self.inv_B]))
 
371
 
 
372
    # TODO: test two inventories with the same file revision