~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_workingtree.py

  • Committer: Martin Pool
  • Date: 2006-08-10 01:16:16 UTC
  • mto: (1904.1.2 0.9)
  • mto: This revision was merged to the branch mainline in revision 1913.
  • Revision ID: mbp@sourcefrog.net-20060810011616-d74881eba696e746
compare_trees is deprecated in 0.9 not 0.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
from bzrlib.bzrdir import BzrDir
26
26
from bzrlib.errors import NotBranchError, NotVersionedError
27
27
from bzrlib.lockdir import LockDir
28
 
from bzrlib.mutabletree import needs_tree_write_lock
29
28
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
30
 
from bzrlib.symbol_versioning import zero_thirteen
31
 
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
 
29
from bzrlib.tests import TestCaseWithTransport, TestSkipped
32
30
from bzrlib.trace import mutter
33
31
from bzrlib.transport import get_transport
34
 
from bzrlib.workingtree import (
35
 
    TreeEntry,
36
 
    TreeDirectory,
37
 
    TreeFile,
38
 
    TreeLink,
39
 
    WorkingTree,
40
 
    )
 
32
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
 
33
                                WorkingTree)
41
34
 
42
35
class TestTreeDirectory(TestCaseWithTransport):
43
36
 
97
90
    def initialize(self, a_bzrdir, revision_id=None):
98
91
        """Sample branches cannot be created."""
99
92
        t = a_bzrdir.get_workingtree_transport(self)
100
 
        t.put_bytes('format', self.get_format_string())
 
93
        t.put('format', StringIO(self.get_format_string()))
101
94
        return 'A tree'
102
95
 
103
96
    def is_supported(self):
174
167
        t = control.get_workingtree_transport(None)
175
168
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
176
169
                             t.get('format').read())
177
 
        # self.assertContainsRe(t.get('inventory').read(), 
178
 
        #                       '<inventory file_id="[^"]*" format="5">\n'
179
 
        #                       '</inventory>\n',
180
 
        #                      )
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'
185
 
                              '</inventory>\n',
186
 
                             )
 
170
        self.assertEqualDiff('<inventory format="5">\n'
 
171
                             '</inventory>\n',
 
172
                             t.get('inventory').read())
187
173
        self.assertEqualDiff('### bzr hashcache v5\n',
188
174
                             t.get('stat-cache').read())
189
175
        self.assertFalse(t.has('inventory.basis'))
223
209
        control.create_branch()
224
210
        tree = workingtree.WorkingTreeFormat3().initialize(control)
225
211
        tree._control_files._transport.delete("pending-merges")
226
 
        self.assertEqual([], tree.get_parent_ids())
 
212
        self.assertEqual([], tree.pending_merges())
227
213
 
228
214
 
229
215
class TestFormat2WorkingTree(TestCaseWithTransport):
259
245
class TestNonFormatSpecificCode(TestCaseWithTransport):
260
246
    """This class contains tests of workingtree that are not format specific."""
261
247
 
 
248
    
262
249
    def test_gen_file_id(self):
263
 
        file_id = self.applyDeprecated(zero_thirteen, workingtree.gen_file_id,
264
 
                                      'filename')
265
 
        self.assertStartsWith(file_id, 'filename-')
266
 
 
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-')
270
 
        
271
 
 
272
 
class InstrumentedTree(object):
273
 
    """A instrumented tree to check the needs_tree_write_lock decorator."""
274
 
 
275
 
    def __init__(self):
276
 
        self._locks = []
277
 
 
278
 
    def lock_tree_write(self):
279
 
        self._locks.append('t')
280
 
 
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."""
284
 
        return args, kwargs
285
 
 
286
 
    @needs_tree_write_lock
287
 
    def method_that_raises(self):
288
 
        """This method causes an exception when called with parameters.
289
 
        
290
 
        This allows the decorator code to be checked - it should still call
291
 
        unlock.
