15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
from cStringIO import StringIO
19
from bzrlib import osutils
21
from bzrlib import errors, ignores, osutils
20
22
from bzrlib.add import (
24
from bzrlib.tests import TestCase, TestCaseWithTransport
25
from bzrlib.inventory import Inventory
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
34
class TestSmartAdd(TestCaseWithTransport):
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".",))
44
self.assertNotEqual(wt.path2id(path), None)
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('.')
53
smart_add_tree(wt, (u".",))
55
self.assertNotEqual(wt.path2id(path), None)
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",))
67
self.assertNotEqual(wt.path2id(path), None)
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")
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, (".",))
83
self.assertNotEqual((path, wt.path2id(path)),
85
for path in full_child_paths:
86
self.assertEqual((path, wt.path2id(path)),
88
for path in child_paths:
89
self.assertEqual(child_tree.path2id(path), None)
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)
99
self.assertNotEqual(wt.path2id(path), None)
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)
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)
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'])
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')
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'),
148
self.assertSubset(('*.py[co]',), ignored)
149
self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
28
152
class AddCustomIDAction(AddAction):
30
154
def __call__(self, inv, parent_ie, path, kind):
31
155
# The first part just logs if appropriate
32
156
# Now generate a custom id
33
file_id = osutils.safe_file_id(kind + '-'
34
+ path.raw_path.replace('/', '%'),
157
file_id = kind + '-' + path.raw_path.replace('/', '%')
36
158
if self.should_print:
37
self._to_file.write('added %s with id %s\n'
159
self._to_file.write('added %s with id %s\n'
38
160
% (path.raw_path, file_id))
164
class TestSmartAddTree(TestCaseWithTransport):
165
"""Test smart adds with a specified branch."""
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".",))
174
self.assertNotEqual(wt.path2id(path), None)
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('.')
182
smart_add_tree(wt, (u".",))
184
self.assertNotEqual(wt.path2id(path), None)
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",))
195
self.assertNotEqual(tree.path2id(path), None)
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".",))
209
self.assertNotEqual((path, tree.path2id(path)),
211
for path in full_child_paths:
212
self.assertEqual((path, tree.path2id(path)),
214
for path in child_paths:
215
self.assertEqual(child_tree.path2id(path), None)
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)
224
self.assertNotEqual(wt.path2id(path), None)
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',
233
not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
234
self.build_tree(added_paths)
235
self.build_tree(not_added)
237
wt = self.make_branch_and_tree('.')
238
smart_add_tree(wt, ['file1', 'file2', 'dir1', 'dir2'])
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,))
247
def test_custom_ids(self):
249
action = AddCustomIDAction(to_file=sio, should_print=True)
250
self.build_tree(['file1', 'dir1/', 'dir1/file2'])
252
wt = self.make_branch_and_tree('.')
253
smart_add_tree(wt, ['.'], action=action)
254
# The order of adds is not strictly fixed:
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',
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()])
42
269
class TestAddFrom(TestCaseWithTransport):
43
270
"""Tests for AddFromBaseAction"""
139
364
# matching path or child of 'subby'.
140
365
a_id = new_tree.path2id('subby/a')
141
366
self.assertNotEqual(None, a_id)
142
self.base_tree.lock_read()
143
self.addCleanup(self.base_tree.unlock)
144
367
self.failIf(a_id in self.base_tree)
370
class TestAddNonNormalized(TestCaseWithTransport):
374
self.build_tree([u'a\u030a'])
376
raise TestSkipped('Filesystem cannot create unicode filenames')
378
self.wt = self.make_branch_and_tree('.')
380
def test_accessible_explicit(self):
382
orig = osutils.normalized_filename
383
osutils.normalized_filename = osutils._accessible_normalized_filename
385
smart_add_tree(self.wt, [u'a\u030a'])
386
self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
387
[(path, ie.kind) for path,ie in
388
self.wt.inventory.iter_entries()])
390
osutils.normalized_filename = orig
392
def test_accessible_implicit(self):
394
orig = osutils.normalized_filename
395
osutils.normalized_filename = osutils._accessible_normalized_filename
397
smart_add_tree(self.wt, [])
398
self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
399
[(path, ie.kind) for path,ie in
400
self.wt.inventory.iter_entries()])
402
osutils.normalized_filename = orig
404
def test_inaccessible_explicit(self):
406
orig = osutils.normalized_filename
407
osutils.normalized_filename = osutils._inaccessible_normalized_filename
409
self.assertRaises(errors.InvalidNormalization,
410
smart_add_tree, self.wt, [u'a\u030a'])
412
osutils.normalized_filename = orig
414
def test_inaccessible_implicit(self):
416
orig = osutils.normalized_filename
417
osutils.normalized_filename = osutils._inaccessible_normalized_filename
419
# TODO: jam 20060701 In the future, this should probably
420
# just ignore files that don't fit the normalization
421
# rules, rather than exploding
422
self.assertRaises(errors.InvalidNormalization,
423
smart_add_tree, self.wt, [])
425
osutils.normalized_filename = orig
147
428
class TestAddActions(TestCase):
149
430
def test_quiet(self):