~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: John Arbash Meinel
  • Date: 2005-11-30 15:43:57 UTC
  • mto: (1185.50.1 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1518.
  • Revision ID: john@arbash-meinel.com-20051130154357-614206b3a7b83cd0
Refactored bzrlib/ui.py into a module with the possibility for multiple ui forms.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
from cStringIO import StringIO
18
18
import os
19
 
import time
20
19
 
21
 
from bzrlib import errors, inventory, osutils
22
20
from bzrlib.branch import Branch
 
21
from bzrlib.clone import copy_branch
 
22
import bzrlib.errors as errors
23
23
from bzrlib.diff import internal_diff
24
 
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
 
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.tests import TestCase, TestCaseInTempDir
31
28
 
32
29
 
33
30
class TestInventory(TestCase):
34
31
 
35
32
    def test_is_within(self):
 
33
        from bzrlib.osutils import is_inside_any
36
34
 
37
 
        SRC_FOO_C = pathjoin('src', 'foo.c')
 
35
        SRC_FOO_C = os.path.join('src', 'foo.c')
38
36
        for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
39
37
                         (['src'], SRC_FOO_C),
40
38
                         (['src'], 'src'),
44
42
        for dirs, fn in [(['src'], 'srccontrol'),
45
43
                         (['src'], 'srccontrol/foo')]:
46
44
            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
45
            
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
46
    def test_ids(self):
63
47
        """Test detection of files within selected directories."""
64
48
        inv = Inventory()
75
59
        
76
60
        self.assert_('src-id' in inv)
77
61
 
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
 
            ('Makefile', 'makefile-id'),
90
 
            ('doc', 'doc-id'),
91
 
            ('src', 'src-id'),
92
 
            ('src/bye.c', 'bye-id'),
93
 
            ('src/hello.c', 'hello-id'),
94
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
95
 
            
96
 
    def test_iter_entries_by_dir(self):
97
 
        inv = Inventory()
98
 
        
99
 
        for args in [('src', 'directory', 'src-id'), 
100
 
                     ('doc', 'directory', 'doc-id'), 
101
 
                     ('src/hello.c', 'file', 'hello-id'),
102
 
                     ('src/bye.c', 'file', 'bye-id'),
103
 
                     ('zz', 'file', 'zz-id'),
104
 
                     ('src/sub/', 'directory', 'sub-id'),
105
 
                     ('src/zz.c', 'file', 'zzc-id'),
106
 
                     ('src/sub/a', 'file', 'a-id'),
107
 
                     ('Makefile', 'file', 'makefile-id')]:
108
 
            inv.add_path(*args)
109
 
 
110
 
        self.assertEqual([
111
 
            ('Makefile', 'makefile-id'),
112
 
            ('doc', 'doc-id'),
113
 
            ('src', 'src-id'),
114
 
            ('zz', 'zz-id'),
115
 
            ('src/bye.c', 'bye-id'),
116
 
            ('src/hello.c', 'hello-id'),
117
 
            ('src/sub', 'sub-id'),
118
 
            ('src/zz.c', 'zzc-id'),
119
 
            ('src/sub/a', 'a-id'),
120
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
121
 
            
 
62
 
122
63
    def test_version(self):
123
64
        """Inventory remembers the text's version."""
124
65
        inv = Inventory()
191
132
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
192
133
        self.failIf(link.has_text())
193
134
 
194
 
    def test_make_entry(self):
195
 
        self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
196
 
            inventory.InventoryFile)
197
 
        self.assertIsInstance(inventory.make_entry("symlink", "name", ROOT_ID),
198
 
            inventory.InventoryLink)
199
 
        self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
200
 
            inventory.InventoryDirectory)
201
 
 
202
 
    def test_make_entry_non_normalized(self):
203
 
        orig_normalized_filename = osutils.normalized_filename
204
 
 
205
 
        try:
206
 
            osutils.normalized_filename = osutils._accessible_normalized_filename
207
 
            entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
208
 
            self.assertEqual(u'\xe5', entry.name)
209
 
            self.assertIsInstance(entry, inventory.InventoryFile)
210
 
 
211
 
            osutils.normalized_filename = osutils._inaccessible_normalized_filename
212
 
            self.assertRaises(errors.InvalidNormalization,
213
 
                    inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
214
 
        finally:
215
 
            osutils.normalized_filename = orig_normalized_filename
216
 
 
217
 
 
218
 
class TestEntryDiffing(TestCaseWithTransport):
 
135
 
 
136
class TestEntryDiffing(TestCaseInTempDir):
219
137
 
220
138
    def setUp(self):
221
139
        super(TestEntryDiffing, self).setUp()
222
 
        self.wt = self.make_branch_and_tree('.')
223
 
        self.branch = self.wt.branch
 
140
        self.branch = Branch.initialize(u'.')
 
141
        self.wt = self.branch.working_tree()
224
142
        print >> open('file', 'wb'), 'foo'
225
 
        print >> open('binfile', 'wb'), 'foo'
226
 
        self.wt.add(['file'], ['fileid'])
227
 
        self.wt.add(['binfile'], ['binfileid'])
 
143
        self.branch.working_tree().add(['file'], ['fileid'])
228
144
        if has_symlinks():
229
145
            os.symlink('target1', 'symlink')
230
 
            self.wt.add(['symlink'], ['linkid'])
 
146
            self.branch.working_tree().add(['symlink'], ['linkid'])
231
147
        self.wt.commit('message_1', rev_id = '1')
232
148
        print >> open('file', 'wb'), 'bar'
233
 
        print >> open('binfile', 'wb'), 'x' * 1023 + '\x00'
234
149
        if has_symlinks():
235
150
            os.unlink('symlink')
236
151
            os.symlink('target2', 'symlink')
237
 
        self.tree_1 = self.branch.repository.revision_tree('1')
238
 
        self.inv_1 = self.branch.repository.get_inventory('1')
 
152
        self.tree_1 = self.branch.revision_tree('1')
 
153
        self.inv_1 = self.branch.get_inventory('1')
239
154
        self.file_1 = self.inv_1['fileid']
240
 
        self.file_1b = self.inv_1['binfileid']
241
 
        self.tree_2 = self.wt
 
155
        self.tree_2 = self.branch.working_tree()
242
156
        self.inv_2 = self.tree_2.read_working_inventory()
243
157
        self.file_2 = self.inv_2['fileid']
244
 
        self.file_2b = self.inv_2['binfileid']
245
158
        if has_symlinks():
246
159
            self.link_1 = self.inv_1['linkid']
247
160
            self.link_2 = self.inv_2['linkid']
252
165
                          "old_label", self.tree_1,
253
166
                          "/dev/null", None, None,
254
167
                          output)
255
 
        self.assertEqual(output.getvalue(), "--- old_label\n"
256
 
                                            "+++ /dev/null\n"
 
168
        self.assertEqual(output.getvalue(), "--- old_label\t\n"
 
169
                                            "+++ /dev/null\t\n"
257
170
                                            "@@ -1,1 +0,0 @@\n"
258
171
                                            "-foo\n"
259
172
                                            "\n")
264
177
                          "new_label", self.tree_1,
265
178
                          "/dev/null", None, None,
266
179
                          output, reverse=True)
267
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
268
 
                                            "+++ new_label\n"
 
180
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
181
                                            "+++ new_label\t\n"
269
182
                                            "@@ -0,0 +1,1 @@\n"
270
183
                                            "+foo\n"
271
184
                                            "\n")
