~ubuntu-branches/debian/lenny/bzr/lenny

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-08-22 20:06:37 UTC
  • mfrom: (3.1.63 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080822200637-kxobfsnjlzojhqra
Tags: 1.5-1.1
* Non-maintainer upload.
* Apply patch from upstream VCS to fix FTBFS in tools/rst2html.py
  with older docutils. Thanks to Olivier Tétard for digging it
  up.
  Closes: #494246.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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 cStringIO import StringIO
18
 
import os
19
 
import time
20
17
 
21
18
from bzrlib import errors, inventory, osutils
22
 
from bzrlib.branch import Branch
23
 
from bzrlib.diff import internal_diff
24
19
from bzrlib.inventory import (Inventory, ROOT_ID, InventoryFile,
25
 
    InventoryDirectory, InventoryEntry)
26
 
from bzrlib.osutils import (has_symlinks, rename, pathjoin, is_inside_any, 
27
 
    is_inside_or_parent_of_any)
28
 
from bzrlib.tests import TestCase, TestCaseWithTransport
29
 
from bzrlib.transform import TreeTransform
30
 
from bzrlib.uncommit import uncommit
31
 
 
32
 
 
33
 
class TestInventory(TestCase):
34
 
 
35
 
    def test_is_within(self):
36
 
 
37
 
        SRC_FOO_C = pathjoin('src', 'foo.c')
38
 
        for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
39
 
                         (['src'], SRC_FOO_C),
40
 
                         (['src'], 'src'),
41
 
                         ]:
42
 
            self.assert_(is_inside_any(dirs, fn))
43
 
            
44
 
        for dirs, fn in [(['src'], 'srccontrol'),
45
 
                         (['src'], 'srccontrol/foo')]:
46
 
            self.assertFalse(is_inside_any(dirs, fn))
47
 
 
48
 
    def test_is_within_or_parent(self):
49
 
        for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
50
 
                         (['src'], 'src/foo.c'),
51
 
                         (['src/bar.c'], 'src'),
52
 
                         (['src/bar.c', 'bla/foo.c'], 'src'),
53
 
                         (['src'], 'src'),
54
 
                         ]:
55
 
            self.assert_(is_inside_or_parent_of_any(dirs, fn))
56
 
            
57
 
        for dirs, fn in [(['src'], 'srccontrol'),
58
 
                         (['srccontrol/foo.c'], 'src'),
59
 
                         (['src'], 'srccontrol/foo')]:
60
 
            self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
61
 
 
62
 
    def test_ids(self):
63
 
        """Test detection of files within selected directories."""
64
 
        inv = Inventory()
65
 
        
66
 
        for args in [('src', 'directory', 'src-id'), 
67
 
                     ('doc', 'directory', 'doc-id'), 
68
 
                     ('src/hello.c', 'file'),
69
 
                     ('src/bye.c', 'file', 'bye-id'),
70
 
                     ('Makefile', 'file')]:
71
 
            inv.add_path(*args)
72
 
            
73
 
        self.assertEqual(inv.path2id('src'), 'src-id')
74
 
        self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
75
 
        
76
 
        self.assert_('src-id' in inv)
77
 
 
78
 
    def test_iter_entries(self):
79
 
        inv = Inventory()
80
 
        
81
 
        for args in [('src', 'directory', 'src-id'), 
82
 
                     ('doc', 'directory', 'doc-id'), 
83
 
                     ('src/hello.c', 'file', 'hello-id'),
84
 
                     ('src/bye.c', 'file', 'bye-id'),
85
 
                     ('Makefile', 'file', 'makefile-id')]:
86
 
            inv.add_path(*args)
