18
18
from cStringIO import StringIO
21
from bzrlib import ignores
22
23
from bzrlib.branch import Branch
23
import bzrlib.bzrdir as bzrdir
24
from bzrlib import bzrdir, conflicts, errors, workingtree
24
25
from bzrlib.bzrdir import BzrDir
25
from bzrlib.conflicts import *
26
import bzrlib.errors as errors
27
26
from bzrlib.errors import NotBranchError, NotVersionedError
28
27
from bzrlib.lockdir import LockDir
28
from bzrlib.mutabletree import needs_tree_write_lock
29
29
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
30
from bzrlib.tests import TestCaseWithTransport, TestSkipped
30
from bzrlib.symbol_versioning import zero_thirteen
31
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
31
32
from bzrlib.trace import mutter
32
33
from bzrlib.transport import get_transport
33
import bzrlib.workingtree as workingtree
34
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
34
from bzrlib.workingtree import (
37
42
class TestTreeDirectory(TestCaseWithTransport):
169
174
t = control.get_workingtree_transport(None)
170
175
self.assertEqualDiff('Bazaar-NG Working Tree format 3',
171
176
t.get('format').read())
172
self.assertEqualDiff('<inventory format="5">\n'
174
t.get('inventory').read())
177
# self.assertContainsRe(t.get('inventory').read(),
178
# '<inventory file_id="[^"]*" format="5">\n'
181
# WorkingTreeFormat3 doesn't default to creating a unique root id,
182
# because it is incompatible with older bzr versions
183
self.assertContainsRe(t.get('inventory').read(),
184
'<inventory format="5">\n'
175
187
self.assertEqualDiff('### bzr hashcache v5\n',
176
188
t.get('stat-cache').read())
177
189
self.assertFalse(t.has('inventory.basis'))
206
218
self.assertEquals(our_lock.peek(), None)
220
def test_missing_pending_merges(self):
221
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
222
control.create_repository()
223
control.create_branch()
224
tree = workingtree.WorkingTreeFormat3().initialize(control)
225
tree._control_files._transport.delete("pending-merges")
226
self.assertEqual([], tree.get_parent_ids())
229
class TestFormat2WorkingTree(TestCaseWithTransport):
230
"""Tests that are specific to format 2 trees."""
208
232
def create_format2_tree(self, url):
209
return BzrDir.create_standalone_workingtree(url)
233
return self.make_branch_and_tree(
234
url, format=bzrlib.bzrdir.BzrDirFormat6())
211
def test_conflicts_format2(self):
236
def test_conflicts(self):
212
237
# test backwards compatability
213
238
tree = self.create_format2_tree('.')
214
239
self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
216
241
file('lala.BASE', 'wb').write('labase')
217
expected = ContentsConflict('lala')
242
expected = conflicts.ContentsConflict('lala')
218
243
self.assertEqual(list(tree.conflicts()), [expected])
219
244
file('lala', 'wb').write('la')
220
245
tree.add('lala', 'lala-id')
221
expected = ContentsConflict('lala', file_id='lala-id')
246
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
222
247
self.assertEqual(list(tree.conflicts()), [expected])
223
248
file('lala.THIS', 'wb').write('lathis')
224
249
file('lala.OTHER', 'wb').write('laother')
225
250
# When "text conflict"s happen, stem, THIS and OTHER are text
226
expected = TextConflict('lala', file_id='lala-id')
251
expected = conflicts.TextConflict('lala', file_id='lala-id')
227
252
self.assertEqual(list(tree.conflicts()), [expected])
228
253
os.unlink('lala.OTHER')
229
254
os.mkdir('lala.OTHER')
230
expected = ContentsConflict('lala', file_id='lala-id')
255
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
231
256
self.assertEqual(list(tree.conflicts()), [expected])
259
class TestNonFormatSpecificCode(TestCaseWithTransport):
260
"""This class contains tests of workingtree that are not format specific."""
262
def test_gen_file_id(self):
263
file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_file_id,
265
self.assertStartsWith(file_id, 'filename-')
267
def test_gen_root_id(self):
268
file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_root_id)
269
self.assertStartsWith(file_id, 'tree_root-')
272
class InstrumentedTree(object):
273
"""A instrumented tree to check the needs_tree_write_lock decorator."""
278
def lock_tree_write(self):
279
self._locks.append('t')
281
@needs_tree_write_lock
282
def method_with_tree_write_lock(self, *args, **kwargs):
283
"""A lock_tree_write decorated method that returns its arguments."""
286
@needs_tree_write_lock
287
def method_that_raises(self):
288
"""This method causes an exception when called with parameters.
290
This allows the decorator code to be checked - it should still call
295
self._locks.append('u')
298
class TestInstrumentedTree(TestCase):
300
def test_needs_tree_write_lock(self):
301
"""@needs_tree_write_lock should be semantically transparent."""
302
tree = InstrumentedTree()
304
'method_with_tree_write_lock',
305
tree.method_with_tree_write_lock.__name__)
307
"A lock_tree_write decorated method that returns its arguments.",
308
tree.method_with_tree_write_lock.__doc__)
311
result = tree.method_with_tree_write_lock(1,2,3, a='b')
312
self.assertEqual((args, kwargs), result)
313
self.assertEqual(['t', 'u'], tree._locks)
314
self.assertRaises(TypeError, tree.method_that_raises, 'foo')
315
self.assertEqual(['t', 'u', 't', 'u'], tree._locks)