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
30
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
32
from bzrlib.transport import get_transport
33
31
from bzrlib.workingtree import (
65
63
class TestDefaultFormat(TestCaseWithTransport):
67
65
def test_get_set_default_format(self):
68
old_format = workingtree.WorkingTreeFormat.get_default_format()
70
self.assertTrue(isinstance(old_format, workingtree.WorkingTreeFormat3))
71
workingtree.WorkingTreeFormat.set_default_format(SampleTreeFormat())
73
# the default branch format is used by the meta dir format
74
# which is not the default bzrdir format at this point
75
dir = bzrdir.BzrDirMetaFormat1().initialize('.')
76
dir.create_repository()
78
result = dir.create_workingtree()
79
self.assertEqual(result, 'A tree')
81
workingtree.WorkingTreeFormat.set_default_format(old_format)
82
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)
85
123
class SampleTreeFormat(workingtree.WorkingTreeFormat):
86
124
"""A sample format
88
this format is initializable, unsupported to aid in testing the
126
this format is initializable, unsupported to aid in testing the
89
127
open and open_downlevel routines.
107
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)
110
168
class TestWorkingTreeFormat(TestCaseWithTransport):
111
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))
113
184
def test_find_format(self):
114
185
# is the right format object found for a working tree?
115
186
# create a branch with a few known format objects.
149
220
format.initialize(dir)
150
221
# register a format for it.
151
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))
152
227
# which branch.Open will refuse (not supported)
153
228
self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
154
229
# but open_downlevel will work
155
230
self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
156
231
# unregister the format
157
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)
160
314
class TestWorkingTreeFormat3(TestCaseWithTransport):
215
369
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
216
370
control.create_repository()
217
371
control.create_branch()
218
tree = workingtree.WorkingTreeFormat3().initialize(control)
372
tree = workingtree_3.WorkingTreeFormat3().initialize(control)
219
373
tree._transport.delete("pending-merges")
220
374
self.assertEqual([], tree.get_parent_ids())
223
class TestFormat2WorkingTree(TestCaseWithTransport):
224
"""Tests that are specific to format 2 trees."""
226
def create_format2_tree(self, url):
227
return self.make_branch_and_tree(
228
url, format=bzrdir.BzrDirFormat6())
230
def test_conflicts(self):
231
# test backwards compatability
232
tree = self.create_format2_tree('.')
233
self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
235
file('lala.BASE', 'wb').write('labase')
236
expected = conflicts.ContentsConflict('lala')
237
self.assertEqual(list(tree.conflicts()), [expected])
238
file('lala', 'wb').write('la')
239
tree.add('lala', 'lala-id')
240
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
241
self.assertEqual(list(tree.conflicts()), [expected])
242
file('lala.THIS', 'wb').write('lathis')
243
file('lala.OTHER', 'wb').write('laother')
244
# When "text conflict"s happen, stem, THIS and OTHER are text
245
expected = conflicts.TextConflict('lala', file_id='lala-id')
246
self.assertEqual(list(tree.conflicts()), [expected])
247
os.unlink('lala.OTHER')
248
os.mkdir('lala.OTHER')
249
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
250
self.assertEqual(list(tree.conflicts()), [expected])
253
377
class InstrumentedTree(object):
254
378
"""A instrumented tree to check the needs_tree_write_lock decorator."""
326
450
self.build_tree_contents([('other/hello', 'hELLO')])
327
451
other.commit('Case switch')
328
452
this = base.bzrdir.sprout('this').open_workingtree()
329
self.failUnlessExists('this/hello')
453
self.assertPathExists('this/hello')
330
454
self.build_tree_contents([('this/hello', 'Hello World')])
331
455
this.commit('Add World')
332
456
this.merge_from_branch(other.branch)
333
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
457
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
334
458
this.conflicts())
335
459
this.auto_resolve()
336
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
460
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
337
461
this.conflicts())
338
462
self.build_tree_contents([('this/hello', '<<<<<<<')])
339
463
this.auto_resolve()
340
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
464
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
341
465
this.conflicts())
342
466
self.build_tree_contents([('this/hello', '=======')])
343
467
this.auto_resolve()
344
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
468
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
345
469
this.conflicts())
346
470
self.build_tree_contents([('this/hello', '\n>>>>>>>')])
347
471
remaining, resolved = this.auto_resolve()
348
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
472
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
349
473
this.conflicts())
350
474
self.assertEqual([], resolved)
351
475
self.build_tree_contents([('this/hello', 'hELLO wORLD')])
352
476
remaining, resolved = this.auto_resolve()
353
477
self.assertEqual([], this.conflicts())
354
self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
478
self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
356
self.failIfExists('this/hello.BASE')
480
self.assertPathDoesNotExist('this/hello.BASE')
358
482
def test_auto_resolve_dir(self):
359
483
tree = self.make_branch_and_tree('tree')
360
484
self.build_tree(['tree/hello/'])
361
485
tree.add('hello', 'hello-id')
362
file_conflict = conflicts.TextConflict('file', None, 'hello-id')
486
file_conflict = conflicts.TextConflict('file', 'hello-id')
363
487
tree.set_conflicts(conflicts.ConflictList([file_conflict]))
364
488
tree.auto_resolve()