276
189
                          "/dev/null", self.tree_1, 
277
190
                          "new_label", self.file_2, self.tree_2,
278
191
                          output)
279
 
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
280
 
                                            "+++ new_label\n"
 
192
        self.assertEqual(output.getvalue(), "--- /dev/null\t\n"
 
193
                                            "+++ new_label\t\n"
281
194
                                            "@@ -1,1 +1,1 @@\n"
282
195
                                            "-foo\n"
283
196
                                            "+bar\n"
284
197
                                            "\n")
285
198
        
286
 
    def test_file_diff_binary(self):
287
 
        output = StringIO()
288
 
        self.file_1.diff(internal_diff, 
289
 
                          "/dev/null", self.tree_1, 
290
 
                          "new_label", self.file_2b, self.tree_2,
291
 
                          output)
292
 
        self.assertEqual(output.getvalue(), 
293
 
                         "Binary files /dev/null and new_label differ\n")
294
199
    def test_link_diff_deleted(self):
295
200
        if not has_symlinks():
296
201
            return
325
230
                         "=== target changed 'target1' => 'target2'\n")
326
231
 
327
232
 
328
 
class TestSnapshot(TestCaseWithTransport):
 
233
class TestSnapshot(TestCaseInTempDir):
329
234
 
330
235
    def setUp(self):