87
 
 
88
 
        self.assertEqual([
89
 
            ('', ROOT_ID),
90
 
            ('Makefile', 'makefile-id'),
91
 
            ('doc', 'doc-id'),
92
 
            ('src', 'src-id'),
93
 
            ('src/bye.c', 'bye-id'),
94
 
            ('src/hello.c', 'hello-id'),
95
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
96
 
            
97
 
    def test_iter_entries_by_dir(self):
98
 
        inv = Inventory()
99
 
        
100
 
        for args in [('src', 'directory', 'src-id'), 
101
 
                     ('doc', 'directory', 'doc-id'), 
102
 
                     ('src/hello.c', 'file', 'hello-id'),
103
 
                     ('src/bye.c', 'file', 'bye-id'),
104
 
                     ('zz', 'file', 'zz-id'),
105
 
                     ('src/sub/', 'directory', 'sub-id'),
106
 
                     ('src/zz.c', 'file', 'zzc-id'),
107
 
                     ('src/sub/a', 'file', 'a-id'),
108
 
                     ('Makefile', 'file', 'makefile-id')]:
109
 
            inv.add_path(*args)
110
 
 
111
 
        self.assertEqual([
112
 
            ('', ROOT_ID),
113
 
            ('Makefile', 'makefile-id'),
114
 
            ('doc', 'doc-id'),
115
 
            ('src', 'src-id'),
116
 
            ('zz', 'zz-id'),
117
 
            ('src/bye.c', 'bye-id'),
118
 
            ('src/hello.c', 'hello-id'),
119
 
            ('src/sub', 'sub-id'),
120
 
            ('src/zz.c', 'zzc-id'),
121
 
            ('src/sub/a', 'a-id'),
122
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
123
 
            
124
 
    def test_version(self):
125
 
        """Inventory remembers the text's version."""
126
 
        inv = Inventory()
127
 
        ie = inv.add_path('foo.txt', 'file')
128
 
        ## XXX
 
20
    InventoryDirectory, InventoryEntry, TreeReference)
 
21
from bzrlib.tests import TestCase
129
22
 
130
23
 
131
24
class TestInventoryEntry(TestCase):
217
110
            osutils.normalized_filename = orig_normalized_filename
218
111
 
219
112
 
220
 
class TestEntryDiffing(TestCaseWithTransport):
221
 
 
222
 
    def setUp(self):
223
 
        super(TestEntryDiffing, self).setUp()
224
 
        self.wt = self.make_branch_and_tree('.')
225
 
        self.branch = self.wt.branch
226
 
        print >> open('file', 'wb'), 'foo'
227
 
        print >> open('binfile', 'wb'), 'foo'
228
 
        self.wt.add(['file'], ['fileid'])
229
 
        self.wt.add(['binfile'], ['binfileid'])
230
 
        if has_symlinks():
231
 
            os.symlink('target1', 'symlink')
232
 
            self.wt.add(['symlink'], ['linkid'])
233
 
        self.wt.commit('message_1', rev_id = '1')
234
 
        print >> open('file', 'wb'), 'bar'
235
 
        print >> open('binfile', 'wb'), 'x' * 1023 + '\x00'
236
 
        if has_symlinks():
237
 
            os.unlink('symlink')
238
 
            os.symlink('target2', 'symlink')
239
 
        self.tree_1 = self.branch.repository.revision_tree('1')
240
 
        self.inv_1 = self.branch.repository.get_inventory('1')
241
 
        self.file_1 = self.inv_1['fileid']
242
 
        self.file_1b = self.inv_1['binfileid']
243
 
        self.tree_2 = self.wt
244
 
        self.inv_2 = self.tree_2.read_working_inventory()
245
 
        self.file_2 = self.inv_2['fileid']
246
 
        self.file_2b = self.inv_2['binfileid']
247
 
        if has_symlinks():
248
 
            self.link_1 = self.inv_1['linkid']
249
 
            self.link_2 = self.inv_2['linkid']
250
 
 
251
 
    def test_file_diff_deleted(self):
252
 
        output = StringIO()
253
 
        self.file_1.diff(internal_diff, 
254
 
                          "old_label", self.tree_1,
255
 
                          "/dev/null", None, None,
256
 
                          output)
257
 
        self.assertEqual(output.getvalue(), "--- old_label\n"
258
 
                                            "+++ /dev/null\n"
259
 
                                            "@@ -1,1 +0,0 @@\n"
260
 
                                            "-foo\n"
261
 
                                            "\n")
262
 
 
263
 
    def test_file_diff_added(self):
264
 
        output = StringIO()
265
 
        self.file_1.diff(internal_diff, 
266
 
                          "new_label", self.tree_1,
267
 
                          "/dev/null", None, None,
268
 
                          output, reverse=True)
269
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
270
 
                                            "+++ new_label\n"
271
 
                                            "@@ -0,0 +1,1 @@\n"
272
 
                                            "+foo\n"
273
 
                                            "\n")
274
 
 
275
 
    def test_file_diff_changed(self):
276
 
        output = StringIO()
277
 
        self.file_1.diff(internal_diff, 
278
 
                          "/dev/null", self.tree_1, 
279
 
                          "new_label", self.file_2, self.tree_2,
280
 
                          output)
281
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
282
 
                                            "+++ new_label\n"
283
 
                                            "@@ -1,1 +1,1 @@\n"
284
 
                                            "-foo\n"
285
 
                                            "+bar\n"
286
 
                                            "\n")
287
 
        
288
 
    def test_file_diff_binary(self):
289
 
        output = StringIO()
290
 
        self.file_1.diff(internal_diff, 
291
 
                          "/dev/null", self.tree_1, 
292
 
                          "new_label", self.file_2b, self.tree_2,
293
 
                          output)
294
 
        self.assertEqual(output.getvalue(), 
295
 
                         "Binary files /dev/null and new_label differ\n")
296
 
    def test_link_diff_deleted(self):
297
 
        if not has_symlinks():
298
 
            return
299
 
        output = StringIO()
300
 
        self.link_1.diff(internal_diff, 
301
 
                          "old_label", self.tree_1,
302
 
                          "/dev/null", None, None,
303
 
                          output)
304
 
        self.assertEqual(output.getvalue(),
305
 
                         "=== target was 'target1'\n")
306
 
 
307
 
    def test_link_diff_added(self):
308
 
        if not has_symlinks():
309
 
            return
310
 
        output = StringIO()
311
 
        self.link_1.diff(internal_diff, 
312
 
                          "new_label", self.tree_1,
313
 
                          "/dev/null", None, None,
314
 
                          output, reverse=True)
315
 
        self.assertEqual(output.getvalue(),
316
 
                         "=== target is 'target1'\n")
317
 
 
318
 
    def test_link_diff_changed(self):
319
 
        if not has_symlinks():
320
 
            return
321
 
        output = StringIO()
322
 
        self.link_1.diff(internal_diff, 
323
 
                          "/dev/null", self.tree_1, 
324
 
                          "new_label", self.link_2, self.tree_2,
325
 
                          output)
326
 
        self.assertEqual(output.getvalue(),
327
 
                         "=== target changed 'target1' => 'target2'\n")
328
 
 
329
 
 
330
 
class TestSnapshot(TestCaseWithTransport):
331
 
 
332
 
    def setUp(self):
333
 
        # for full testing we'll need a branch
334
 
        # with a subdir to test parent changes.
335
 
        # and a file, link and dir under that.
336
 
        # but right now I only need one attribute
337
 
        # to change, and then test merge patterns
338
 
        # with fake parent entries.
339
 
        super(TestSnapshot, self).setUp()
340
 
        self.wt = self.make_branch_and_tree('.')
341
 
        self.branch = self.wt.branch
342
 
        self.build_tree(['subdir/', 'subdir/file'], line_endings='binary')
343
 
        self.wt.add(['subdir', 'subdir/file'],
344
 
                                       ['dirid', 'fileid'])
345
 
        if has_symlinks():
346
 
            pass
347
 
        self.wt.commit('message_1', rev_id = '1')
348
 
        self.tree_1 = self.branch.repository.revision_tree('1')
349
 
        self.inv_1 = self.branch.repository.get_inventory('1')
350
 
        self.file_1 = self.inv_1['fileid']
351
 
        self.file_active = self.wt.inventory['fileid']
352
 
        self.builder = self.branch.get_commit_builder([], timestamp=time.time(), revision_id='2')
353
 
 
354
 
    def test_snapshot_new_revision(self):
355
 
        # This tests that a simple commit with no parents makes a new
356
 
        # revision value in the inventory entry
357
 
        self.file_active.snapshot('2', 'subdir/file', {}, self.wt, self.builder)
358
 
        # expected outcome - file_1 has a revision id of '2', and we can get
359
 
        # its text of 'file contents' out of the weave.
360
 
        self.assertEqual(self.file_1.revision, '1')
361
 
        self.assertEqual(self.file_active.revision, '2')
362
 
        # this should be a separate test probably, but lets check it once..
363
 
        lines = self.branch.repository.weave_store.get_weave(
364
 
            'fileid', 
365
 
            self.branch.get_transaction()).get_lines('2')
366
 
        self.assertEqual(lines, ['contents of subdir/file\n'])
367
 
 
368
 
    def test_snapshot_unchanged(self):
369
 
        #This tests that a simple commit does not make a new entry for
370
 
        # an unchanged inventory entry
371
 
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
372
 
                                  self.wt, self.builder)
