~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Martin Pool
  • Date: 2005-05-12 02:18:48 UTC
  • Revision ID: mbp@sourcefrog.net-20050512021848-d1a727373aee2c85
- WorkingTree loads statcache in constructor and holds
  it permanently

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
from bzrlib import errors, inventory, osutils
18
 
from bzrlib.inventory import (Inventory, ROOT_ID, InventoryFile,
19
 
    InventoryDirectory, InventoryEntry, TreeReference)
20
 
from bzrlib.osutils import (pathjoin, is_inside_any, 
21
 
    is_inside_or_parent_of_any)
22
 
from bzrlib.tests import TestCase
23
 
 
24
 
 
25
 
class TestInventory(TestCase):
26
 
 
27
 
    def test_add_path(self):
28
 
 
29
 
        inv = Inventory(root_id=None)
30
 
        self.assertIs(None, inv.root)
31
 
        ie = inv.add_path("", "directory", "my-root")
32
 
        self.assertEqual("my-root", ie.file_id)
33
 
        self.assertIs(ie, inv.root)
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_non_directory_children(self):
79
 
        """Test path2id when a parent directory has no children"""
80
 
        inv = inventory.Inventory('tree_root')
81
 
        inv.add(inventory.InventoryFile('file-id','file', 
82
 
                                        parent_id='tree_root'))
83
 
        inv.add(inventory.InventoryLink('link-id','link', 
84
 
                                        parent_id='tree_root'))
85
 
        self.assertIs(None, inv.path2id('file/subfile'))
86
 
        self.assertIs(None, inv.path2id('link/subfile'))
87
 
 
88
 
    def test_iter_entries(self):
89
 
        inv = Inventory()
90
 
        
91
 
        for args in [('src', 'directory', 'src-id'), 
92
 
                     ('doc', 'directory', 'doc-id'), 
93
 
                     ('src/hello.c', 'file', 'hello-id'),
94
 
                     ('src/bye.c', 'file', 'bye-id'),
95
 
                     ('Makefile', 'file', 'makefile-id')]:
96
 
            inv.add_path(*args)
97
 
 
98
 
        self.assertEqual([
99
 
            ('', ROOT_ID),
100
 
            ('Makefile', 'makefile-id'),
101
 
            ('doc', 'doc-id'),
102
 
            ('src', 'src-id'),
103
 
            ('src/bye.c', 'bye-id'),
104
 
            ('src/hello.c', 'hello-id'),
105
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
106
 
            
107
 
    def test_iter_entries_by_dir(self):
108
 
        inv = Inventory()
109
 
        
110
 
        for args in [('src', 'directory', 'src-id'), 
111
 
                     ('doc', 'directory', 'doc-id'), 
112
 
                     ('src/hello.c', 'file', 'hello-id'),
113
 
                     ('src/bye.c', 'file', 'bye-id'),
114
 
                     ('zz', 'file', 'zz-id'),
115
 
                     ('src/sub/', 'directory', 'sub-id'),
116
 
                     ('src/zz.c', 'file', 'zzc-id'),
117
 
                     ('src/sub/a', 'file', 'a-id'),
118
 
                     ('Makefile', 'file', 'makefile-id')]:
119
 
            inv.add_path(*args)
120
 
 
121
 
        self.assertEqual([
122
 
            ('', ROOT_ID),
123
 
            ('Makefile', 'makefile-id'),
124
 
            ('doc', 'doc-id'),
125
 
            ('src', 'src-id'),
126
 
            ('zz', 'zz-id'),
127
 
            ('src/bye.c', 'bye-id'),
128
 
            ('src/hello.c', 'hello-id'),
129
 
            ('src/sub', 'sub-id'),
130
 
            ('src/zz.c', 'zzc-id'),
131
 
            ('src/sub/a', 'a-id'),
132
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
133
 
            
134
 
        self.assertEqual([
135
 
            ('', ROOT_ID),
136
 
            ('Makefile', 'makefile-id'),
137
 
            ('doc', 'doc-id'),
138
 
            ('src', 'src-id'),
139
 
            ('zz', 'zz-id'),
140
 
            ('src/bye.c', 'bye-id'),
141
 
            ('src/hello.c', 'hello-id'),
142
 
            ('src/sub', 'sub-id'),
143
 
            ('src/zz.c', 'zzc-id'),
144
 
            ('src/sub/a', 'a-id'),
145
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
146
 
                specific_file_ids=('a-id', 'zzc-id', 'doc-id', ROOT_ID,
147
 
                'hello-id', 'bye-id', 'zz-id', 'src-id', 'makefile-id', 
148
 
                'sub-id'))])
149
 
 
150
 
        self.assertEqual([
151
 
            ('Makefile', 'makefile-id'),
152
 
            ('doc', 'doc-id'),
153
 
            ('zz', 'zz-id'),
154
 
            ('src/bye.c', 'bye-id'),
155
 
            ('src/hello.c', 'hello-id'),
156
 
            ('src/zz.c', 'zzc-id'),
157
 
            ('src/sub/a', 'a-id'),
158
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
159
 
                specific_file_ids=('a-id', 'zzc-id', 'doc-id',
160
 
                'hello-id', 'bye-id', 'zz-id', 'makefile-id'))])
161
 
 
162
 
        self.assertEqual([
163
 
            ('Makefile', 'makefile-id'),
164
 
            ('src/bye.c', 'bye-id'),
165
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
166
 
                specific_file_ids=('bye-id', 'makefile-id'))])
167
 
 
168
 
        self.assertEqual([
169
 
            ('Makefile', 'makefile-id'),
170
 
            ('src/bye.c', 'bye-id'),
171
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
172
 
                specific_file_ids=('bye-id', 'makefile-id'))])
