~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_workingtree.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
from cStringIO import StringIO
19
19
import os
20
20
 
21
 
from bzrlib import ignores
22
 
import bzrlib
 
21
from bzrlib import (
 
22
    bzrdir,
 
23
    conflicts,
 
24
    errors,
 
25
    workingtree,
 
26
    )
23
27
from bzrlib.branch import Branch
24
 
from bzrlib import bzrdir, conflicts, errors, workingtree
25
28
from bzrlib.bzrdir import BzrDir
26
 
from bzrlib.errors import NotBranchError, NotVersionedError
27
29
from bzrlib.lockdir import LockDir
28
30
from bzrlib.mutabletree import needs_tree_write_lock
29
 
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
 
31
from bzrlib.symbol_versioning import zero_thirteen
30
32
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
31
 
from bzrlib.trace import mutter
32
33
from bzrlib.transport import get_transport
33
34
from bzrlib.workingtree import (
34
35
    TreeEntry,
35
36
    TreeDirectory,
36
37
    TreeFile,
37
38
    TreeLink,
38
 
    WorkingTree,
39
39
    )
40
40
 
 
41
 
41
42
class TestTreeDirectory(TestCaseWithTransport):
42
43
 
43
44
    def test_kind_character(self):
173
174
        t = control.get_workingtree_transport(None)
174
175
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
175
176
                             t.get('format').read())
176
 
        self.assertEqualDiff('<inventory format="5">\n'
177
 
                             '</inventory>\n',
178
 
                             t.get('inventory').read())
 
177
        self.assertEqualDiff(t.get('inventory').read(), 
 
178
                              '<inventory format="5">\n'
 
179
                              '</inventory>\n',
 
180
                             )
179
181
        self.assertEqualDiff('### bzr hashcache v5\n',
180
182
                             t.get('stat-cache').read())
181
183
        self.assertFalse(t.has('inventory.basis'))
223
225
 
224
226
    def create_format2_tree(self, url):
225
227
        return self.make_branch_and_tree(
226
 
            url, format=bzrlib.bzrdir.BzrDirFormat6())
 
228
            url, format=bzrdir.BzrDirFormat6())
227
229
 
228
230
    def test_conflicts(self):
229
231
        # test backwards compatability
251
253
class TestNonFormatSpecificCode(TestCaseWithTransport):
252
254
    """This class contains tests of workingtree that are not format specific."""
253
255
 
254
 
    
255
256
    def test_gen_file_id(self):
256
 
        gen_file_id = bzrlib.workingtree.gen_file_id
257
 
 
258
 
        # We try to use the filename if possible
259
 
        self.assertStartsWith(gen_file_id('bar'), 'bar-')
260
 
 
261
 
        # but we squash capitalization, and remove non word characters
262
 
        self.assertStartsWith(gen_file_id('Mwoo oof\t m'), 'mwoooofm-')
263
 
 
264
 
        # We also remove leading '.' characters to prevent hidden file-ids
265
 
        self.assertStartsWith(gen_file_id('..gam.py'), 'gam.py-')
266
 
        self.assertStartsWith(gen_file_id('..Mwoo oof\t m'), 'mwoooofm-')
267
 
 
268
 
        # we remove unicode characters, and still don't end up with a 
269
 
        # hidden file id
270
 
        self.assertStartsWith(gen_file_id(u'\xe5\xb5.txt'), 'txt-')
 
257
        file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_file_id,
 
258
                                      'filename')
 
259
        self.assertStartsWith(file_id, 'filename-')
 
260
 
 
261
    def test_gen_root_id(self):
 
262
        file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_root_id)
 
263
        self.assertStartsWith(file_id, 'tree_root-')
271
264
        
272
 
        # Our current method of generating unique ids adds 33 characters
273
 
        # plus an serial number (log10(N) characters)
274
 
        # to the end of the filename. We now restrict the filename portion to
275
 
        # be <= 20 characters, so the maximum length should now be approx < 60
276
 
 
277
 
        # Test both case squashing and length restriction
278
 
        fid = gen_file_id('A'*50 + '.txt')
