~lifeless/ubuntu/lucid/bzr/2.1.2-sru

« back to all changes in this revision

Viewing changes to bzrlib/tests/workingtree_implementations/test_smart_add.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2009-07-21 11:25:12 UTC
  • mfrom: (1.4.1 upstream) (8.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090721112512-dzfg8hfhqddf1dwj
* New upstream release.
 + Fixes compatibility with Python 2.4. Closes: #537708

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
"""Test that we can use smart_add on all Tree implementations."""
18
 
 
19
 
from cStringIO import StringIO
20
 
 
21
 
from bzrlib import (
22
 
    add,
23
 
    errors,
24
 
    ignores,
25
 
    osutils,
26
 
    tests,
27
 
    workingtree,
28
 
    )
29
 
from bzrlib.add import (
30
 
    AddAction,
31
 
    AddFromBaseAction,
32
 
    )
33
 
from bzrlib.tests.test_smart_add import AddCustomIDAction
34
 
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
35
 
 
36
 
 
37
 
class TestSmartAddTree(TestCaseWithWorkingTree):
38
 
 
39
 
    def test_single_file(self):
40
 
        tree = self.make_branch_and_tree('tree')
41
 
        self.build_tree(['tree/a'])
42
 
        tree.smart_add(['tree'])
43
 
 
44
 
        tree.lock_read()
45
 
        try:
46
 
            files = [(path, status, kind)
47
 
                     for path, status, kind, file_id, parent_id
48
 
                      in tree.list_files(include_root=True)]
49
 
        finally:
50
 
            tree.unlock()
51
 
        self.assertEqual([('', 'V', 'directory'), ('a', 'V', 'file')],
52
 
                         files)
53
 
 
54
 
    def test_save_false(self):
55
 
        """Dry-run add doesn't permanently affect the tree."""
56
 
        wt = self.make_branch_and_tree('.')
57
 
        wt.lock_write()
58
 
        try:
59
 
            self.build_tree(['file'])
60
 
            wt.smart_add(['file'], save=False)
61
 
            # the file should not be added - no id.
62
 
            self.assertEqual(wt.path2id('file'), None)
63
 
        finally:
64
 
            wt.unlock()
65
 
        # and the disk state should be the same - reopen to check.
66
 
        wt = wt.bzrdir.open_workingtree()
67
 
        self.assertEqual(wt.path2id('file'), None)
68
 
 
69
 
    def test_add_dot_from_root(self):
70
 
        """Test adding . from the root of the tree."""
71
 
        paths = ("original/", "original/file1", "original/file2")
72
 
        self.build_tree(paths)
73
 
        wt = self.make_branch_and_tree('.')
74
 
        wt.smart_add((u".",))
75
 
        for path in paths:
76
 
            self.assertNotEqual(wt.path2id(path), None)
77
 
 
78
 
    def test_add_dot_from_subdir(self):
79
 
        """Test adding . from a subdir of the tree."""
80
 
        paths = ("original/", "original/file1", "original/file2")
81
 
        self.build_tree(paths)
82
 
        wt = self.make_branch_and_tree('.')
83
 
        wt.smart_add((u".",))
84
 
        for path in paths:
85
 
            self.assertNotEqual(wt.path2id(path), None)
86
 
 
87
 
    def test_add_tree_from_above_tree(self):
88
 
        """Test adding a tree from above the tree."""
89
 
        paths = ("original/", "original/file1", "original/file2")
90
 
        branch_paths = ("branch/", "branch/original/", "branch/original/file1",
91
 
                        "branch/original/file2")
92
 
        self.build_tree(branch_paths)
93
 
        wt = self.make_branch_and_tree('branch')
94
 
        wt.smart_add(("branch",))
95
 
        for path in paths:
96
 
            self.assertNotEqual(wt.path2id(path), None)
97
 
 
98
 
    def test_add_above_tree_preserves_tree(self):
99
 
        """Test nested trees are not affect by an add above them."""
100
 
        paths = ("original/", "original/file1", "original/file2")
101
 
        child_paths = ("path",)
102
 
        full_child_paths = ("original/child", "original/child/path")
103
 
        build_paths = ("original/", "original/file1", "original/file2",
104
 
                       "original/child/", "original/child/path")
105
 
 
106
 
        self.build_tree(build_paths)
107
 
        wt = self.make_branch_and_tree('.')
108
 
        child_tree = self.make_branch_and_tree('original/child')
109
 
        wt.smart_add((".",))
110
 
        for path in paths:
111
 
            self.assertNotEqual((path, wt.path2id(path)),
112
 
                                (path, None))
113
 
        for path in full_child_paths:
114
 
            self.assertEqual((path, wt.path2id(path)),
115
 
                             (path, None))
116
 
        for path in child_paths:
117
 
            self.assertEqual(child_tree.path2id(path), None)
118
 
 
119
 
    def test_add_paths(self):
120
 
        """Test smart-adding a list of paths."""
121
 
        paths = ("file1", "file2")
122
 
        self.build_tree(paths)
123
 
        wt = self.make_branch_and_tree('.')
124
 
        wt.smart_add(paths)
125
 
        for path in paths:
126
 
            self.assertNotEqual(wt.path2id(path), None)
127
 
 
128
 
    def test_add_ignored_nested_paths(self):
129
 
        """Test smart-adding a list of paths which includes ignored ones."""
130
 
        wt = self.make_branch_and_tree('.')
131
 
        tree_shape = ("adir/", "adir/CVS/", "adir/CVS/afile", "adir/CVS/afile2")
132
 
        add_paths = ("adir/CVS", "adir/CVS/afile", "adir")
133
 
        expected_paths = ("adir", "adir/CVS", "adir/CVS/afile", "adir/CVS/afile2")
134
 
        self.build_tree(tree_shape)
135
 
        wt.smart_add(add_paths)
136
 
        for path in expected_paths:
137
 
            self.assertNotEqual(wt.path2id(path), None, "No id added for %s" % path)
138
 
 
139
 
    def test_add_non_existant(self):
140
 
        """Test smart-adding a file that does not exist."""
141
 
        wt = self.make_branch_and_tree('.')
142
 
        self.assertRaises(errors.NoSuchFile, wt.smart_add, ['non-existant-file'])
143
 
 
144
 
    def test_returns_and_ignores(self):
145
 
        """Correctly returns added/ignored files"""
146
 
        wt = self.make_branch_and_tree('.')
147
 
        # The default ignore list includes '*.py[co]', but not CVS
148
 
        ignores._set_user_ignores(['*.py[co]'])
149
 
        self.build_tree(['inertiatic/', 'inertiatic/esp', 'inertiatic/CVS',
150
 
                        'inertiatic/foo.pyc'])
151
 
        added, ignored = wt.smart_add(u'.')
152
 
        self.assertSubset(('inertiatic', 'inertiatic/esp', 'inertiatic/CVS'),
153
 
                          added)
154
 
        self.assertSubset(('*.py[co]',), ignored)
155
 
        self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
156
 
 
157
 
    def test_add_multiple_dirs(self):
158
 
        """Test smart adding multiple directories at once."""
159
 
        added_paths = ['file1', 'file2',
160
 
                       'dir1/', 'dir1/file3',
161
 
                       'dir1/subdir2/', 'dir1/subdir2/file4',
162
 
                       'dir2/', 'dir2/file5',
163
 
                      ]
164
 
        not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
165
 
        self.build_tree(added_paths)
166
 
        self.build_tree(not_added)
167
 
 
168
 
        wt = self.make_branch_and_tree('.')
169
 
        wt.smart_add(['file1', 'file2', 'dir1', 'dir2'])
170
 
 
171
 
        for path in added_paths:
172
 
            self.assertNotEqual(None, wt.path2id(path.rstrip('/')),
173
 
                    'Failed to add path: %s' % (path,))
174
 
        for path in not_added:
175
 
            self.assertEqual(None, wt.path2id(path.rstrip('/')),
176
 
                    'Accidentally added path: %s' % (path,))
177
 
 
178
 
    def test_add_file_in_unknown_dir(self):
179
 
        # Test that parent directory addition is implicit
180
 
        tree = self.make_branch_and_tree('.')
181
 
        self.build_tree(['dir/', 'dir/subdir/', 'dir/subdir/foo'])
182
 
        tree.smart_add(['dir/subdir/foo'])
183
 
        tree.lock_read()
184
 
        self.addCleanup(tree.unlock)
185
 
        self.assertEqual(['', 'dir', 'dir/subdir', 'dir/subdir/foo'],
186
 
            [path for path, ie in tree.iter_entries_by_dir()])
187
 
 
188
 
    def test_custom_ids(self):
189
 
        sio = StringIO()
190
 
        action = AddCustomIDAction(to_file=sio, should_print=True)
191
 
        self.build_tree(['file1', 'dir1/', 'dir1/file2'])
192
 
 
193
 
        wt = self.make_branch_and_tree('.')
194
 
        wt.smart_add(['.'], action=action)
195
 
        # The order of adds is not strictly fixed:
196
 
        sio.seek(0)
197
 
        lines = sorted(sio.readlines())
198
 
        self.assertEqualDiff(['added dir1 with id directory-dir1\n',
199
 
                              'added dir1/file2 with id file-dir1%file2\n',
200
 
                              'added file1 with id file-file1\n',
201
 
                             ], lines)
202
 
        wt.lock_read()
203
 
        self.addCleanup(wt.unlock)
204
 
        self.assertEqual([('', wt.path2id('')),
205
 
                          ('dir1', 'directory-dir1'),
206
 
                          ('dir1/file2', 'file-dir1%file2'),
207
 
                          ('file1', 'file-file1'),
208
 
                         ], [(path, ie.file_id) for path, ie
209
 
                                in wt.inventory.iter_entries()])
210
 
 
211
 
    def make_unicode_containing_tree(self):
212
 
        try:
213
 
            self.build_tree([u'a\u030a'])
214
 
        except UnicodeError:
215
 
            raise tests.TestSkipped('Filesystem cannot create unicode filenames')
216
 
        self.wt = self.make_branch_and_tree('.')
217
 
 
218
 
    def test_accessible_explicit(self):
219
 
        self.make_unicode_containing_tree()
220
 
        orig = osutils.normalized_filename
221
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
222
 
        try:
223
 
            self.wt.smart_add([u'a\u030a'])
224
 
            self.wt.lock_read()
225
 
            self.addCleanup(self.wt.unlock)
226
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
227
 
                    [(path, ie.kind) for path,ie in
228
 
                        self.wt.inventory.iter_entries()])