173
 
 
174
 
        self.assertEqual([
175
 
            ('src/bye.c', 'bye-id'),
176
 
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
177
 
                specific_file_ids=('bye-id',))])
178
 
 
179
 
    def test_add_recursive(self):
180
 
        parent = InventoryDirectory('src-id', 'src', ROOT_ID)
181
 
        child = InventoryFile('hello-id', 'hello.c', 'src-id')
182
 
        parent.children[child.file_id] = child
183
 
        inv = Inventory()
184
 
        inv.add(parent)
185
 
        self.assertEqual('src/hello.c', inv.id2path('hello-id'))
186
 
 
187
 
 
188
 
class TestInventoryEntry(TestCase):
189
 
 
190
 
    def test_file_kind_character(self):
191
 
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
192
 
        self.assertEqual(file.kind_character(), '')
193
 
 
194
 
    def test_dir_kind_character(self):
195
 
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
196
 
        self.assertEqual(dir.kind_character(), '/')
197
 
 
198
 
    def test_link_kind_character(self):
199
 
        dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
200
 
        self.assertEqual(dir.kind_character(), '')
201
 
 
202
 
    def test_dir_detect_changes(self):
203
 
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
204
 
        left.text_sha1 = 123
205
 
        left.executable = True
206
 
        left.symlink_target='foo'
207
 
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
208
 
        right.text_sha1 = 321
209
 
        right.symlink_target='bar'
210
 
        self.assertEqual((False, False), left.detect_changes(right))
211
 
        self.assertEqual((False, False), right.detect_changes(left))
212
 
 
213
 
    def test_file_detect_changes(self):
214
 
        left = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
215
 
        left.text_sha1 = 123
216
 
        right = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
217
 
        right.text_sha1 = 123
218
 
        self.assertEqual((False, False), left.detect_changes(right))
219
 
        self.assertEqual((False, False), right.detect_changes(left))
220
 
        left.executable = True
221
 
        self.assertEqual((False, True), left.detect_changes(right))
222
 
        self.assertEqual((False, True), right.detect_changes(left))
223
 
        right.text_sha1 = 321
224
 
        self.assertEqual((True, True), left.detect_changes(right))
225
 
        self.assertEqual((True, True), right.detect_changes(left))
226
 
 
227
 
    def test_symlink_detect_changes(self):
228
 
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
229
 
        left.text_sha1 = 123
230
 
        left.executable = True
231
 
        left.symlink_target='foo'
232
 
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
233
 
        right.text_sha1 = 321
234
 
        right.symlink_target='foo'
235
 
        self.assertEqual((False, False), left.detect_changes(right))
236
 
        self.assertEqual((False, False), right.detect_changes(left))
237
 
        left.symlink_target = 'different'
238
 
        self.assertEqual((True, False), left.detect_changes(right))
239
 
        self.assertEqual((True, False), right.detect_changes(left))
240
 
 
241
 
    def test_file_has_text(self):
242
 
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
243
 
        self.failUnless(file.has_text())
244
 
 
245
 
    def test_directory_has_text(self):
246
 
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
247
 
        self.failIf(dir.has_text())
248
 
 
249
 
    def test_link_has_text(self):
250
 
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
251
 
        self.failIf(link.has_text())
252
 
 
253
 
    def test_make_entry(self):
254
 
        self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
255
 
            inventory.InventoryFile)
256
 
        self.assertIsInstance(inventory.make_entry("symlink", "name", ROOT_ID),
257
 
            inventory.InventoryLink)
258
 
        self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
259
 
            inventory.InventoryDirectory)
260
 
 
261
 
    def test_make_entry_non_normalized(self):
262
 
        orig_normalized_filename = osutils.normalized_filename
263
 
 
264
 
        try:
265
 
            osutils.normalized_filename = osutils._accessible_normalized_filename
266
 
            entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