279
 
        self.assertStartsWith(fid, 'a'*20 + '-')
280
 
        self.failUnless(len(fid) < 60)
281
 
 
282
 
        # restricting length happens after the other actions, so
283
 
        # we preserve as much as possible
284
 
        fid = gen_file_id('\xe5\xb5..aBcd\tefGhijKLMnop\tqrstuvwxyz')
285
 
        self.assertStartsWith(fid, 'abcdefghijklmnopqrst-')
286
 
        self.failUnless(len(fid) < 60)
287
 
 
288
 
    def test_next_id_suffix(self):
289
 
        bzrlib.workingtree._gen_id_suffix = None
290
 
        bzrlib.workingtree._next_id_suffix()
291
 
        self.assertNotEqual(None, bzrlib.workingtree._gen_id_suffix)
292
 
        bzrlib.workingtree._gen_id_suffix = "foo-"
293
 
        bzrlib.workingtree._gen_id_serial = 1
294
 
        self.assertEqual("foo-2", bzrlib.workingtree._next_id_suffix())
295
 
        self.assertEqual("foo-3", bzrlib.workingtree._next_id_suffix())
296
 
        self.assertEqual("foo-4", bzrlib.workingtree._next_id_suffix())
297
 
        self.assertEqual("foo-5", bzrlib.workingtree._next_id_suffix())
298
 
        self.assertEqual("foo-6", bzrlib.workingtree._next_id_suffix())
299
 
        self.assertEqual("foo-7", bzrlib.workingtree._next_id_suffix())
300
 
        self.assertEqual("foo-8", bzrlib.workingtree._next_id_suffix())
301
 
        self.assertEqual("foo-9", bzrlib.workingtree._next_id_suffix())
302
 
        self.assertEqual("foo-10", bzrlib.workingtree._next_id_suffix())
303
 
 
304
 
    def test__translate_ignore_rule(self):
305
 
        tree = self.make_branch_and_tree('.')
306
 
        # translation should return the regex, the number of groups in it,
307
 
        # and the original rule in a tuple.
308
 
        # there are three sorts of ignore rules:
309
 
        # root only - regex is the rule itself without the leading ./
310
 
        self.assertEqual(
311
 
            "(rootdirrule$)", 
312
 
            tree._translate_ignore_rule("./rootdirrule"))
313
 
        # full path - regex is the rule itself
314
 
        self.assertEqual(
315
 
            "(path\\/to\\/file$)",
316
 
            tree._translate_ignore_rule("path/to/file"))
317
 
        # basename only rule - regex is a rule that ignores everything up
318
 
        # to the last / in the filename
319
 
        self.assertEqual(
320
 
            "((?:.*/)?(?!.*/)basenamerule$)",
321
 
            tree._translate_ignore_rule("basenamerule"))
322
 
 
323
 
    def test__combine_ignore_rules(self):
324
 
        tree = self.make_branch_and_tree('.')
325
 
        # the combined ignore regexs need the outer group indices
326
 
        # placed in a dictionary with the rules that were combined.
327
 
        # an empty set of rules
328
 
        # this is returned as a list of combined regex,rule sets, because
329
 
        # python has a limit of 100 combined regexes.
330
 
        compiled_rules = tree._combine_ignore_rules([])
331
 
        self.assertEqual([], compiled_rules)
332
 
        # one of each type of rule.
333
 
        compiled_rules = tree._combine_ignore_rules(
334
 
            ["rule1", "rule/two", "./three"])[0]
335
 
        # what type *is* the compiled regex to do an isinstance of ?
336
 
        self.assertEqual(3, compiled_rules[0].groups)
337
 
        self.assertEqual(
338
 
            {0:"rule1",1:"rule/two",2:"./three"},
339
 
            compiled_rules[1])
340
 
 
341
 
    def test__combine_ignore_rules_grouping(self):
342
 
        tree = self.make_branch_and_tree('.')
343
 
        # when there are too many rules, the output is split into groups of 100
344
 
        rules = []
345
 
        for index in range(198):
346
 
            rules.append('foo')
347
 
        self.assertEqual(2, len(tree._combine_ignore_rules(rules)))
