15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from cStringIO import StringIO
19
22
from bzrlib.branch import Branch
20
23
from bzrlib.errors import NotBranchError, NotVersionedError
21
from bzrlib.tests import TestCaseInTempDir
24
from bzrlib.tests import TestCaseWithTransport
22
25
from bzrlib.trace import mutter
23
26
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
24
27
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
27
class TestTreeDirectory(TestCaseInTempDir):
30
class TestTreeDirectory(TestCaseWithTransport):
29
32
def test_kind_character(self):
30
33
self.assertEqual(TreeDirectory().kind_character(), '/')
33
class TestTreeEntry(TestCaseInTempDir):
36
class TestTreeEntry(TestCaseWithTransport):
35
38
def test_kind_character(self):
36
39
self.assertEqual(TreeEntry().kind_character(), '???')
39
class TestTreeFile(TestCaseInTempDir):
42
class TestTreeFile(TestCaseWithTransport):
41
44
def test_kind_character(self):
42
45
self.assertEqual(TreeFile().kind_character(), '')
45
class TestTreeLink(TestCaseInTempDir):
48
class TestTreeLink(TestCaseWithTransport):
47
50
def test_kind_character(self):
48
51
self.assertEqual(TreeLink().kind_character(), '')
51
class TestWorkingTree(TestCaseInTempDir):
54
class TestWorkingTree(TestCaseWithTransport):
53
56
def test_listfiles(self):
54
branch = Branch.initialize(u'.')
57
tree = WorkingTree.create_standalone('.')
56
59
print >> open('file', 'w'), "content"
58
61
os.symlink('target', 'symlink')
59
tree = branch.working_tree()
60
62
files = list(tree.list_files())
61
63
self.assertEqual(files[0], ('dir', '?', 'directory', None, TreeDirectory()))
62
64
self.assertEqual(files[1], ('file', '?', 'file', None, TreeFile()))
64
66
self.assertEqual(files[2], ('symlink', '?', 'symlink', None, TreeLink()))
66
68
def test_open_containing(self):
67
branch = Branch.initialize(u'.')
69
branch = WorkingTree.create_standalone('.').branch
68
70
wt, relpath = WorkingTree.open_containing()
69
71
self.assertEqual('', relpath)
70
self.assertEqual(wt.basedir, branch.base)
72
self.assertEqual(wt.basedir + '/', branch.base)
71
73
wt, relpath = WorkingTree.open_containing(u'.')
72
74
self.assertEqual('', relpath)
73
self.assertEqual(wt.basedir, branch.base)
75
self.assertEqual(wt.basedir + '/', branch.base)
74
76
wt, relpath = WorkingTree.open_containing('./foo')
75
77
self.assertEqual('foo', relpath)
76
self.assertEqual(wt.basedir, branch.base)
78
self.assertEqual(wt.basedir + '/', branch.base)
77
79
# paths that are urls are just plain wrong for working trees.
78
80
self.assertRaises(NotBranchError,
79
81
WorkingTree.open_containing,
80
82
'file:///' + getcwd())
82
84
def test_construct_with_branch(self):
83
branch = Branch.initialize(u'.')
85
branch = WorkingTree.create_standalone('.').branch
84
86
tree = WorkingTree(branch.base, branch)
85
87
self.assertEqual(branch, tree.branch)
86
self.assertEqual(branch.base, tree.basedir)
88
self.assertEqual(branch.base, tree.basedir + '/')
88
90
def test_construct_without_branch(self):
89
branch = Branch.initialize(u'.')
91
branch = WorkingTree.create_standalone('.').branch
90
92
tree = WorkingTree(branch.base)
91
93
self.assertEqual(branch.base, tree.branch.base)
92
self.assertEqual(branch.base, tree.basedir)
94
self.assertEqual(branch.base, tree.basedir + '/')
94
96
def test_basic_relpath(self):
95
97
# for comprehensive relpath tests, see whitebox.py.
96
branch = Branch.initialize(u'.')
97
tree = WorkingTree(branch.base)
98
tree = WorkingTree.create_standalone('.')
98
99
self.assertEqual('child',
99
100
tree.relpath(pathjoin(getcwd(), 'child')))
101
102
def test_lock_locks_branch(self):
102
branch = Branch.initialize(u'.')
103
tree = WorkingTree(branch.base)
103
tree = WorkingTree.create_standalone('.')
105
self.assertEqual(1, tree.branch._lock_count)
106
self.assertEqual('r', tree.branch._lock_mode)
105
self.assertEqual('r', tree.branch.peek_lock_mode())
108
self.assertEqual(None, tree.branch._lock_count)
107
self.assertEqual(None, tree.branch.peek_lock_mode())
109
108
tree.lock_write()
110
self.assertEqual(1, tree.branch._lock_count)
111
self.assertEqual('w', tree.branch._lock_mode)
109
self.assertEqual('w', tree.branch.peek_lock_mode())
113
self.assertEqual(None, tree.branch._lock_count)
111
self.assertEqual(None, tree.branch.peek_lock_mode())
115
def get_pullable_branches(self):
113
def get_pullable_trees(self):
116
114
self.build_tree(['from/', 'from/file', 'to/'])
117
br_a = Branch.initialize('from')
118
tree = br_a.working_tree()
115
tree = WorkingTree.create_standalone('from')
120
117
tree.commit('foo', rev_id='A')
121
br_b = Branch.initialize('to')
118
tree_b = WorkingTree.create_standalone('to')
124
121
def test_pull(self):
125
br_a, br_b = self.get_pullable_branches()
126
br_b.working_tree().pull(br_a)
127
self.failUnless(br_b.has_revision('A'))
128
self.assertEqual(['A'], br_b.revision_history())
122
tree_a, tree_b = self.get_pullable_trees()
123
tree_b.pull(tree_a.branch)
124
self.failUnless(tree_b.branch.repository.has_revision('A'))
125
self.assertEqual(['A'], tree_b.branch.revision_history())
130
127
def test_pull_overwrites(self):
131
br_a, br_b = self.get_pullable_branches()
132
br_b.working_tree().commit('foo', rev_id='B')
133
self.assertEqual(['B'], br_b.revision_history())
134
br_b.working_tree().pull(br_a, overwrite=True)
135
self.failUnless(br_b.has_revision('A'))
136
self.failUnless(br_b.has_revision('B'))
137
self.assertEqual(['A'], br_b.revision_history())
128
tree_a, tree_b = self.get_pullable_trees()
129
tree_b.commit('foo', rev_id='B')
130
self.assertEqual(['B'], tree_b.branch.revision_history())
131
tree_b.pull(tree_a.branch, overwrite=True)
132
self.failUnless(tree_b.branch.repository.has_revision('A'))
133
self.failUnless(tree_b.branch.repository.has_revision('B'))
134
self.assertEqual(['A'], tree_b.branch.revision_history())
139
136
def test_revert(self):
140
137
"""Test selected-file revert"""
141
b = Branch.initialize(u'.')
138
tree = WorkingTree.create_standalone('.')
143
140
self.build_tree(['hello.txt'])
144
141
file('hello.txt', 'w').write('initial hello')
146
143
self.assertRaises(NotVersionedError,
147
b.working_tree().revert, ['hello.txt'])
148
tree = WorkingTree(b.base, b)
144
tree.revert, ['hello.txt'])
149
145
tree.add(['hello.txt'])
150
146
tree.commit('create initial hello.txt')
174
169
def test_hashcache(self):
175
170
from bzrlib.tests.test_hashcache import pause
176
b = Branch.initialize(u'.')
177
tree = WorkingTree(u'.', b)
171
tree = WorkingTree.create_standalone('.')
178
172
self.build_tree(['hello.txt',
180
174
tree.add('hello.txt')
182
176
sha = tree.get_file_sha1(tree.path2id('hello.txt'))
183
177
self.assertEqual(1, tree._hashcache.miss_count)
184
tree2 = WorkingTree(u'.', b)
178
tree2 = WorkingTree('.', tree.branch)
185
179
sha2 = tree2.get_file_sha1(tree2.path2id('hello.txt'))
186
180
self.assertEqual(0, tree2._hashcache.miss_count)
187
181
self.assertEqual(1, tree2._hashcache.hit_count)
183
def test_checkout(self):
184
# at this point as we dont have checkout versions, checkout simply
185
# populates the required files for a working tree at the dir.
186
self.build_tree(['branch/'])
187
b = Branch.create('branch')
188
t = WorkingTree.create(b, 'tree')
189
# as we are moving the ownership to working tree, we will check here
190
# that its split out correctly
191
self.failIfExists('branch/.bzr/inventory')
192
self.failIfExists('branch/.bzr/pending-merges')
194
bzrlib.xml5.serializer_v5.write_inventory(bzrlib.inventory.Inventory(),
196
self.assertFileEqual(sio.getvalue(), 'tree/.bzr/inventory')
197
self.assertFileEqual('', 'tree/.bzr/pending-merges')
199
def test_initialize(self):
200
# initialize should create a working tree and branch in an existing dir
201
t = WorkingTree.create_standalone('.')
203
self.assertEqual(t.branch.base, b.base)
204
t2 = WorkingTree('.')
205
self.assertEqual(t.basedir, t2.basedir)
206
self.assertEqual(b.base, t2.branch.base)
207
# TODO maybe we should check the branch format? not sure if its
210
def test_rename_dirs(self):
211
"""Test renaming directories and the files within them."""
212
wt = self.make_branch_and_tree('.')
214
self.build_tree(['dir/', 'dir/sub/', 'dir/sub/file'])
215
wt.add(['dir', 'dir/sub', 'dir/sub/file'])
217
wt.commit('create initial state')
219
revid = b.revision_history()[0]
220
self.log('first revision_id is {%s}' % revid)
222
inv = b.repository.get_revision_inventory(revid)
223
self.log('contents of inventory: %r' % inv.entries())
225
self.check_inventory_shape(inv,
226
['dir', 'dir/sub', 'dir/sub/file'])
228
wt.rename_one('dir', 'newdir')
230
self.check_inventory_shape(wt.read_working_inventory(),
231
['newdir', 'newdir/sub', 'newdir/sub/file'])
233
wt.rename_one('newdir/sub', 'newdir/newsub')
234
self.check_inventory_shape(wt.read_working_inventory(),
235
['newdir', 'newdir/newsub',
236
'newdir/newsub/file'])
238
def test_add_in_unversioned(self):
239
"""Try to add a file in an unversioned directory.
241
"bzr add" adds the parent as necessary, but simple working tree add
244
from bzrlib.errors import NotVersionedError
245
wt = self.make_branch_and_tree('.')
246
self.build_tree(['foo/',
248
self.assertRaises(NotVersionedError,
252
def test_remove_verbose(self):
253
#FIXME the remove api should not print or otherwise depend on the
254
# text UI - RBC 20060124
255
wt = self.make_branch_and_tree('.')
256
self.build_tree(['hello'])
258
wt.commit(message='add hello')
261
self.assertEqual(None, self.apply_redirected(None, stdout, stderr,
265
self.assertEqual('? hello\n', stdout.getvalue())
266
self.assertEqual('', stderr.getvalue())