331
236
        # for full testing we'll need a branch
335
240
        # to change, and then test merge patterns
336
241
        # with fake parent entries.
337
242
        super(TestSnapshot, self).setUp()
338
 
        self.wt = self.make_branch_and_tree('.')
339
 
        self.branch = self.wt.branch
 
243
        self.branch = Branch.initialize(u'.')
340
244
        self.build_tree(['subdir/', 'subdir/file'], line_endings='binary')
341
 
        self.wt.add(['subdir', 'subdir/file'],
 
245
        self.branch.working_tree().add(['subdir', 'subdir/file'],
342
246
                                       ['dirid', 'fileid'])
343
247
        if has_symlinks():
344
248
            pass
 
249
        self.wt = self.branch.working_tree()
345
250
        self.wt.commit('message_1', rev_id = '1')
346
 
        self.tree_1 = self.branch.repository.revision_tree('1')
347
 
        self.inv_1 = self.branch.repository.get_inventory('1')
 
251
        self.tree_1 = self.branch.revision_tree('1')
 
252
        self.inv_1 = self.branch.get_inventory('1')
348
253
        self.file_1 = self.inv_1['fileid']
349
 
        self.file_active = self.wt.inventory['fileid']
350
 
        self.builder = self.branch.get_commit_builder([], timestamp=time.time(), revision_id='2')
 
254
        self.work_tree = self.branch.working_tree()
 
255
        self.file_active = self.work_tree.inventory['fileid']
351
256
 
352
257
    def test_snapshot_new_revision(self):
353
258
        # This tests that a simple commit with no parents makes a new
354
259
        # revision value in the inventory entry
355
 
        self.file_active.snapshot('2', 'subdir/file', {}, self.wt, self.builder)
 
260
        self.file_active.snapshot('2', 'subdir/file', {}, self.work_tree, 
 
261
                                  self.branch.weave_store,
 
262
                                  self.branch.get_transaction())
356
263
        # expected outcome - file_1 has a revision id of '2', and we can get
357
264
        # its text of 'file contents' out of the weave.
358
265
        self.assertEqual(self.file_1.revision, '1')
359
266
        self.assertEqual(self.file_active.revision, '2')
360
267
        # this should be a separate test probably, but lets check it once..
361
 
        lines = self.branch.repository.weave_store.get_weave(
362
 
            'fileid', 
363
 
            self.branch.get_transaction()).get_lines('2')
 
268
        lines = self.branch.weave_store.get_lines('fileid','2',
 
269
            self.branch.get_transaction())
364
270
        self.assertEqual(lines, ['contents of subdir/file\n'])
365
271
 
366
272
    def test_snapshot_unchanged(self):
367
273
        #This tests that a simple commit does not make a new entry for
368
274
        # an unchanged inventory entry
369
275
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
370
 
                                  self.wt, self.builder)
 
276
                                  self.work_tree, self.branch.weave_store,
 
277
                                  self.branch.get_transaction())
371
278
        self.assertEqual(self.file_1.revision, '1')
372
279
        self.assertEqual(self.file_active.revision, '1')
