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
paths = ("original/", "original/file1", "original/file2")
39
self.build_tree(paths)
40
wt = self.make_branch_and_tree('.')
41
smart_add_tree(wt, (u".",))
43
self.assertNotEqual(wt.path2id(path), None)
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('.')
52
smart_add_tree(wt, (u".",))
54
self.assertNotEqual(wt.path2id(path), None)
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",))
66
self.assertNotEqual(wt.path2id(path), None)
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")
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, (".",))
82
self.assertNotEqual((path, wt.path2id(path)),
84
for path in full_child_paths:
85
self.assertEqual((path, wt.path2id(path)),
87
for path in child_paths:
88
self.assertEqual(child_tree.path2id(path), None)
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)
98
self.assertNotEqual(wt.path2id(path), None)
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)
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.run_bzr('add --dry-run .')
119
eq(list(wt.unknowns()), ['inertiatic'])
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')
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'),
138
self.assertSubset(('*.py[co]',), ignored)
139
self.assertSubset(('inertiatic/foo.pyc',), ignored['*.py[co]'])
28
142
class AddCustomIDAction(AddAction):
156
class TestSmartAddTree(TestCaseWithTransport):
157
"""Test smart adds with a specified branch."""
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".",))
166
self.assertNotEqual(wt.path2id(path), None)
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('.')
174
smart_add_tree(wt, (u".",))
176
self.assertNotEqual(wt.path2id(path), None)
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",))
187
self.assertNotEqual(tree.path2id(path), None)
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".",))
201
self.assertNotEqual((path, tree.path2id(path)),
203
for path in full_child_paths:
204
self.assertEqual((path, tree.path2id(path)),
206
for path in child_paths:
207
self.assertEqual(child_tree.path2id(path), None)
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)
216
self.assertNotEqual(wt.path2id(path), None)
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',
225
not_added = ['file6', 'dir3/', 'dir3/file7', 'dir3/file8']
226
self.build_tree(added_paths)
227
self.build_tree(not_added)
229
wt = self.make_branch_and_tree('.')
230
smart_add_tree(wt, ['file1', 'file2', 'dir1', 'dir2'])
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,))
239
def test_custom_ids(self):
241
action = AddCustomIDAction(to_file=sio, should_print=True)
242
self.build_tree(['file1', 'dir1/', 'dir1/file2'])
244
wt = self.make_branch_and_tree('.')
245
smart_add_tree(wt, ['.'], action=action)
246
# The order of adds is not strictly fixed:
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',
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()])
42
263
class TestAddFrom(TestCaseWithTransport):
43
264
"""Tests for AddFromBaseAction"""
144
365
self.failIf(a_id in self.base_tree)
368
class TestAddNonNormalized(TestCaseWithTransport):
372
self.build_tree([u'a\u030a'])
374
raise TestSkipped('Filesystem cannot create unicode filenames')
376
self.wt = self.make_branch_and_tree('.')
378
def test_accessible_explicit(self):
380
orig = osutils.normalized_filename
381
osutils.normalized_filename = osutils._accessible_normalized_filename
383
smart_add_tree(self.wt, [u'a\u030a'])
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()])
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, [])
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()])
404
osutils.normalized_filename = orig
406
def test_inaccessible_explicit(self):
408
orig = osutils.normalized_filename
409
osutils.normalized_filename = osutils._inaccessible_normalized_filename
411
self.assertRaises(errors.InvalidNormalization,
412
smart_add_tree, self.wt, [u'a\u030a'])
414
osutils.normalized_filename = orig
416
def test_inaccessible_implicit(self):
418
orig = osutils.normalized_filename
419
osutils.normalized_filename = osutils._inaccessible_normalized_filename
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, [])
427
osutils.normalized_filename = orig
147
430
class TestAddActions(TestCase):
149
432
def test_quiet(self):