373
 
        self.assertEqual(self.file_1.revision, '1')
374
 
        self.assertEqual(self.file_active.revision, '1')
375
 
        vf = self.branch.repository.weave_store.get_weave(
376
 
            'fileid', 
377
 
            self.branch.repository.get_transaction())
378
 
        self.assertRaises(errors.RevisionNotPresent,
379
 
                          vf.get_lines,
380
 
                          '2')
381
 
 
382
 
    def test_snapshot_merge_identical_different_revid(self):
383
 
        # This tests that a commit with two identical parents, one of which has
384
 
        # a different revision id, results in a new revision id in the entry.
385
 
        # 1->other, commit a merge of other against 1, results in 2.
386
 
        other_ie = inventory.InventoryFile('fileid', 'newname', self.file_1.parent_id)
387
 
        other_ie = inventory.InventoryFile('fileid', 'file', self.file_1.parent_id)
388
 
        other_ie.revision = '1'
389
 
        other_ie.text_sha1 = self.file_1.text_sha1
390
 
        other_ie.text_size = self.file_1.text_size
391
 
        self.assertEqual(self.file_1, other_ie)
392
 
        other_ie.revision = 'other'
393
 
        self.assertNotEqual(self.file_1, other_ie)
394
 
        versionfile = self.branch.repository.weave_store.get_weave(
395
 
            'fileid', self.branch.repository.get_transaction())