267
 
            self.assertEqual(u'\xe5', entry.name)
268
 
            self.assertIsInstance(entry, inventory.InventoryFile)
269
 
 
270
 
            osutils.normalized_filename = osutils._inaccessible_normalized_filename
271
 
            self.assertRaises(errors.InvalidNormalization,
272
 
                    inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
273
 
        finally:
274
 
            osutils.normalized_filename = orig_normalized_filename
275
 
 
276
 
 
277
 
class TestDescribeChanges(TestCase):
278
 
 
279
 
    def test_describe_change(self):
280
 
        # we need to test the following change combinations:
281
 
        # rename
282
 
        # reparent
283
 
        # modify
284
 
        # gone
285
 
        # added
286
 
        # renamed/reparented and modified
287
 
        # change kind (perhaps can't be done yet?)
288
 
        # also, merged in combination with all of these?
289
 
        old_a = InventoryFile('a-id', 'a_file', ROOT_ID)
290
 
        old_a.text_sha1 = '123132'
291
 
        old_a.text_size = 0
292
 
        new_a = InventoryFile('a-id', 'a_file', ROOT_ID)
293
 
        new_a.text_sha1 = '123132'
294
 
        new_a.text_size = 0
295
 
 
296
 
        self.assertChangeDescription('unchanged', old_a, new_a)
297
 
 
298
 
        new_a.text_size = 10
299
 
        new_a.text_sha1 = 'abcabc'
300
 
        self.assertChangeDescription('modified', old_a, new_a)
301
 
 
302
 
        self.assertChangeDescription('added', None, new_a)
303
 
        self.assertChangeDescription('removed', old_a, None)
304
 
        # perhaps a bit questionable but seems like the most reasonable thing...
305
 
        self.assertChangeDescription('unchanged', None, None)
306
 
 
307
 
        # in this case it's both renamed and modified; show a rename and 
308
 
        # modification:
309
 
        new_a.name = 'newfilename'
310
 
        self.assertChangeDescription('modified and renamed', old_a, new_a)
311
 
 
312
 
        # reparenting is 'renaming'
313
 
        new_a.name = old_a.name
314
 
        new_a.parent_id = 'somedir-id'
315
 
        self.assertChangeDescription('modified and renamed', old_a, new_a)
316
 
 
317
 
        # reset the content values so its not modified
318
 
        new_a.text_size = old_a.text_size
319
 
        new_a.text_sha1 = old_a.text_sha1
320
 
        new_a.name = old_a.name
321
 
 
322
 
        new_a.name = 'newfilename'
323
 
        self.assertChangeDescription('renamed', old_a, new_a)
324
 
 
325
 
        # reparenting is 'renaming'
326
 
        new_a.name = old_a.name
327
 
        new_a.parent_id = 'somedir-id'
328
 
        self.assertChangeDescription('renamed', old_a, new_a)
329
 
 
330
 
    def assertChangeDescription(self, expected_change, old_ie, new_ie):
331
 
        change = InventoryEntry.describe_change(old_ie, new_ie)
332
 
        self.assertEqual(expected_change, change)
333
 
 
334
 
 
335
 
class TestIsRoot(TestCase):
336
 
    """Ensure our root-checking code is accurate."""
337
 
 
338
 
    def test_is_root(self):
339
 
        inv = Inventory('TREE_ROOT')
340
 
        self.assertTrue(inv.is_root('TREE_ROOT'))
341
 
        self.assertFalse(inv.is_root('booga'))
342
 
        inv.root.file_id = 'booga'
343
 
        self.assertFalse(inv.is_root('TREE_ROOT'))
344
 
        self.assertTrue(inv.is_root('booga'))
345
 
        # works properly even if no root is set
346
 
        inv.root = None
347
 
        self.assertFalse(inv.is_root('TREE_ROOT'))
348
 
        self.assertFalse(inv.is_root('booga'))
349
 
 
350
 
 
351
 
class TestTreeReference(TestCase):
352
 
    
353
 
    def test_create(self):
354
 
        inv = Inventory('tree-root-123')
355
 
        inv.add(TreeReference('nested-id', 'nested', parent_id='tree-root-123',
356
 
                              revision='rev', reference_revision='rev2'))
357
 
 
358
 
 
359
 
class TestEncoding(TestCase):
360
 
 
361
 
    def test_error_encoding(self):
362
 
        inv = Inventory('tree-root')
363
 
        inv.add(InventoryFile('a-id', u'\u1234', 'tree-root'))
364
 
        try:
365
 
            inv.add(InventoryFile('b-id', u'\u1234', 'tree-root'))
366
 
        except errors.BzrError, e:
367
 
            self.assertContainsRe(str(e), u'\u1234'.encode('utf-8'))
368
 
        else:
369
 
            self.fail('BzrError not raised')