/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_add.py

First attempt to merge .dev and resolve the conflicts (but tests are 
failing)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 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
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
from cStringIO import StringIO
18
 
import os
19
 
import unittest
20
18
 
21
 
from bzrlib import errors, ignores, osutils
 
19
from bzrlib import osutils
22
20
from bzrlib.add import (
23
21
    AddAction,
24
22
    AddFromBaseAction,
25
 
    smart_add,
26
 
    smart_add_tree,
27
23
    )
28
 
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
29
 
from bzrlib.errors import NoSuchFile
30
 
from bzrlib.inventory import InventoryFile, Inventory
31
 
from bzrlib.workingtree import WorkingTree
32
 
 
33
 
 
34
 
class TestSmartAdd(TestCaseWithTransport):
35
 
 
36
 
    def test_add_dot_from_root(self):
37
 
        """Test adding . from the root of the tree.""" 
38
 
        from bzrlib.add import smart_add
39
 
        paths = ("original/", "original/file1", "original/file2")
40
 
        self.build_tree(paths)
41
 
        wt = self.make_branch_and_tree('.')
42
 
        smart_add_tree(wt, (u".",))
43
 
        for path in paths:
44
 
            self.assertNotEqual(wt.path2id(path), None)
45
 
 
46
 
    def test_add_dot_from_subdir(self):
47
 
        """Test adding . from a subdir of the tree.""" 
48
 
        from bzrlib.add import smart_add
49
 
        paths = ("original/", "original/file1", "original/file2")
50
 
        self.build_tree(paths)
51
 
        wt = self.make_branch_and_tree('.')
52
 
        os.chdir("original")
53
 
        smart_add_tree(wt, (u".",))
54
 
        for path in paths:
55
 
            self.assertNotEqual(wt.path2id(path), None)
56
 
 
57
 
    def test_add_tree_from_above_tree(self):
58
 
        """Test adding a tree from above the tree.""" 
59
 
        from bzrlib.add import smart_add
60
 
        paths = ("original/", "original/file1", "original/file2")
61
 
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
62
 
                        "branch/original/file2")
63
 
        self.build_tree(branch_paths)
64
 
        wt = self.make_branch_and_tree('branch')
65
 
        smart_add_tree(wt, ("branch",))
66
 
        for path in paths:
67
 
            self.assertNotEqual(wt.path2id(path), None)
68
 
 
69
 
    def test_add_above_tree_preserves_tree(self):
70
 
        """Test nested trees are not affect by an add above them."""
71
 
        from bzrlib.add import smart_add
72
 
        paths = ("original/", "original/file1", "original/file2")
73
 
        child_paths = ("path",)
74
 
        full_child_paths = ("original/child", "original/child/path")
75
 
        build_paths = ("original/", "original/file1", "original/file2", 
76
 
                       "original/child/", "original/child/path")
77
 
        
78
 
        self.build_tree(build_paths)
79
 
        wt = self.make_branch_and_tree('.')
80
 
        child_tree = self.make_branch_and_tree('original/child')
81
 
        smart_add_tree(wt, (".",))
82
 
        for path in paths:
83
 
            self.assertNotEqual((path, wt.path2id(path)),
84
 
                                (path, None))
85
 
        for path in full_child_paths:
86
 
            self.assertEqual((path, wt.path2id(path)),
87
 
                             (path, None))
88
 
        for path in child_paths:
89
 
            self.assertEqual(child_tree.path2id(path), None)
90
 
 
91
 
    def test_add_paths(self):
92
 
        """Test smart-adding a list of paths."""
93
 
        from bzrlib.add import smart_add
94
 
        paths = ("file1", "file2")
95
 
        self.build_tree(paths)
96
 
        wt = self.make_branch_and_tree('.')
97
 
        smart_add_tree(wt, paths)
98
 
        for path in paths:
99
 
            self.assertNotEqual(wt.path2id(path), None)
100
 
    
101
 
    def test_add_ignored_nested_paths(self):
102
 
        """Test smart-adding a list of paths which includes ignored ones."""
103
 
        wt = self.make_branch_and_tree('.')
104
 
        tree_shape = ("adir/", "adir/CVS/", "adir/CVS/afile", "adir/CVS/afile2")
105
 
        add_paths = ("adir/CVS", "adir/CVS/afile", "adir")
106
 
        expected_paths = ("adir", "adir/CVS", "adir/CVS/afile", "adir/CVS/afile2")
107
 
        self.build_tree(tree_shape)
108
 
        smart_add_tree(wt, add_paths)