396
 
        versionfile.clone_text('other', '1', ['1'])
397
 
        self.file_active.snapshot('2', 'subdir/file', 
398
 
                                  {'1':self.file_1, 'other':other_ie},
399
 
                                  self.wt, self.builder)
400
 
        self.assertEqual(self.file_active.revision, '2')
401
 
 
402
 
    def test_snapshot_changed(self):
403
 
        # This tests that a commit with one different parent results in a new
404
 
        # revision id in the entry.
405
 
        self.file_active.name='newname'
406
 
        rename('subdir/file', 'subdir/newname')
407
 
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
408
 
                                  self.wt, self.builder)
409
 
        # expected outcome - file_1 has a revision id of '2'
410
 
        self.assertEqual(self.file_active.revision, '2')
411
 
 
412
 
 
413
 
class TestPreviousHeads(TestCaseWithTransport):
414
 
 
415
 
    def setUp(self):
416
 
        # we want several inventories, that respectively
417
 
        # give use the following scenarios:
418
 
        # A) fileid not in any inventory (A),
419
 
        # B) fileid present in one inventory (B) and (A,B)
420
 
        # C) fileid present in two inventories, and they
421
 
        #   are not mutual descendents (B, C)
422
 
        # D) fileid present in two inventories and one is
423
 
        #   a descendent of the other. (B, D)
424
 
        super(TestPreviousHeads, self).setUp()