373
 
        vf = self.branch.repository.weave_store.get_weave(
374
 
            'fileid', 
375
 
            self.branch.repository.get_transaction())
376
 
        self.assertRaises(errors.RevisionNotPresent,
377
 
                          vf.get_lines,
378
 
                          '2')
 
280
        self.assertRaises(errors.WeaveError,
 
281
                          self.branch.weave_store.get_lines, 'fileid', '2',
 
282
                          self.branch.get_transaction())
379
283
 
380
284
    def test_snapshot_merge_identical_different_revid(self):
381
285
        # This tests that a commit with two identical parents, one of which has
389
293
        self.assertEqual(self.file_1, other_ie)
390
294
        other_ie.revision = 'other'
391
295
        self.assertNotEqual(self.file_1, other_ie)
392
 
        versionfile = self.branch.repository.weave_store.get_weave(
393
 
            'fileid', self.branch.repository.get_transaction())
394
 
        versionfile.clone_text('other', '1', ['1'])
 
296
        self.branch.weave_store.add_identical_text('fileid', '1', 'other', ['1'],
 
297
            self.branch.get_transaction())
395
298
        self.file_active.snapshot('2', 'subdir/file', 
396
299
                                  {'1':self.file_1, 'other':other_ie},
397
 
                                  self.wt, self.builder)
 
300
                                  self.work_tree, self.branch.weave_store,
 
301
                                  self.branch.get_transaction())
398
302
        self.assertEqual(self.file_active.revision, '2')
399
303
 
400
304
    def test_snapshot_changed(self):
403
307
        self.file_active.name='newname'
404
308
        rename('subdir/file', 'subdir/newname')
405
309
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
406
 
                                  self.wt, self.builder)
 
310
                                  self.work_tree, 
 
311
                                  self.branch.weave_store,
 
312
                                  self.branch.get_transaction())
407
313
        # expected outcome - file_1 has a revision id of '2'
408
314
        self.assertEqual(self.file_active.revision, '2')
409
315
 
410
316
 
411
 
class TestPreviousHeads(TestCaseWithTransport):
 
317
class TestPreviousHeads(TestCaseInTempDir):
412
318
 
413
319
    def setUp(self):
414
320
        # we want several inventories, that respectively
420
326
        # D) fileid present in two inventories and one is
421
327
        #   a descendent of the other. (B, D)
422
328
        super(TestPreviousHeads, self).setUp()
423
 
        self.wt = self.make_branch_and_tree('.')
424
 
        self.branch = self.wt.branch
425
329
        self.build_tree(['file'])
 
330
        self.branch = Branch.initialize(u'.')
 
331
        self.wt = self.branch.working_tree()
426
332
        self.wt.commit('new branch', allow_pointless=True, rev_id='A')
427
 
        self.inv_A = self.branch.repository.get_inventory('A')
428
 
        self.wt.add(['file'], ['fileid'])
 
333
        self.inv_A = self.branch.get_inventory('A')
 
334
        self.branch.working_tree().add(['file'], ['fileid'])
429
335
        self.wt.commit('add file', rev_id='B')
430
 
        self.inv_B = self.branch.repository.get_inventory('B')
431
 
        uncommit(self.branch, tree=self.wt)
 
336
        self.inv_B = self.branch.get_inventory('B')
 
337
        self.branch.put_controlfile('revision-history', 'A\n')
432
338
        self.assertEqual(self.branch.revision_history(), ['A'])
433
339
        self.wt.commit('another add of file', rev_id='C')
434
 
        self.inv_C = self.branch.repository.get_inventory('C')
 
340
        self.inv_C = self.branch.get_inventory('C')
435
341
        self.wt.add_pending_merge('B')
436
342
        self.wt.commit('merge in B', rev_id='D')
437
 
        self.inv_D = self.branch.repository.get_inventory('D')
 
343
        self.inv_D = self.branch.get_inventory('D')
438
344
        self.file_active = self.wt.inventory['fileid']
439
 
        self.weave = self.branch.repository.weave_store.get_weave('fileid',
440
 
            self.branch.repository.get_transaction())
 