109
 
        for path in expected_paths:
110
 
            self.assertNotEqual(wt.path2id(path), None, "No id added for %s" % path)
111
 
 
112
 
    def test_save_false(self):
113
 
        """Test smart-adding a path with save set to false."""
114
 
        wt = self.make_branch_and_tree('.')
115
 
        self.build_tree(['file'])
116
 
        smart_add_tree(wt, ['file'], save=False)
117
 
        self.assertNotEqual(wt.path2id('file'), None, "No id added for 'file'")
118
 
        wt.read_working_inventory()
119
 
        self.assertEqual(wt.path2id('file'), None)
120
 
 
121
 
    def test_add_dry_run(self):
122
 
        """Test a dry run add, make sure nothing is added."""
123
 
        from bzrlib.commands import run_bzr
124
 
        eq = self.assertEqual
125
 
        wt = self.make_branch_and_tree('.')
126
 
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
127
 
        eq(list(wt.unknowns()), ['inertiatic'])
128
 
        self.capture('add --dry-run .')
129
 
        eq(list(wt.unknowns()), ['inertiatic'])
130
 
 
131
 
    def test_add_non_existant(self):
132
 
        """Test smart-adding a file that does not exist."""
133
 
        from bzrlib.add import smart_add
134
 
        wt = self.make_branch_and_tree('.')
135
 
        self.assertRaises(NoSuchFile, smart_add_tree, wt, 'non-existant-file')
136
 
 
137
 
    def test_returns_and_ignores(self):
138
 
        """Correctly returns added/ignored files"""
139
 
        from bzrlib.commands import run_bzr
140
 
        wt = self.make_branch_and_tree('.')
141
 
        # The default ignore list includes '*.py[co]', but not CVS
142
 
        ignores._set_user_ignores(['*.py[co]'])
143
 
        self.build_tree(['inertiatic/', 'inertiatic/esp', 'inertiatic/CVS',
144
 
                        'inertiatic/foo.pyc'])
145
 
        added, ignored = smart_add_tree(wt, u'.')
146
 
        self.assertSubset(('inertiatic', 'inertiatic/esp', 'inertiatic/CVS'),
147
 
                          added)
148
 
        self.assertSubset(('*.py[co]',), ignored)
149
 
        self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
 
24
from bzrlib.tests import TestCase, TestCaseWithTransport
 
25
from bzrlib.inventory import Inventory
150
26
 
151
27
 
152
28
class AddCustomIDAction(AddAction):
154
30
    def __call__(self, inv, parent_ie, path, kind):
155
31
        # The first part just logs if appropriate
156
32
        # Now generate a custom id
157
 
        file_id = kind + '-' + path.raw_path.replace('/', '%')
 
33
        file_id = osutils.safe_file_id(kind + '-'
 
34
                                       + path.raw_path.replace('/', '%'),
 
35
                                       warn=False)
158
36
        if self.should_print:
159
 
            self._to_file.write('added %s with id %s\n' 
 
37
            self._to_file.write('added %s with id %s\n'
160
38
                                % (path.raw_path, file_id))
161
39
        return file_id
162
40
 
163
41
 
164
 
class TestSmartAddTree(TestCaseWithTransport):
165
 
    """Test smart adds with a specified branch."""
166
 
 
167
 
    def test_add_dot_from_root(self):
168
 
        """Test adding . from the root of the tree.""" 
169
 
        paths = ("original/", "original/file1", "original/file2")
170
 
        self.build_tree(paths)
171
 
        wt = self.make_branch_and_tree('.')
172
 
        smart_add_tree(wt, (u".",))
173
 
        for path in paths:
174
 
            self.assertNotEqual(wt.path2id(path), None)
175
 
 
176
 
    def test_add_dot_from_subdir(self):
177
 
        """Test adding . from a subdir of the tree.""" 
178
 
        paths = ("original/", "original/file1", "original/file2")
179
 
        self.build_tree(paths)
180
 
        wt = self.make_branch_and_tree('.')
181
 
        os.chdir("original")
182
 
        smart_add_tree(wt, (u".",))
183
 
        for path in paths:
184
 
            self.assertNotEqual(wt.path2id(path), None)
185
 
 
186
 
    def test_add_tree_from_above_tree(self):
187
 
        """Test adding a tree from above the tree.""" 
188
 
        paths = ("original/", "original/file1", "original/file2")
189
 
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
190
 
                        "branch/original/file2")
191
 
        self.build_tree(branch_paths)
192
 
        tree = self.make_branch_and_tree('branch')
