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
23
import bzrlib.bzrdir as bzrdir
24
from bzrlib.bzrdir import BzrDir
25
import bzrlib.errors as errors
20
26
from bzrlib.errors import NotBranchError, NotVersionedError
21
from bzrlib.tests import TestCaseInTempDir
27
from bzrlib.lockdir import LockDir
28
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
29
from bzrlib.tests import TestCaseWithTransport, TestSkipped
22
30
from bzrlib.trace import mutter
31
from bzrlib.transport import get_transport
32
import bzrlib.workingtree as workingtree
23
33
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
26
class TestTreeDirectory(TestCaseInTempDir):
36
class TestTreeDirectory(TestCaseWithTransport):
28
38
def test_kind_character(self):
29
39
self.assertEqual(TreeDirectory().kind_character(), '/')
32
class TestTreeEntry(TestCaseInTempDir):
42
class TestTreeEntry(TestCaseWithTransport):
34
44
def test_kind_character(self):
35
45
self.assertEqual(TreeEntry().kind_character(), '???')
38
class TestTreeFile(TestCaseInTempDir):
48
class TestTreeFile(TestCaseWithTransport):
40
50
def test_kind_character(self):
41
51
self.assertEqual(TreeFile().kind_character(), '')
44
class TestTreeLink(TestCaseInTempDir):
54
class TestTreeLink(TestCaseWithTransport):
46
56
def test_kind_character(self):
47
57
self.assertEqual(TreeLink().kind_character(), '')
50
class TestWorkingTree(TestCaseInTempDir):
52
def test_listfiles(self):
53
branch = Branch.initialize(u'.')
55
print >> open('file', 'w'), "content"
56
os.symlink('target', 'symlink')
57
tree = branch.working_tree()
58
files = list(tree.list_files())
59
self.assertEqual(files[0], ('dir', '?', 'directory', None, TreeDirectory()))
60
self.assertEqual(files[1], ('file', '?', 'file', None, TreeFile()))
61
self.assertEqual(files[2], ('symlink', '?', 'symlink', None, TreeLink()))
63
def test_open_containing(self):
64
branch = Branch.initialize(u'.')
65
wt, relpath = WorkingTree.open_containing()
66
self.assertEqual('', relpath)
67
self.assertEqual(wt.basedir, branch.base)
68
wt, relpath = WorkingTree.open_containing(u'.')
69
self.assertEqual('', relpath)
70
self.assertEqual(wt.basedir, branch.base)
71
wt, relpath = WorkingTree.open_containing('./foo')
72
self.assertEqual('foo', relpath)
73
self.assertEqual(wt.basedir, branch.base)
74
# paths that are urls are just plain wrong for working trees.
75
self.assertRaises(NotBranchError,
76
WorkingTree.open_containing,
77
'file:///' + os.getcwdu())
79
def test_construct_with_branch(self):
80
branch = Branch.initialize(u'.')
81
tree = WorkingTree(branch.base, branch)
82
self.assertEqual(branch, tree.branch)
83
self.assertEqual(branch.base, tree.basedir)
85
def test_construct_without_branch(self):
86
branch = Branch.initialize(u'.')
87
tree = WorkingTree(branch.base)
88
self.assertEqual(branch.base, tree.branch.base)
89
self.assertEqual(branch.base, tree.basedir)
91
def test_basic_relpath(self):
92
# for comprehensive relpath tests, see whitebox.py.
93
branch = Branch.initialize(u'.')
94
tree = WorkingTree(branch.base)
95
self.assertEqual('child',
96
tree.relpath(os.path.join(os.getcwd(), 'child')))
98
def test_lock_locks_branch(self):
99
branch = Branch.initialize(u'.')
100
tree = WorkingTree(branch.base)
102
self.assertEqual(1, tree.branch._lock_count)
103
self.assertEqual('r', tree.branch._lock_mode)
105
self.assertEqual(None, tree.branch._lock_count)
60
class TestDefaultFormat(TestCaseWithTransport):
62
def test_get_set_default_format(self):
63
old_format = workingtree.WorkingTreeFormat.get_default_format()
65
self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
66
workingtree.WorkingTreeFormat.set_default_format(SampleTreeFormat())
68
# the default branch format is used by the meta dir format
69
# which is not the default bzrdir format at this point
70
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
71
dir.create_repository()
73
result = dir.create_workingtree()
74
self.assertEqual(result, 'A tree')
76
workingtree.WorkingTreeFormat.set_default_format(old_format)
77
self.assertEqual(old_format, workingtree.WorkingTreeFormat.get_default_format())
80
class SampleTreeFormat(workingtree.WorkingTreeFormat):
83
this format is initializable, unsupported to aid in testing the
84
open and open_downlevel routines.
87
def get_format_string(self):
88
"""See WorkingTreeFormat.get_format_string()."""
89
return "Sample tree format."
91
def initialize(self, a_bzrdir, revision_id=None):
92
"""Sample branches cannot be created."""
93
t = a_bzrdir.get_workingtree_transport(self)
94
t.put('format', StringIO(self.get_format_string()))
97
def is_supported(self):
100
def open(self, transport, _found=False):
101
return "opened tree."
104
class TestWorkingTreeFormat(TestCaseWithTransport):
105
"""Tests for the WorkingTreeFormat facility."""
107
def test_find_format(self):
108
# is the right format object found for a working tree?
109
# create a branch with a few known format objects.
110
self.build_tree(["foo/", "bar/"])
111
def check_format(format, url):
112
dir = format._matchingbzrdir.initialize(url)
113
dir.create_repository()
115
format.initialize(dir)
116
t = get_transport(url)
117
found_format = workingtree.WorkingTreeFormat.find_format(dir)
118
self.failUnless(isinstance(found_format, format.__class__))
119
check_format(workingtree.WorkingTreeFormat3(), "bar")
121
def test_find_format_no_tree(self):
122
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
123
self.assertRaises(errors.NoWorkingTree,
124
workingtree.WorkingTreeFormat.find_format,
127
def test_find_format_unknown_format(self):
128
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
129
dir.create_repository()
131
SampleTreeFormat().initialize(dir)
132
self.assertRaises(errors.UnknownFormatError,
133
workingtree.WorkingTreeFormat.find_format,
136
def test_register_unregister_format(self):
137
format = SampleTreeFormat()
139
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
140
dir.create_repository()
143
format.initialize(dir)
144
# register a format for it.
145
workingtree.WorkingTreeFormat.register_format(format)
146
# which branch.Open will refuse (not supported)
147
self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
148
# but open_downlevel will work
149
self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
150
# unregister the format
151
workingtree.WorkingTreeFormat.unregister_format(format)
154
class TestWorkingTreeFormat3(TestCaseWithTransport):
155
"""Tests specific to WorkingTreeFormat3."""
157
def test_disk_layout(self):
158
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
159
control.create_repository()
160
control.create_branch()
161
tree = workingtree.WorkingTreeFormat3().initialize(control)
163
# format 'Bazaar-NG Working Tree format 3'
164
# inventory = blank inventory
165
# pending-merges = ''
167
# no inventory.basis yet
168
t = control.get_workingtree_transport(None)
169
self.assertEqualDiff('Bazaar-NG Working Tree format 3',
170
t.get('format').read())
171
self.assertEqualDiff('<inventory format="5">\n'
173
t.get('inventory').read())
174
self.assertEqualDiff('### bzr hashcache v5\n',
175
t.get('stat-cache').read())
176
self.assertFalse(t.has('inventory.basis'))
177
# no last-revision file means 'None' or 'NULLREVISION'
178
self.assertFalse(t.has('last-revision'))
179
# TODO RBC 20060210 do a commit, check the inventory.basis is created
180
# correctly and last-revision file becomes present.
182
def test_uses_lockdir(self):
183
"""WorkingTreeFormat3 uses its own LockDir:
185
- lock is a directory
186
- when the WorkingTree is locked, LockDir can see that
188
t = self.get_transport()
190
dir = bzrdir.BzrDirMetaFormat1().initialize(url)
191
repo = dir.create_repository()
192
branch = dir.create_branch()
194
tree = workingtree.WorkingTreeFormat3().initialize(dir)
195
except errors.NotLocalUrl:
196
raise TestSkipped('Not a local URL')
197
self.assertIsDirectory('.bzr', t)
198
self.assertIsDirectory('.bzr/checkout', t)
199
self.assertIsDirectory('.bzr/checkout/lock', t)
200
our_lock = LockDir(t, '.bzr/checkout/lock')
201
self.assertEquals(our_lock.peek(), None)
106
202
tree.lock_write()
107
self.assertEqual(1, tree.branch._lock_count)
108
self.assertEqual('w', tree.branch._lock_mode)
203
self.assertTrue(our_lock.peek())
110
self.assertEqual(None, tree.branch._lock_count)
112
def get_pullable_branches(self):
113
self.build_tree(['from/', 'from/file', 'to/'])
114
br_a = Branch.initialize('from')
115
tree = br_a.working_tree()
117
tree.commit('foo', rev_id='A')
118
br_b = Branch.initialize('to')
122
br_a, br_b = self.get_pullable_branches()
123
br_b.working_tree().pull(br_a)
124
self.failUnless(br_b.has_revision('A'))
125
self.assertEqual(['A'], br_b.revision_history())
127
def test_pull_overwrites(self):
128
br_a, br_b = self.get_pullable_branches()
129
br_b.working_tree().commit('foo', rev_id='B')
130
self.assertEqual(['B'], br_b.revision_history())
131
br_b.working_tree().pull(br_a, overwrite=True)
132
self.failUnless(br_b.has_revision('A'))
133
self.failUnless(br_b.has_revision('B'))
134
self.assertEqual(['A'], br_b.revision_history())
136
def test_revert(self):
137
"""Test selected-file revert"""
138
b = Branch.initialize(u'.')
140
self.build_tree(['hello.txt'])
141
file('hello.txt', 'w').write('initial hello')
143
self.assertRaises(NotVersionedError,
144
b.working_tree().revert, ['hello.txt'])
145
tree = WorkingTree(b.base, b)
146
tree.add(['hello.txt'])
147
tree.commit('create initial hello.txt')
149
self.check_file_contents('hello.txt', 'initial hello')
150
file('hello.txt', 'w').write('new hello')
151
self.check_file_contents('hello.txt', 'new hello')
153
# revert file modified since last revision
154
tree.revert(['hello.txt'])
155
self.check_file_contents('hello.txt', 'initial hello')
156
self.check_file_contents('hello.txt~', 'new hello')
158
# reverting again does not clobber the backup
159
tree.revert(['hello.txt'])
160
self.check_file_contents('hello.txt', 'initial hello')
161
self.check_file_contents('hello.txt~', 'new hello')
163
def test_unknowns(self):
164
b = Branch.initialize(u'.')
165
tree = WorkingTree(u'.', b)
166
self.build_tree(['hello.txt',
168
self.assertEquals(list(tree.unknowns()),
205
self.assertEquals(our_lock.peek(), None)