292
 
        """
293
 
 
294
 
    def unlock(self):
295
 
        self._locks.append('u')
296
 
 
297
 
 
298
 
class TestInstrumentedTree(TestCase):
299
 
 
300
 
    def test_needs_tree_write_lock(self):
301
 
        """@needs_tree_write_lock should be semantically transparent."""
302
 
        tree = InstrumentedTree()
303
 
        self.assertEqual(
304
 
            'method_with_tree_write_lock',
305
 
            tree.method_with_tree_write_lock.__name__)
306
 
        self.assertEqual(
307
 
            "A lock_tree_write decorated method that returns its arguments.",
308
 
            tree.method_with_tree_write_lock.__doc__)
309
 
        args = (1, 2, 3)
310
 
        kwargs = {'a':'b'}
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)
 
250
        gen_file_id = bzrlib.workingtree.gen_file_id
 
251
 
 
252
        # We try to use the filename if possible
 
253
        self.assertStartsWith(gen_file_id('bar'), 'bar-')
 
254
 
 
255
        # but we squash capitalization, and remove non word characters
 
256
        self.assertStartsWith(gen_file_id('Mwoo oof\t m'), 'mwoooofm-')
 
257
 
 
258
        # We also remove leading '.' characters to prevent hidden file-ids
 
259
        self.assertStartsWith(gen_file_id('..gam.py'), 'gam.py-')
 
260
        self.assertStartsWith(gen_file_id('..Mwoo oof\t m'), 'mwoooofm-')
 
261
 
 
262
        # we remove unicode characters, and still don't end up with a 
 
263
        # hidden file id
 
264
        self.assertStartsWith(gen_file_id(u'\xe5\xb5.txt'), 'txt-')
 
265
        
 
266
        # Our current method of generating unique ids adds 33 characters
 
267
        # plus an serial number (log10(N) characters)
 
268
        # to the end of the filename. We now restrict the filename portion to
 
269
        # be <= 20 characters, so the maximum length should now be approx < 60
 
270
 
 
271
        # Test both case squashing and length restriction
 
272
        fid = gen_file_id('A'*50 + '.txt')
 
273
        self.assertStartsWith(fid, 'a'*20 + '-')
 
274
        self.failUnless(len(fid) < 60)
 
275
 
 
276
        # restricting length happens after the other actions, so
 
277
        # we preserve as much as possible
 
278
        fid = gen_file_id('\xe5\xb5..aBcd\tefGhijKLMnop\tqrstuvwxyz')
 
279
        self.assertStartsWith(fid, 'abcdefghijklmnopqrst-')
 
280
        self.failUnless(len(fid) < 60)
 
281
 
 
282
    def test_next_id_suffix(self):
 
283
        bzrlib.workingtree._gen_id_suffix = None
 
284
        bzrlib.workingtree._next_id_suffix()
 
285
        self.assertNotEqual(None, bzrlib.workingtree._gen_id_suffix)
 
286
        bzrlib.workingtree._gen_id_suffix = "foo-"
 
287
        bzrlib.workingtree._gen_id_serial = 1
 
288
        self.assertEqual("foo-2", bzrlib.workingtree._next_id_suffix())
 
289
        self.assertEqual("foo-3", bzrlib.workingtree._next_id_suffix())
 
290
        self.assertEqual("foo-4", bzrlib.workingtree._next_id_suffix())
 
291
        self.assertEqual("foo-5", bzrlib.workingtree._next_id_suffix())
 
292
        self.assertEqual("foo-6", bzrlib.workingtree._next_id_suffix())
 
293
        self.assertEqual("foo-7", bzrlib.workingtree._next_id_suffix())
 
294
        self.assertEqual("foo-8", bzrlib.workingtree._next_id_suffix())
 
295
        self.assertEqual("foo-9", bzrlib.workingtree._next_id_suffix())
 
296
        self.assertEqual("foo-10", bzrlib.workingtree._next_id_suffix())
 
297
 
 
298
    def test__translate_ignore_rule(self):
 
299
        tree = self.make_branch_and_tree('.')
 
300
        # translation should return the regex, the number of groups in it,
 
301
        # and the original rule in a tuple.
 
302
        # there are three sorts of ignore rules:
 
303
        # root only - regex is the rule itself without the leading ./
 
304
        self.assertEqual(
 
305
            "(rootdirrule$)", 
 
306
            tree._translate_ignore_rule("./rootdirrule"))
 
307
        # full path - regex is the rule itself
 
308
        self.assertEqual(
 
309
            "(path\\/to\\/file$)",
 
310
            tree._translate_ignore_rule("path/to/file"))
 
311
        # basename only rule - regex is a rule that ignores everything up
 
312
        # to the last / in the filename
 
313
        self.assertEqual(
 
314
            "((?:.*/)?(?!.*/)basenamerule$)",
 
315
            tree._translate_ignore_rule("basenamerule"))
 
316
 
 
317
    def test__combine_ignore_rules(self):
 
318
        tree = self.make_branch_and_tree('.')
 
319
        # the combined ignore regexs need the outer group indices
 
320
        # placed in a dictionary with the rules that were combined.
 
321
        # an empty set of rules
 
322
        # this is returned as a list of combined regex,rule sets, because
 
323
        # python has a limit of 100 combined regexes.
 
324
        compiled_rules = tree._combine_ignore_rules([])
 
325
        self.assertEqual([], compiled_rules)
 
326
        # one of each type of rule.
 
327
        compiled_rules = tree._combine_ignore_rules(
 
328
            ["rule1", "rule/two", "./three"])[0]
 
329
        # what type *is* the compiled regex to do an isinstance of ?
 
330
        self.assertEqual(3, compiled_rules[0].groups)
 
331
        self.assertEqual(
 
332
            {0:"rule1",1:"rule/two",2:"./three"},
 
333
            compiled_rules[1])
 
334
 
 
335
    def test__combine_ignore_rules_grouping(self):
 
336
        tree = self.make_branch_and_tree('.')
 
337
        # when there are too many rules, the output is split into groups of 100
 
338
        rules = []
 
339
        for index in range(198):
 
340
            rules.append('foo')
 
341
        self.assertEqual(2, len(tree._combine_ignore_rules(rules)))
 
342
 
 
343
    def test__get_ignore_rules_as_regex(self):
 
344
        tree = self.make_branch_and_tree('.')
 
345
        # Setup the default ignore list to be empty
 
346
        ignores._set_user_ignores([])
 
347
 
 
348
        # some plugins (shelf) modifies the DEFAULT_IGNORE list in memory
 
349
        # which causes this test to fail so force the DEFAULT_IGNORE
 
350
        # list to be empty
 
351
        orig_default = bzrlib.DEFAULT_IGNORE
 
352
        # Also make sure the runtime ignore list is empty
 
353
        orig_runtime = ignores._runtime_ignores
 
354
        try:
 
355
            bzrlib.DEFAULT_IGNORE = []
 
356
            ignores._runtime_ignores = set()
 
357
 
 
358
            self.build_tree_contents([('.bzrignore', 'CVS\n.hg\n')])
 
359
            reference_output = tree._combine_ignore_rules(
 
360
                                    set(['CVS', '.hg']))[0]
 
361
            regex_rules = tree._get_ignore_rules_as_regex()[0]
 
362
            self.assertEqual(len(reference_output[1]), regex_rules[0].groups)
 
363
            self.assertEqual(reference_output[1], regex_rules[1])
 
364
        finally:
 
365
            bzrlib.DEFAULT_IGNORE = orig_default
 
366
            ignores._runtime_ignores = orig_runtime