425
 
        self.wt = self.make_branch_and_tree('.')
426
 
        self.branch = self.wt.branch
427
 
        self.build_tree(['file'])
428
 
        self.wt.commit('new branch', allow_pointless=True, rev_id='A')
429
 
        self.inv_A = self.branch.repository.get_inventory('A')
430
 
        self.wt.add(['file'], ['fileid'])
431
 
        self.wt.commit('add file', rev_id='B')
432
 
        self.inv_B = self.branch.repository.get_inventory('B')
433
 
        uncommit(self.branch, tree=self.wt)
434
 
        self.assertEqual(self.branch.revision_history(), ['A'])
435
 
        self.wt.commit('another add of file', rev_id='C')
436
 
        self.inv_C = self.branch.repository.get_inventory('C')
437
 
        self.wt.add_parent_tree_id('B')
438
 
        self.wt.commit('merge in B', rev_id='D')
439
 
        self.inv_D = self.branch.repository.get_inventory('D')
440
 
        self.file_active = self.wt.inventory['fileid']
441
 
        self.weave = self.branch.repository.weave_store.get_weave('fileid',
442
 
            self.branch.repository.get_transaction())
443
 
        
444
 
    def get_previous_heads(self, inventories):
445
 
        return self.file_active.find_previous_heads(
446
 
            inventories, 
447
 
            self.branch.repository.weave_store,
448
 
            self.branch.repository.get_transaction())
449
 
        
450
 
    def test_fileid_in_no_inventory(self):
451
 
        self.assertEqual({}, self.get_previous_heads([self.inv_A]))
452
 
 
453
 
    def test_fileid_in_one_inventory(self):
454
 
        self.assertEqual({'B':self.inv_B['fileid']},
455
 
                         self.get_previous_heads([self.inv_B]))
456
 
        self.assertEqual({'B':self.inv_B['fileid']},
457
 
                         self.get_previous_heads([self.inv_A, self.inv_B]))
458
 
        self.assertEqual({'B':self.inv_B['fileid']},
459
 
                         self.get_previous_heads([self.inv_B, self.inv_A]))
460
 
 
461
 
    def test_fileid_in_two_inventories_gives_both_entries(self):
462
 
        self.assertEqual({'B':self.inv_B['fileid'],
463
 
                          'C':self.inv_C['fileid']},
464
 
                          self.get_previous_heads([self.inv_B, self.inv_C]))
465
 
        self.assertEqual({'B':self.inv_B['fileid'],
466
 
                          'C':self.inv_C['fileid']},
467
 
                          self.get_previous_heads([self.inv_C, self.inv_B]))
468
 
 
469
 
    def test_fileid_in_two_inventories_already_merged_gives_head(self):
470
 
        self.assertEqual({'D':self.inv_D['fileid']},
471
 
                         self.get_previous_heads([self.inv_B, self.inv_D]))
472
 
        self.assertEqual({'D':self.inv_D['fileid']},
473
 
                         self.get_previous_heads([self.inv_D, self.inv_B]))
474
 
 
475
 
    # TODO: test two inventories with the same file revision 
476
 
 
477
 
 
478
113
class TestDescribeChanges(TestCase):
479
114
 
480
115
    def test_describe_change(self):
531
166
    def assertChangeDescription(self, expected_change, old_ie, new_ie):
532
167
        change = InventoryEntry.describe_change(old_ie, new_ie)
533
168
        self.assertEqual(expected_change, change)
534
 
 
535
 
 
536
 
class TestRevert(TestCaseWithTransport):
537
 
 
538
 
    def test_dangling_id(self):
539
 
        wt = self.make_branch_and_tree('b1')
540
 
        self.assertEqual(len(wt.inventory), 1)
541
 
        open('b1/a', 'wb').write('a test\n')
542
 
        wt.add('a')
543
 
        self.assertEqual(len(wt.inventory), 2)
544
 
        os.unlink('b1/a')
545
 
        wt.revert([])
546
 
        self.assertEqual(len(wt.inventory), 1)