~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: 2007-03-15 22:35:35 UTC
  • mto: This revision was merged to the branch mainline in revision 2363.
  • Revision ID: john@arbash-meinel.com-20070315223535-d3d4964oe1hc8zhg
Add an overzealous test, for Unicode support of _iter_changes.
For both knowns and unknowns.
And include a basic, if suboptimal, fix.
I would rather defer the decoding until we've determined that we are going to return the tuple.
There is still something broken with added files, but I'll get to that.

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'))