193
 
        smart_add_tree(tree, ("branch",))
194
 
        for path in paths:
195
 
            self.assertNotEqual(tree.path2id(path), None)
196
 
 
197
 
    def test_add_above_tree_preserves_tree(self):
198
 
        """Test nested trees are not affect by an add above them."""
199
 
        paths = ("original/", "original/file1", "original/file2")
200
 
        child_paths = ("path")
201
 
        full_child_paths = ("original/child", "original/child/path")
202
 
        build_paths = ("original/", "original/file1", "original/file2", 
203
 
                       "original/child/", "original/child/path")
204
 
        self.build_tree(build_paths)
205
 
        tree = self.make_branch_and_tree('.')
206
 
        child_tree = self.make_branch_and_tree("original/child")
207
 
        smart_add_tree(tree, (u".",))
208
 
        for path in paths:
209
 
            self.assertNotEqual((path, tree.path2id(path)),
210
 
                                (path, None))
211
 
        for path in full_child_paths:
212
 
            self.assertEqual((path, tree.path2id(path)),
213
 
                             (path, None))
214
 
        for path in child_paths:
215
 
            self.assertEqual(child_tree.path2id(path), None)
216
 
 
217
 
    def test_add_paths(self):
218
 
        """Test smart-adding a list of paths."""
219
 
        paths = ("file1", "file2")
220
 
        self.build_tree(paths)
221
 
        wt = self.make_branch_and_tree('.')
222
 
        smart_add_tree(wt, paths)
223
 
        for path in paths:
224
 
            self.assertNotEqual(wt.path2id(path), None)
225
 
 
226
 
    def test_add_multiple_dirs(self):
227
 
        """Test smart adding multiple directories at once."""
228
 
        added_paths = ['file1', 'file2',
229
 
                       'dir1/', 'dir1/file3',
230
 
                       'dir1/subdir2/', 'dir1/subdir2/file4',
231
 
                       'dir2/', 'dir2/file5',
232
 
                      ]
233
 
        not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
234
 
        self.build_tree(added_paths)
235
 
        self.build_tree(not_added)
236
 
 
237
 
        wt = self.make_branch_and_tree('.')
238
 
        smart_add_tree(wt, ['file1', 'file2', 'dir1', 'dir2'])
239
 
 
240
 
        for path in added_paths:
241
 
            self.assertNotEqual(None, wt.path2id(path.rstrip('/')),
242
 
                    'Failed to add path: %s' % (path,))
243
 
        for path in not_added:
244
 
            self.assertEqual(None, wt.path2id(path.rstrip('/')),
245
 
                    'Accidentally added path: %s' % (path,))
246
 
 
247
 
    def test_custom_ids(self):
248
 
        sio = StringIO()
249
 
        action = AddCustomIDAction(to_file=sio, should_print=True)
250
 
        self.build_tree(['file1', 'dir1/', 'dir1/file2'])
251
 
 
252
 
        wt = self.make_branch_and_tree('.')
253
 
        smart_add_tree(wt, ['.'], action=action)
254
 
        # The order of adds is not strictly fixed:
255
 
        sio.seek(0)
256
 
        lines = sorted(sio.readlines())
257
 
        self.assertEqualDiff(['added dir1 with id directory-dir1\n',
258
 
                              'added dir1/file2 with id file-dir1%file2\n',
259
 
                              'added file1 with id file-file1\n',
260
 
                             ], lines)
261
 
        self.assertEqual([('', wt.inventory.root.file_id),
262
 
                          ('dir1', 'directory-dir1'),
263
 
                          ('dir1/file2', 'file-dir1%file2'),
264
 
                          ('file1', 'file-file1'),
265
 
                         ], [(path, ie.file_id) for path, ie
266
 
                                in wt.inventory.iter_entries()])
267
 
 
268
 
 
269
42
class TestAddFrom(TestCaseWithTransport):
270
43
    """Tests for AddFromBaseAction"""
271
44
 
290
63
                action = AddFromBaseAction(base_tree, base_path,
291
64
                                           to_file=to_file,
292
65
                                           should_print=should_print)
293
 
                smart_add_tree(new_tree, file_list, action=action)
 
66
                new_tree.smart_add(file_list, action=action)
294
67
            finally:
295
68
                new_tree.unlock()
296
69
        finally:
319
92
 
320
93
        self.build_tree(['new/a', 'new/b', 'new/c',
321
94
                         'new/subdir/', 'new/subdir/b', 'new/subdir/d'])
 
95
        new_tree.set_root_id(self.base_tree.get_root_id())
