~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_add.py

  • Committer: Martin Pool
  • Date: 2010-01-29 10:36:23 UTC
  • mto: This revision was merged to the branch mainline in revision 4992.
  • Revision ID: mbp@sourcefrog.net-20100129103623-hywka5hymo5z13jw
Change url to canonical.com or wiki, plus some doc improvements in passing

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
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
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
 
        paths = ("original/", "original/file1", "original/file2")
39
 
        self.build_tree(paths)
40
 
        wt = self.make_branch_and_tree('.')
41
 
        smart_add_tree(wt, (u".",))
42
 
        for path in paths:
43
 
            self.assertNotEqual(wt.path2id(path), None)
44
 
 
45
 
    def test_add_dot_from_subdir(self):
46
 
        """Test adding . from a subdir of the tree.""" 
47
 
        from bzrlib.add import smart_add
48
 
        paths = ("original/", "original/file1", "original/file2")
49
 
        self.build_tree(paths)
50
 
        wt = self.make_branch_and_tree('.')
51
 
        os.chdir("original")
52
 
        smart_add_tree(wt, (u".",))
53
 
        for path in paths:
54
 
            self.assertNotEqual(wt.path2id(path), None)
55
 
 
56
 
    def test_add_tree_from_above_tree(self):
57
 
        """Test adding a tree from above the tree.""" 
58
 
        from bzrlib.add import smart_add
59
 
        paths = ("original/", "original/file1", "original/file2")
60
 
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
61
 
                        "branch/original/file2")
62
 
        self.build_tree(branch_paths)
63
 
        wt = self.make_branch_and_tree('branch')
64
 
        smart_add_tree(wt, ("branch",))
65
 
        for path in paths:
66
 
            self.assertNotEqual(wt.path2id(path), None)
67
 
 
68
 
    def test_add_above_tree_preserves_tree(self):
69
 
        """Test nested trees are not affect by an add above them."""
70
 
        from bzrlib.add import smart_add
71
 
        paths = ("original/", "original/file1", "original/file2")
72
 
        child_paths = ("path",)
73
 
        full_child_paths = ("original/child", "original/child/path")
74
 
        build_paths = ("original/", "original/file1", "original/file2", 
75
 
                       "original/child/", "original/child/path")
76
 
        
77
 
        self.build_tree(build_paths)
78
 
        wt = self.make_branch_and_tree('.')
79
 
        child_tree = self.make_branch_and_tree('original/child')
80
 
        smart_add_tree(wt, (".",))
81
 
        for path in paths:
82
 
            self.assertNotEqual((path, wt.path2id(path)),
83
 
                                (path, None))
84
 
        for path in full_child_paths:
85
 
            self.assertEqual((path, wt.path2id(path)),
86
 
                             (path, None))
87
 
        for path in child_paths:
88
 
            self.assertEqual(child_tree.path2id(path), None)
89
 
 
90
 
    def test_add_paths(self):
91
 
        """Test smart-adding a list of paths."""
92
 
        from bzrlib.add import smart_add
93
 
        paths = ("file1", "file2")
94
 
        self.build_tree(paths)
95
 
        wt = self.make_branch_and_tree('.')
96
 
        smart_add_tree(wt, paths)
97
 
        for path in paths:
98
 
            self.assertNotEqual(wt.path2id(path), None)
99
 
    
100
 
    def test_add_ignored_nested_paths(self):
101
 
        """Test smart-adding a list of paths which includes ignored ones."""
102
 
        wt = self.make_branch_and_tree('.')
103
 
        tree_shape = ("adir/", "adir/CVS/", "adir/CVS/afile", "adir/CVS/afile2")
104
 
        add_paths = ("adir/CVS", "adir/CVS/afile", "adir")
105
 
        expected_paths = ("adir", "adir/CVS", "adir/CVS/afile", "adir/CVS/afile2")
106
 
        self.build_tree(tree_shape)
107
 
        smart_add_tree(wt, add_paths)
108
 
        for path in expected_paths:
109
 
            self.assertNotEqual(wt.path2id(path), None, "No id added for %s" % path)
110
 
 
111
 
    def test_add_dry_run(self):
112
 
        """Test a dry run add, make sure nothing is added."""
113
 
        from bzrlib.commands import run_bzr
114
 
        eq = self.assertEqual
115
 
        wt = self.make_branch_and_tree('.')
116
 
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
117
 
        eq(list(wt.unknowns()), ['inertiatic'])
