~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: Robert Collins
  • Date: 2007-07-13 16:35:54 UTC
  • mto: (2592.3.3 repository)
  • mto: This revision was merged to the branch mainline in revision 2624.
  • Revision ID: robertc@robertcollins.net-20070713163554-ok2qtnzv6rcbpt3z
Change the missing key interface in index operations to not raise, allowing callers to set policy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
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 TestBase
18
 
 
19
 
from bzrlib.inventory import Inventory, InventoryEntry
20
 
 
21
 
class TestIsWithin(TestBase):
22
 
    def runTest(self):
 
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):
23
63
        """Test detection of files within selected directories."""
24
64
        inv = Inventory()
25
65
        
34
74
        self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
35
75
        
36
76
        self.assert_('src-id' in inv)
37
 
        
38
 
        
 
 
b'\\ No newline at end of file'
 
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')