~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_workingtree.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-11 00:23:23 UTC
  • mfrom: (2070 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061011002323-82ba88c293d7caff
[merge] bzr.dev 2070

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
21
22
import bzrlib
22
23
from bzrlib.branch import Branch
23
24
from bzrlib import bzrdir, conflicts, errors, workingtree
24
25
from bzrlib.bzrdir import BzrDir
25
26
from bzrlib.errors import NotBranchError, NotVersionedError
26
27
from bzrlib.lockdir import LockDir
 
28
from bzrlib.mutabletree import needs_tree_write_lock
27
29
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
28
 
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
30
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
29
31
from bzrlib.trace import mutter
30
32
from bzrlib.transport import get_transport
31
 
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
32
 
                                WorkingTree)
 
33
from bzrlib.workingtree import (
 
34
    TreeEntry,
 
35
    TreeDirectory,
 
36
    TreeFile,
 
37
    TreeLink,
 
38
    WorkingTree,
 
39
    )
33
40
 
34
41
class TestTreeDirectory(TestCaseWithTransport):
35
42
 
89
96
    def initialize(self, a_bzrdir, revision_id=None):
90
97
        """Sample branches cannot be created."""
91
98
        t = a_bzrdir.get_workingtree_transport(self)
92
 
        t.put('format', StringIO(self.get_format_string()))
 
99
        t.put_bytes('format', self.get_format_string())
93
100
        return 'A tree'
94
101
 
95
102
    def is_supported(self):
208
215
        control.create_branch()
209
216
        tree = workingtree.WorkingTreeFormat3().initialize(control)
210
217
        tree._control_files._transport.delete("pending-merges")
211
 
        self.assertEqual([], tree.pending_merges())
 
218
        self.assertEqual([], tree.get_parent_ids())
212
219
 
213
220
 
214
221
class TestFormat2WorkingTree(TestCaseWithTransport):
246
253
 
247
254
    
248
255
    def test_gen_file_id(self):
249
 
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('bar'), 'bar-')
250
 
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('Mwoo oof\t m'), 'Mwoooofm-')
251
 
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('..gam.py'), 'gam.py-')
252
 
        self.assertStartsWith(bzrlib.workingtree.gen_file_id('..Mwoo oof\t m'), 'Mwoooofm-')
 
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-')
 
271
        
 
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)
253
287
 
254
288
    def test_next_id_suffix(self):
255
289
        bzrlib.workingtree._gen_id_suffix = None
314
348
 
315
349
    def test__get_ignore_rules_as_regex(self):
316
350
        tree = self.make_branch_and_tree('.')
317
 
        self.build_tree_contents([('.bzrignore', 'CVS\n.hg\n')])
318
 
        reference_output = tree._combine_ignore_rules(['CVS', '.hg'])[0]
319
 
        regex_rules = tree._get_ignore_rules_as_regex()[0]
320
 
        self.assertEqual(len(reference_output[1]), regex_rules[0].groups)
321
 
        self.assertEqual(reference_output[1], regex_rules[1])
 
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
 
 
375
class InstrumentedTree(object):
 
376
    """A instrumented tree to check the needs_tree_write_lock decorator."""
 
377
 
 
378
    def __init__(self):
 
379
        self._locks = []
 
380
 
 
381
    def lock_tree_write(self):
 
382
        self._locks.append('t')
 
383
 
 
384
    @needs_tree_write_lock
 
385
    def method_with_tree_write_lock(self, *args, **kwargs):
 
386
        """A lock_tree_write decorated method that returns its arguments."""
 
387
        return args, kwargs
 
388
 
 
389
    @needs_tree_write_lock
 
390
    def method_that_raises(self):
 
391
        """This method causes an exception when called with parameters.
 
392
        
 
393
        This allows the decorator code to be checked - it should still call
 
394
        unlock.
 
395
        """
 
396
 
 
397
    def unlock(self):
 
398
        self._locks.append('u')
 
399
 
 
400
 
 
401
class TestInstrumentedTree(TestCase):
 
402
 
 
403
    def test_needs_tree_write_lock(self):
 
404
        """@needs_tree_write_lock should be semantically transparent."""
 
405
        tree = InstrumentedTree()
 
406
        self.assertEqual(
 
407
            'method_with_tree_write_lock',
 
408
            tree.method_with_tree_write_lock.__name__)
 
409
        self.assertEqual(
 
410
            "A lock_tree_write decorated method that returns its arguments.",
 
411
            tree.method_with_tree_write_lock.__doc__)
 
412
        args = (1, 2, 3)
 
413
        kwargs = {'a':'b'}
 
414
        result = tree.method_with_tree_write_lock(1,2,3, a='b')
 
415
        self.assertEqual((args, kwargs), result)
 
416
        self.assertEqual(['t', 'u'], tree._locks)
 
417
        self.assertRaises(TypeError, tree.method_that_raises, 'foo')
 
418
        self.assertEqual(['t', 'u', 't', 'u'], tree._locks)