118
 
        self.capture('add --dry-run .')
119
 
        eq(list(wt.unknowns()), ['inertiatic'])
120
 
 
121
 
    def test_add_non_existant(self):
122
 
        """Test smart-adding a file that does not exist."""
123
 
        from bzrlib.add import smart_add
124
 
        wt = self.make_branch_and_tree('.')
125
 
        self.assertRaises(NoSuchFile, smart_add_tree, wt, 'non-existant-file')
126
 
 
127
 
    def test_returns_and_ignores(self):
128
 
        """Correctly returns added/ignored files"""
129
 
        from bzrlib.commands import run_bzr
130
 
        wt = self.make_branch_and_tree('.')
131
 
        # The default ignore list includes '*.py[co]', but not CVS
132
 
        ignores._set_user_ignores(['*.py[co]'])
133
 
        self.build_tree(['inertiatic/', 'inertiatic/esp', 'inertiatic/CVS',
134
 
                        'inertiatic/foo.pyc'])
135
 
        added, ignored = smart_add_tree(wt, u'.')
136
 
        self.assertSubset(('inertiatic', 'inertiatic/esp', 'inertiatic/CVS'),
137
 
                          added)
138
 
        self.assertSubset(('*.py[co]',), ignored)
139
 
        self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
 
24
from bzrlib.tests import TestCase, TestCaseWithTransport
 
25
from bzrlib.inventory import Inventory
140
26
 
141
27
 
142
28
class AddCustomIDAction(AddAction):
153
39
        return file_id
154
40
 
155
41
 
156
 
class TestSmartAddTree(TestCaseWithTransport):
157
 
    """Test smart adds with a specified branch."""
158
 
 
159
 
    def test_add_dot_from_root(self):
160
 
        """Test adding . from the root of the tree.""" 
161
 
        paths = ("original/", "original/file1", "original/file2")
162
 
        self.build_tree(paths)
163
 
        wt = self.make_branch_and_tree('.')
164
 
        smart_add_tree(wt, (u".",))
165
 
        for path in paths:
166
 
            self.assertNotEqual(wt.path2id(path), None)
167
 
 
168
 
    def test_add_dot_from_subdir(self):
169
 
        """Test adding . from a subdir of the tree.""" 
170
 
        paths = ("original/", "original/file1", "original/file2")
171
 
        self.build_tree(paths)
172
 
        wt = self.make_branch_and_tree('.')
173
 
        os.chdir("original")
174
 
        smart_add_tree(wt, (u".",))
175
 
        for path in paths:
176
 
            self.assertNotEqual(wt.path2id(path), None)
177
 
 
178
 
    def test_add_tree_from_above_tree(self):
179
 
        """Test adding a tree from above the tree.""" 
180
 
        paths = ("original/", "original/file1", "original/file2")
181
 
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
182
 
                        "branch/original/file2")
183
 
        self.build_tree(branch_paths)
184
 
        tree = self.make_branch_and_tree('branch')
185
 
        smart_add_tree(tree, ("branch",))
186
 
        for path in paths:
187
 
            self.assertNotEqual(tree.path2id(path), None)
188
 
 
189
 
    def test_add_above_tree_preserves_tree(self):
190
 
        """Test nested trees are not affect by an add above them."""
191
 
        paths = ("original/", "original/file1", "original/file2")
192
 
        child_paths = ("path")
193
 
        full_child_paths = ("original/child", "original/child/path")
194
 
        build_paths = ("original/", "original/file1", "original/file2", 
195
 
                       "original/child/", "original/child/path")
196
 
        self.build_tree(build_paths)
197
 
        tree = self.make_branch_and_tree('.')
198
 
        child_tree = self.make_branch_and_tree("original/child")
199
 
        smart_add_tree(tree, (u".",))
200
 
        for path in paths:
201
 
            self.assertNotEqual((path, tree.path2id(path)),
202
 
                                (path, None))
203
 
        for path in full_child_paths:
204
 
            self.assertEqual((path, tree.path2id(path)),
205
 
                             (path, None))
206
 
        for path in child_paths:
207
 
            self.assertEqual(child_tree.path2id(path), None)
208
 
 
209
 
    def test_add_paths(self):
210
 
        """Test smart-adding a list of paths."""
211
 
        paths = ("file1", "file2")
212
 
        self.build_tree(paths)
213
 
        wt = self.make_branch_and_tree('.')
