14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from cStringIO import StringIO
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
18
from bzrlib import (
27
from bzrlib.branch import Branch
28
from bzrlib.bzrdir import BzrDir
29
28
from bzrlib.lockdir import LockDir
30
29
from bzrlib.mutabletree import needs_tree_write_lock
31
from bzrlib.symbol_versioning import zero_thirteen
32
30
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
33
from bzrlib.transport import get_transport
34
31
from bzrlib.workingtree import (
66
63
class TestDefaultFormat(TestCaseWithTransport):
68
65
def test_get_set_default_format(self):
69
old_format = workingtree.WorkingTreeFormat.get_default_format()
71
self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
72
workingtree.WorkingTreeFormat.set_default_format(SampleTreeFormat())
74
# the default branch format is used by the meta dir format
75
# which is not the default bzrdir format at this point
76
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
77
dir.create_repository()
79
result = dir.create_workingtree()
80
self.assertEqual(result, 'A tree')
82
workingtree.WorkingTreeFormat.set_default_format(old_format)
83
self.assertEqual(old_format, workingtree.WorkingTreeFormat.get_default_format())
66
old_format = workingtree.format_registry.get_default()
68
self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
69
workingtree.format_registry.set_default(SampleTreeFormat())
71
# the default branch format is used by the meta dir format
72
# which is not the default bzrdir format at this point
73
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
74
dir.create_repository()
76
result = dir.create_workingtree()
77
self.assertEqual(result, 'A tree')
79
workingtree.format_registry.set_default(old_format)
80
self.assertEqual(old_format, workingtree.format_registry.get_default())
82
def test_get_set_default_format_by_key(self):
83
old_format = workingtree.format_registry.get_default()
85
format = SampleTreeFormat()
86
workingtree.format_registry.register(format)
87
self.addCleanup(workingtree.format_registry.remove, format)
88
self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
89
workingtree.format_registry.set_default_key(format.get_format_string())
91
# the default branch format is used by the meta dir format
92
# which is not the default bzrdir format at this point
93
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
94
dir.create_repository()
96
result = dir.create_workingtree()
97
self.assertEqual(result, 'A tree')
99
workingtree.format_registry.set_default_key(
100
old_format.get_format_string())
101
self.assertEqual(old_format, workingtree.format_registry.get_default())
104
tree = self.make_branch_and_tree('.')
105
open_direct = workingtree.WorkingTree.open('.')
106
self.assertEqual(tree.basedir, open_direct.basedir)
107
open_no_args = workingtree.WorkingTree.open()
108
self.assertEqual(tree.basedir, open_no_args.basedir)
110
def test_open_containing(self):
111
tree = self.make_branch_and_tree('.')
112
open_direct, relpath = workingtree.WorkingTree.open_containing('.')
113
self.assertEqual(tree.basedir, open_direct.basedir)
114
self.assertEqual('', relpath)
115
open_no_args, relpath = workingtree.WorkingTree.open_containing()
116
self.assertEqual(tree.basedir, open_no_args.basedir)
117
self.assertEqual('', relpath)
118
open_subdir, relpath = workingtree.WorkingTree.open_containing('subdir')
119
self.assertEqual(tree.basedir, open_subdir.basedir)
120
self.assertEqual('subdir', relpath)
86
123
class SampleTreeFormat(workingtree.WorkingTreeFormat):
87
124
"""A sample format
89
this format is initializable, unsupported to aid in testing the
126
this format is initializable, unsupported to aid in testing the
90
127
open and open_downlevel routines.
108
145
return "opened tree."
148
class SampleExtraTreeFormat(workingtree.WorkingTreeFormat):
149
"""A sample format that does not support use in a metadir.
153
def get_format_string(self):
154
# Not usable in a metadir, so no format string
157
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
158
accelerator_tree=None, hardlink=False):
159
raise NotImplementedError(self.initialize)
161
def is_supported(self):
164
def open(self, transport, _found=False):
165
raise NotImplementedError(self.open)
111
168
class TestWorkingTreeFormat(TestCaseWithTransport):
112
169
"""Tests for the WorkingTreeFormat facility."""
171
def test_find_format_string(self):
172
# is the right format object found for a working tree?
173
branch = self.make_branch('branch')
174
self.assertRaises(errors.NoWorkingTree,
175
workingtree.WorkingTreeFormat.find_format_string, branch.bzrdir)
176
transport = branch.bzrdir.get_workingtree_transport(None)
178
transport.put_bytes("format", "some format name")
179
# The format does not have to be known by Bazaar,
180
# find_format_string just retrieves the name
181
self.assertEquals("some format name",
182
workingtree.WorkingTreeFormat.find_format_string(branch.bzrdir))
114
184
def test_find_format(self):
115
185
# is the right format object found for a working tree?
116
186
# create a branch with a few known format objects.
150
220
format.initialize(dir)
151
221
# register a format for it.
152
workingtree.WorkingTreeFormat.register_format(format)
222
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
223
workingtree.WorkingTreeFormat.register_format, format)
224
self.assertTrue(format in
225
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
226
workingtree.WorkingTreeFormat.get_formats))
153
227
# which branch.Open will refuse (not supported)
154
228
self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
155
229
# but open_downlevel will work
156
230
self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
157
231
# unregister the format
158
workingtree.WorkingTreeFormat.unregister_format(format)
232
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
233
workingtree.WorkingTreeFormat.unregister_format, format)
234
self.assertFalse(format in
235
self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
236
workingtree.WorkingTreeFormat.get_formats))
239
class TestWorkingTreeIterEntriesByDir_wSubtrees(TestCaseWithTransport):
241
def make_simple_tree(self):
242
tree = self.make_branch_and_tree('tree', format='development-subtree')
243
self.build_tree(['tree/a/', 'tree/a/b/', 'tree/a/b/c'])
244
tree.set_root_id('root-id')
245
tree.add(['a', 'a/b', 'a/b/c'], ['a-id', 'b-id', 'c-id'])
246
tree.commit('initial')
249
def test_just_directory(self):
250
tree = self.make_simple_tree()
251
self.assertEqual([('directory', 'root-id'),
252
('directory', 'a-id'),
253
('directory', 'b-id'),
255
[(ie.kind, ie.file_id)
256
for path, ie in tree.iter_entries_by_dir()])
257
subtree = self.make_branch_and_tree('tree/a/b')
258
self.assertEqual([('tree-reference', 'b-id')],
259
[(ie.kind, ie.file_id)
260
for path, ie in tree.iter_entries_by_dir(['b-id'])])
262
def test_direct_subtree(self):
263
tree = self.make_simple_tree()
264
subtree = self.make_branch_and_tree('tree/a/b')
265
self.assertEqual([('directory', 'root-id'),
266
('directory', 'a-id'),
267
('tree-reference', 'b-id')],
268
[(ie.kind, ie.file_id)
269
for path, ie in tree.iter_entries_by_dir()])
271
def test_indirect_subtree(self):
272
tree = self.make_simple_tree()
273
subtree = self.make_branch_and_tree('tree/a')
274
self.assertEqual([('directory', 'root-id'),
275
('tree-reference', 'a-id')],
276
[(ie.kind, ie.file_id)
277
for path, ie in tree.iter_entries_by_dir()])
280
class TestWorkingTreeFormatRegistry(TestCase):
283
super(TestWorkingTreeFormatRegistry, self).setUp()
284
self.registry = workingtree.WorkingTreeFormatRegistry()
286
def test_register_unregister_format(self):
287
format = SampleTreeFormat()
288
self.registry.register(format)
289
self.assertEquals(format, self.registry.get("Sample tree format."))
290
self.registry.remove(format)
291
self.assertRaises(KeyError, self.registry.get, "Sample tree format.")
293
def test_get_all(self):
294
format = SampleTreeFormat()
295
self.assertEquals([], self.registry._get_all())
296
self.registry.register(format)
297
self.assertEquals([format], self.registry._get_all())
299
def test_register_extra(self):
300
format = SampleExtraTreeFormat()
301
self.assertEquals([], self.registry._get_all())
302
self.registry.register_extra(format)
303
self.assertEquals([format], self.registry._get_all())
305
def test_register_extra_lazy(self):
306
self.assertEquals([], self.registry._get_all())
307
self.registry.register_extra_lazy("bzrlib.tests.test_workingtree",
308
"SampleExtraTreeFormat")
309
formats = self.registry._get_all()
310
self.assertEquals(1, len(formats))
311
self.assertIsInstance(formats[0], SampleExtraTreeFormat)
161
314
class TestWorkingTreeFormat3(TestCaseWithTransport):
216
369
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
217
370
control.create_repository()
218
371
control.create_branch()
219
tree = workingtree.WorkingTreeFormat3().initialize(control)
220
tree._control_files._transport.delete("pending-merges")
372
tree = workingtree_3.WorkingTreeFormat3().initialize(control)
373
tree._transport.delete("pending-merges")
221
374
self.assertEqual([], tree.get_parent_ids())
224
class TestFormat2WorkingTree(TestCaseWithTransport):
225
"""Tests that are specific to format 2 trees."""
227
def create_format2_tree(self, url):
228
return self.make_branch_and_tree(
229
url, format=bzrdir.BzrDirFormat6())
231
def test_conflicts(self):
232
# test backwards compatability
233
tree = self.create_format2_tree('.')
234
self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
236
file('lala.BASE', 'wb').write('labase')
237
expected = conflicts.ContentsConflict('lala')
238
self.assertEqual(list(tree.conflicts()), [expected])
239
file('lala', 'wb').write('la')
240
tree.add('lala', 'lala-id')
241
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
242
self.assertEqual(list(tree.conflicts()), [expected])
243
file('lala.THIS', 'wb').write('lathis')
244
file('lala.OTHER', 'wb').write('laother')
245
# When "text conflict"s happen, stem, THIS and OTHER are text
246
expected = conflicts.TextConflict('lala', file_id='lala-id')
247
self.assertEqual(list(tree.conflicts()), [expected])
248
os.unlink('lala.OTHER')
249
os.mkdir('lala.OTHER')
250
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
251
self.assertEqual(list(tree.conflicts()), [expected])
254
class TestNonFormatSpecificCode(TestCaseWithTransport):
255
"""This class contains tests of workingtree that are not format specific."""
257
def test_gen_file_id(self):
258
file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_file_id,
260
self.assertStartsWith(file_id, 'filename-')
262
def test_gen_root_id(self):
263
file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_root_id)
264
self.assertStartsWith(file_id, 'tree_root-')
267
377
class InstrumentedTree(object):
268
378
"""A instrumented tree to check the needs_tree_write_lock decorator."""
340
450
self.build_tree_contents([('other/hello', 'hELLO')])
341
451
other.commit('Case switch')
342
452
this = base.bzrdir.sprout('this').open_workingtree()
343
self.failUnlessExists('this/hello')
453
self.assertPathExists('this/hello')
344
454
self.build_tree_contents([('this/hello', 'Hello World')])
345
455
this.commit('Add World')
346
456
this.merge_from_branch(other.branch)
347
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
457
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
348
458
this.conflicts())
349
459
this.auto_resolve()
350
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
460
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
351
461
this.conflicts())
352
462
self.build_tree_contents([('this/hello', '<<<<<<<')])
353
463
this.auto_resolve()
354
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
464
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
355
465
this.conflicts())
356
466
self.build_tree_contents([('this/hello', '=======')])
357
467
this.auto_resolve()
358
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
468
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
359
469
this.conflicts())
360
470
self.build_tree_contents([('this/hello', '\n>>>>>>>')])
361
471
remaining, resolved = this.auto_resolve()
362
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
472
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
363
473
this.conflicts())
364
474
self.assertEqual([], resolved)
365
475
self.build_tree_contents([('this/hello', 'hELLO wORLD')])
366
476
remaining, resolved = this.auto_resolve()
367
477
self.assertEqual([], this.conflicts())
368
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
478
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
370
self.failIfExists('this/hello.BASE')
480
self.assertPathDoesNotExist('this/hello.BASE')
372
482
def test_auto_resolve_dir(self):
373
483
tree = self.make_branch_and_tree('tree')
374
484
self.build_tree(['tree/hello/'])
375
485
tree.add('hello', 'hello-id')
376
file_conflict = conflicts.TextConflict('file', None, 'hello-id')
486
file_conflict = conflicts.TextConflict('file', 'hello-id')
377
487
tree.set_conflicts(conflicts.ConflictList([file_conflict]))
378
488
tree.auto_resolve()