345
        self.weave = self.branch.weave_store.get_weave('fileid',
 
346
            self.branch.get_transaction())
441
347
        
442
348
    def get_previous_heads(self, inventories):
443
 
        return self.file_active.find_previous_heads(
444
 
            inventories, 
445
 
            self.branch.repository.weave_store,
446
 
            self.branch.repository.get_transaction())
 
349
        return self.file_active.find_previous_heads(inventories, self.weave)
447
350
        
448
351
    def test_fileid_in_no_inventory(self):
449
352
        self.assertEqual({}, self.get_previous_heads([self.inv_A]))
471
374
                         self.get_previous_heads([self.inv_D, self.inv_B]))
472
375
 
473
376
    # TODO: test two inventories with the same file revision 
474
 
 
475
 
 
476
 
class TestDescribeChanges(TestCase):
477
 
 
478
 
    def test_describe_change(self):
479
 
        # we need to test the following change combinations:
480
 
        # rename
481
 
        # reparent
482
 
        # modify
483
 
        # gone
484
 
        # added
485
 
        # renamed/reparented and modified
486
 
        # change kind (perhaps can't be done yet?)
487
 
        # also, merged in combination with all of these?
488
 
        old_a = InventoryFile('a-id', 'a_file', ROOT_ID)
489
 
        old_a.text_sha1 = '123132'
490
 
        old_a.text_size = 0
491
 
        new_a = InventoryFile('a-id', 'a_file', ROOT_ID)
492
 
        new_a.text_sha1 = '123132'
493
 
        new_a.text_size = 0
494
 
 
495
 
        self.assertChangeDescription('unchanged', old_a, new_a)
496
 
 
497
 
        new_a.text_size = 10
498
 
        new_a.text_sha1 = 'abcabc'
499
 
        self.assertChangeDescription('modified', old_a, new_a)
500
 
 
501
 
        self.assertChangeDescription('added', None, new_a)
502
 
        self.assertChangeDescription('removed', old_a, None)
503
 
        # perhaps a bit questionable but seems like the most reasonable thing...
504
 
        self.assertChangeDescription('unchanged', None, None)
505
 
 
506
 
        # in this case it's both renamed and modified; show a rename and 
507
 
        # modification:
508
 
        new_a.name = 'newfilename'
509
 
        self.assertChangeDescription('modified and renamed', old_a, new_a)
510
 
 
511
 
        # reparenting is 'renaming'
512
 
        new_a.name = old_a.name
513
 
        new_a.parent_id = 'somedir-id'
514
 
        self.assertChangeDescription('modified and renamed', old_a, new_a)
515
 
 
516
 
        # reset the content values so its not modified
517
 
        new_a.text_size = old_a.text_size
518
 
        new_a.text_sha1 = old_a.text_sha1
519
 
        new_a.name = old_a.name
520
 
 
521
 
        new_a.name = 'newfilename'
522
 
        self.assertChangeDescription('renamed', old_a, new_a)
523
 
 
524
 
        # reparenting is 'renaming'
525
 
        new_a.name = old_a.name
526
 
        new_a.parent_id = 'somedir-id'
527
 
        self.assertChangeDescription('renamed', old_a, new_a)
528
 
 
529
 
    def assertChangeDescription(self, expected_change, old_ie, new_ie):
530
 
        change = InventoryEntry.describe_change(old_ie, new_ie)
531
 
        self.assertEqual(expected_change, change)
532
 
 
533
 
 
534
 
class TestRevert(TestCaseWithTransport):
535
 
 
536
 
    def test_dangling_id(self):
537
 
        wt = self.make_branch_and_tree('b1')
538
 
        self.assertEqual(len(wt.inventory), 1)
539
 
        open('b1/a', 'wb').write('a test\n')
540
 
        wt.add('a')
541
 
        self.assertEqual(len(wt.inventory), 2)
542
 
        os.unlink('b1/a')
543
 
        wt.revert([])
544
 
        self.assertEqual(len(wt.inventory), 1)