214
 
        smart_add_tree(wt, paths)
215
 
        for path in paths:
216
 
            self.assertNotEqual(wt.path2id(path), None)
217
 
 
218
 
    def test_add_multiple_dirs(self):
219
 
        """Test smart adding multiple directories at once."""
220
 
        added_paths = ['file1', 'file2',
221
 
                       'dir1/', 'dir1/file3',
222
 
                       'dir1/subdir2/', 'dir1/subdir2/file4',
223
 
                       'dir2/', 'dir2/file5',
224
 
                      ]
225
 
        not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
226
 
        self.build_tree(added_paths)
227
 
        self.build_tree(not_added)
228
 
 
229
 
        wt = self.make_branch_and_tree('.')
230
 
        smart_add_tree(wt, ['file1', 'file2', 'dir1', 'dir2'])
231
 
 
232
 
        for path in added_paths:
233
 
            self.assertNotEqual(None, wt.path2id(path.rstrip('/')),
234
 
                    'Failed to add path: %s' % (path,))
235
 
        for path in not_added:
236
 
            self.assertEqual(None, wt.path2id(path.rstrip('/')),
237
 
                    'Accidentally added path: %s' % (path,))
238
 
 
239
 
    def test_custom_ids(self):
240
 
        sio = StringIO()
241
 
        action = AddCustomIDAction(to_file=sio, should_print=True)
242
 
        self.build_tree(['file1', 'dir1/', 'dir1/file2'])
243
 
 
244
 
        wt = self.make_branch_and_tree('.')
245
 
        smart_add_tree(wt, ['.'], action=action)
246
 
        # The order of adds is not strictly fixed:
247
 
        sio.seek(0)
248
 
        lines = sorted(sio.readlines())
249
 
        self.assertEqualDiff(['added dir1 with id directory-dir1\n',
250
 
                              'added dir1/file2 with id file-dir1%file2\n',
251
 
                              'added file1 with id file-file1\n',
252
 
                             ], lines)
253
 
        wt.lock_read()
254
 
        self.addCleanup(wt.unlock)
255
 
        self.assertEqual([('', wt.path2id('')),
256
 
                          ('dir1', 'directory-dir1'),
257
 
                          ('dir1/file2', 'file-dir1%file2'),
258
 
                          ('file1', 'file-file1'),
259
 
                         ], [(path, ie.file_id) for path, ie
260
 
                                in wt.inventory.iter_entries()])
261
 
 
262
 
 
263
42
class TestAddFrom(TestCaseWithTransport):
264
43
    """Tests for AddFromBaseAction"""
265
44
 
284
63
                action = AddFromBaseAction(base_tree, base_path,
285
64
                                           to_file=to_file,
286
65
                                           should_print=should_print)
287
 
                smart_add_tree(new_tree, file_list, action=action)
 
66
                new_tree.smart_add(file_list, action=action)
288
67
            finally:
289
68
                new_tree.unlock()
290
69
        finally:
365
144
        self.failIf(a_id in self.base_tree)
366
145
 
367
146
 
368
 
class TestAddNonNormalized(TestCaseWithTransport):
369
 
 
370
 
    def make(self):
371
 
        try:
372
 
            self.build_tree([u'a\u030a'])
373
 
        except UnicodeError:
374
 
            raise TestSkipped('Filesystem cannot create unicode filenames')
375
 
 
376
 
        self.wt = self.make_branch_and_tree('.')
377
 
 
378
 
    def test_accessible_explicit(self):
379
 
        self.make()
380
 
        orig = osutils.normalized_filename
381
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
382
 
        try:
383
 
            smart_add_tree(self.wt, [u'a\u030a'])
384
 
            self.wt.lock_read()
385
 
            self.addCleanup(self.wt.unlock)
386
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
387
 
                    [(path, ie.kind) for path,ie in 
388
 
                        self.wt.inventory.iter_entries()])
389
 
        finally:
390
 
            osutils.normalized_filename = orig
391
 
 
392
 
    def test_accessible_implicit(self):
393
 
        self.make()
394
 
        orig = osutils.normalized_filename
395
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
396
 
        try:
397
 
            smart_add_tree(self.wt, [])
398
 
            self.wt.lock_read()
399
 
            self.addCleanup(self.wt.unlock)
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):
433
150
        self.run_action("")
434
151
 
435
152
    def test__print(self):
436
 
        self.run_action("added path\n")
 
153
        self.run_action("adding 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)