229
 
        finally:
230
 
            osutils.normalized_filename = orig
231
 
 
232
 
    def test_accessible_implicit(self):
233
 
        self.make_unicode_containing_tree()
234
 
        orig = osutils.normalized_filename
235
 
        osutils.normalized_filename = osutils._accessible_normalized_filename
236
 
        try:
237
 
            self.wt.smart_add([])
238
 
            self.wt.lock_read()
239
 
            self.addCleanup(self.wt.unlock)
240
 
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
241
 
                    [(path, ie.kind) for path,ie in
242
 
                        self.wt.inventory.iter_entries()])
243
 
        finally:
244
 
            osutils.normalized_filename = orig
245
 
 
246
 
    def test_inaccessible_explicit(self):
247
 
        self.make_unicode_containing_tree()
248
 
        orig = osutils.normalized_filename
249
 
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
250
 
        try:
251
 
            self.assertRaises(errors.InvalidNormalization,
252
 
                    self.wt.smart_add, [u'a\u030a'])
253
 
        finally:
254
 
            osutils.normalized_filename = orig
255
 
 
256
 
    def test_inaccessible_implicit(self):
257
 
        self.make_unicode_containing_tree()
258
 
        orig = osutils.normalized_filename
259
 
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
260
 
        try:
261
 
            # TODO: jam 20060701 In the future, this should probably
262
 
            #       just ignore files that don't fit the normalization
263
 
            #       rules, rather than exploding
264
 
            self.assertRaises(errors.InvalidNormalization,
265
 
                    self.wt.smart_add, [])
266
 
        finally:
267
 
            osutils.normalized_filename = orig