322
96
        self.add_helper(self.base_tree, 'dir', new_tree, ['new'])
323
97
 
324
 
        # We 'a' and 'b' exist in the root, and they are being added
325
 
        # in a new 'root'. Since ROOT ids are not unique, we will
 
98
        # We know 'a' and 'b' exist in the root, and they are being added
 
99
        # in a new 'root'. Since ROOT ids have been set as the same, we will
326
100
        # use those ids
327
 
        # TODO: This will probably change once trees have a unique root id
328
 
        # It is definitely arguable that 'a' should get the id of
329
 
        # 'dir/a' not of 'a'.
330
101
        self.assertEqual(self.base_tree.path2id('a'),
331
102
                         new_tree.path2id('a'))
332
103
        self.assertEqual(self.base_tree.path2id('b'),
343
114
        # These should get newly generated ids
344
115
        c_id = new_tree.path2id('c')
345
116
        self.assertNotEqual(None, c_id)
 
117
        self.base_tree.lock_read()
 
118
        self.addCleanup(self.base_tree.unlock)
346
119
        self.failIf(c_id in self.base_tree)
347
120
 
348
121
        d_id = new_tree.path2id('subdir/d')
366
139
        # matching path or child of 'subby'.
367
140
        a_id = new_tree.path2id('subby/a')
368
141
        self.assertNotEqual(None, a_id)
 
142
        self.base_tree.lock_read()
 
143
        self.addCleanup(self.base_tree.unlock)
369
144
        self.failIf(a_id in self.base_tree)
370
145
 
371
146
 
372
 
class TestAddNonNormalized(TestCaseWithTransport):
373
 
 
374
 
    def make(self):
375
 
        try:
376
 
            self.build_tree([u'a\u030a'])
377
 
        except UnicodeError:
378
 
            raise TestSkipped('Filesystem cannot create unicode filenames')
379
 
 
380
 
        self.wt = self.make_branch_and_tree('.')
381
 
 
382
 
    def test_accessible_explicit(self):
383
 
        self.make()
384
 
        orig = osutils.normalized_filename
385
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
386
 
        try:
387
 
            smart_add_tree(self.wt, [u'a\u030a'])
388
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
389
 
                    [(path, ie.kind) for path,ie in 
390
 
                        self.wt.inventory.iter_entries()])
391
 
        finally:
392
 
            osutils.normalized_filename = orig
393
 
 
394
 
    def test_accessible_implicit(self):
395
 
        self.make()
396
 
        orig = osutils.normalized_filename
397
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
398
 
        try:
399
 
            smart_add_tree(self.wt, [])
400
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
401
 
                    [(path, ie.kind) for path,ie in 
402
 
                        self.wt.inventory.iter_entries()])
403
 
        finally:
404
 
            osutils.normalized_filename = orig
405
 
 
406
 
    def test_inaccessible_explicit(self):
407
 
        self.make()
408
 
        orig = osutils.normalized_filename
409
 
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
410
 
        try:
411
 
            self.assertRaises(errors.InvalidNormalization,
412
 
                    smart_add_tree, self.wt, [u'a\u030a'])
413
 
        finally:
414
 
            osutils.normalized_filename = orig
415
 
 
416
 
    def test_inaccessible_implicit(self):
417
 
        self.make()
418
 
        orig = osutils.normalized_filename
419
 
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
420
 
        try:
421
 
            # TODO: jam 20060701 In the future, this should probably
422
 
            #       just ignore files that don't fit the normalization
423
 
            #       rules, rather than exploding
424
 
            self.assertRaises(errors.InvalidNormalization,
425
 
                    smart_add_tree, self.wt, [])
426
 
        finally:
427
 
            osutils.normalized_filename = orig
428
 
 
429
 
 
430
147
class TestAddActions(TestCase):
431
148
 
432
149
    def test_quiet(self):
436
153
        self.run_action("added path\n")
437
154
 
438
155
    def run_action(self, output):
439
 
        from bzrlib.add import AddAction, FastPath
 
156
        from bzrlib.add import AddAction
 
157
        from bzrlib.mutabletree import _FastPath
440
158
        inv = Inventory()
441
159
        stdout = StringIO()
442
160
        action = AddAction(to_file=stdout, should_print=bool(output))
443
161
 
444
 
        self.apply_redirected(None, stdout, None, action, inv, None, FastPath('path'), 'file')
 
162
        self.apply_redirected(None, stdout, None, action, inv, None,
 
163
            _FastPath('path'), 'file')
445
164
        self.assertEqual(stdout.getvalue(), output)