348
 
 
349
 
    def test__get_ignore_rules_as_regex(self):
350
 
        tree = self.make_branch_and_tree('.')
351
 
        # Setup the default ignore list to be empty
352
 
        ignores._set_user_ignores([])
353
 
 
354
 
        # some plugins (shelf) modifies the DEFAULT_IGNORE list in memory
355
 
        # which causes this test to fail so force the DEFAULT_IGNORE
356
 
        # list to be empty
357
 
        orig_default = bzrlib.DEFAULT_IGNORE
358
 
        # Also make sure the runtime ignore list is empty
359
 
        orig_runtime = ignores._runtime_ignores
360
 
        try:
361
 
            bzrlib.DEFAULT_IGNORE = []
362
 
            ignores._runtime_ignores = set()
363
 
 
364
 
            self.build_tree_contents([('.bzrignore', 'CVS\n.hg\n')])
365
 
            reference_output = tree._combine_ignore_rules(
366
 
                                    set(['CVS', '.hg']))[0]
367
 
            regex_rules = tree._get_ignore_rules_as_regex()[0]
368
 
            self.assertEqual(len(reference_output[1]), regex_rules[0].groups)
369
 
            self.assertEqual(reference_output[1], regex_rules[1])
370
 
        finally:
371
 
            bzrlib.DEFAULT_IGNORE = orig_default
372
 
            ignores._runtime_ignores = orig_runtime
373
 
 
374
265
 
375
266
class InstrumentedTree(object):
376
267
    """A instrumented tree to check the needs_tree_write_lock decorator."""
416
307
        self.assertEqual(['t', 'u'], tree._locks)
417
308
        self.assertRaises(TypeError, tree.method_that_raises, 'foo')
418
309
        self.assertEqual(['t', 'u', 't', 'u'], tree._locks)
 
310
 
 
311
 
 
312
class TestAutoResolve(TestCaseWithTransport):
 
313
 
 
314
    def test_auto_resolve(self):
 
315
        base = self.make_branch_and_tree('base')
 
316
        self.build_tree_contents([('base/hello', 'Hello')])
 
317
        base.add('hello', 'hello_id')
 
318
        base.commit('Hello')
 
319
        other = base.bzrdir.sprout('other').open_workingtree()
 
320
        self.build_tree_contents([('other/hello', 'hELLO')])
 
321
        other.commit('Case switch')
 
322
        this = base.bzrdir.sprout('this').open_workingtree()
 
323
        self.failUnlessExists('this/hello')
 
324
        self.build_tree_contents([('this/hello', 'Hello World')])
 
325
        this.commit('Add World')
 
326
        this.merge_from_branch(other.branch)
 
327
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
328
                         this.conflicts())
 
329
        this.auto_resolve()
 
330
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
331
                         this.conflicts())
 
332
        self.build_tree_contents([('this/hello', '<<<<<<<')])
 
333
        this.auto_resolve()
 
334
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
335
                         this.conflicts())
 
336
        self.build_tree_contents([('this/hello', '=======')])
 
337
        this.auto_resolve()
 
338
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
339
                         this.conflicts())
 
340
        self.build_tree_contents([('this/hello', '\n>>>>>>>')])
 
341
        remaining, resolved = this.auto_resolve()
 
342
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
343
                         this.conflicts())
 
344
        self.assertEqual([], resolved)
 
345
        self.build_tree_contents([('this/hello', 'hELLO wORLD')])
 
346
        remaining, resolved = this.auto_resolve()
 
347
        self.assertEqual([], this.conflicts())
 
348
        self.assertEqual([conflicts.TextConflict('hello', None, 'hello_id')],
 
349
                         resolved)
 
350
        self.failIfExists('this/hello.BASE')
 
351
 
 
352
    def test_auto_resolve_dir(self):
 
353
        tree = self.make_branch_and_tree('tree')
 
354
        self.build_tree(['tree/hello/'])
 
355
        tree.add('hello', 'hello-id')
 
356
        file_conflict = conflicts.TextConflict('file', None, 'hello-id')
 
357
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
 
358
        tree.auto_resolve()