~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testworkingtree.py

  • Committer: Robert Collins
  • Date: 2005-10-06 05:13:21 UTC
  • mfrom: (1393.3.3)
  • Revision ID: robertc@robertcollins.net-20051006051321-88f1053c3bf1ca4a
merge in an adjusted version of Jelmer's empty-log detection patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# (C) 2005 Canonical Ltd
2
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
13
13
#
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
 
 
18
 
from bzrlib import (
19
 
    bzrdir,
20
 
    conflicts,
21
 
    errors,
22
 
    symbol_versioning,
23
 
    transport,
24
 
    workingtree,
25
 
    workingtree_3,
26
 
    workingtree_4,
27
 
    )
28
 
from bzrlib.lockdir import LockDir
29
 
from bzrlib.mutabletree import needs_tree_write_lock
30
 
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
31
 
from bzrlib.workingtree import (
32
 
    TreeEntry,
33
 
    TreeDirectory,
34
 
    TreeFile,
35
 
    TreeLink,
36
 
    )
37
 
 
38
 
 
39
 
class TestTreeDirectory(TestCaseWithTransport):
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
import os
 
19
from bzrlib.branch import Branch
 
20
from bzrlib.selftest import TestCaseInTempDir
 
21
from bzrlib.trace import mutter
 
22
from bzrlib.workingtree import TreeEntry, TreeDirectory, TreeFile, TreeLink
 
23
 
 
24
class TestTreeDirectory(TestCaseInTempDir):
40
25
 
41
26
    def test_kind_character(self):
42
27
        self.assertEqual(TreeDirectory().kind_character(), '/')
43
28
 
44
29
 
45
 
class TestTreeEntry(TestCaseWithTransport):
 
30
class TestTreeEntry(TestCaseInTempDir):
46
31
 
47
32
    def test_kind_character(self):
48
33
        self.assertEqual(TreeEntry().kind_character(), '???')
49
34
 
50
35
 
51
 
class TestTreeFile(TestCaseWithTransport):
 
36
class TestTreeFile(TestCaseInTempDir):
52
37
 
53
38
    def test_kind_character(self):
54
39
        self.assertEqual(TreeFile().kind_character(), '')
55
40
 
56
41
 
57
 
class TestTreeLink(TestCaseWithTransport):
 
42
class TestTreeLink(TestCaseInTempDir):
58
43
 
59
44
    def test_kind_character(self):
60
45
        self.assertEqual(TreeLink().kind_character(), '')
61
46
 
62
47
 
63
 
class TestDefaultFormat(TestCaseWithTransport):
64
 
 
65
 
    def test_get_set_default_format(self):
66
 
        old_format = workingtree.format_registry.get_default()
67
 
        # default is 6
68
 
        self.assertTrue(isinstance(old_format, workingtree_4.WorkingTreeFormat6))
69
 
        workingtree.format_registry.set_default(SampleTreeFormat())
70
 
        try:
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()
75
 
            dir.create_branch()
76
 
            result = dir.create_workingtree()
77
 
            self.assertEqual(result, 'A tree')
78
 
        finally:
79
 
            workingtree.format_registry.set_default(old_format)
80
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
81
 
 
82
 
    def test_get_set_default_format_by_key(self):
83
 
        old_format = workingtree.format_registry.get_default()
84
 
        # default is 6
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())
90
 
        try:
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()
95
 
            dir.create_branch()
96
 
            result = dir.create_workingtree()
97
 
            self.assertEqual(result, 'A tree')
98
 
        finally:
99
 
            workingtree.format_registry.set_default_key(
100
 
                old_format.get_format_string())
101
 
        self.assertEqual(old_format, workingtree.format_registry.get_default())
102
 
 
103
 
    def test_open(self):
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)
109
 
 
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)
121
 
 
122
 
 
123
 
class SampleTreeFormat(workingtree.WorkingTreeFormat):
124
 
    """A sample format
125
 
 
126
 
    this format is initializable, unsupported to aid in testing the
127
 
    open and open_downlevel routines.
128
 
    """
129
 
 
130
 
    def get_format_string(self):
131
 
        """See WorkingTreeFormat.get_format_string()."""
132
 
        return "Sample tree format."
133
 
 
134
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
135
 
                   accelerator_tree=None, hardlink=False):
136
 
        """Sample branches cannot be created."""
137
 
        t = a_bzrdir.get_workingtree_transport(self)
138
 
        t.put_bytes('format', self.get_format_string())
139
 
        return 'A tree'
140
 
 
141
 
    def is_supported(self):
142
 
        return False
143
 
 
144
 
    def open(self, transport, _found=False):
145
 
        return "opened tree."
146
 
 
147
 
 
148
 
class SampleExtraTreeFormat(workingtree.WorkingTreeFormat):
149
 
    """A sample format that does not support use in a metadir.
150
 
 
151
 
    """
152
 
 
153
 
    def get_format_string(self):
154
 
        # Not usable in a metadir, so no format string
155
 
        return None
156
 
 
157
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
158
 
                   accelerator_tree=None, hardlink=False):
159
 
        raise NotImplementedError(self.initialize)
160
 
 
161
 
    def is_supported(self):
162
 
        return False
163
 
 
164
 
    def open(self, transport, _found=False):
165
 
        raise NotImplementedError(self.open)
166
 
 
167
 
 
168
 
class TestWorkingTreeFormat(TestCaseWithTransport):
169
 
    """Tests for the WorkingTreeFormat facility."""
170
 
 
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)
177
 
        transport.mkdir('.')
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))
183
 
 
184
 
    def test_find_format(self):
185
 
        # is the right format object found for a working tree?
186
 
        # create a branch with a few known format objects.
187
 
        self.build_tree(["foo/", "bar/"])
188
 
        def check_format(format, url):
189
 
            dir = format._matchingbzrdir.initialize(url)
190
 
            dir.create_repository()
191
 
            dir.create_branch()
192
 
            format.initialize(dir)
193
 
            t = transport.get_transport(url)
194
 
            found_format = workingtree.WorkingTreeFormat.find_format(dir)
195
 
            self.assertIsInstance(found_format, format.__class__)
196
 
        check_format(workingtree_3.WorkingTreeFormat3(), "bar")
197
 
 
198
 
    def test_find_format_no_tree(self):
199
 
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
200
 
        self.assertRaises(errors.NoWorkingTree,
201
 
                          workingtree.WorkingTreeFormat.find_format,
202
 
                          dir)
203
 
 
204
 
    def test_find_format_unknown_format(self):
205
 
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
206
 
        dir.create_repository()
207
 
        dir.create_branch()
208
 
        SampleTreeFormat().initialize(dir)
209
 
        self.assertRaises(errors.UnknownFormatError,
210
 
                          workingtree.WorkingTreeFormat.find_format,
211
 
                          dir)
212
 
 
213
 
    def test_register_unregister_format(self):
214
 
        format = SampleTreeFormat()
215
 
        # make a control dir
216
 
        dir = bzrdir.BzrDirMetaFormat1().initialize('.')
217
 
        dir.create_repository()
218
 
        dir.create_branch()
219
 
        # make a branch
220
 
        format.initialize(dir)
221
 
        # register a format for it.
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))
227
 
        # which branch.Open will refuse (not supported)
228
 
        self.assertRaises(errors.UnsupportedFormatError, workingtree.WorkingTree.open, '.')
229
 
        # but open_downlevel will work
230
 
        self.assertEqual(format.open(dir), workingtree.WorkingTree.open_downlevel('.'))
231
 
        # unregister the 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))
237
 
 
238
 
 
239
 
class TestWorkingTreeIterEntriesByDir_wSubtrees(TestCaseWithTransport):
240
 
 
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')
247
 
        return tree
248
 
 
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'),
254
 
                          ('file', 'c-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'])])
261
 
 
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()])
270
 
 
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()])
278
 
 
279
 
 
280
 
class TestWorkingTreeFormatRegistry(TestCase):
281
 
 
282
 
    def setUp(self):
283
 
        super(TestWorkingTreeFormatRegistry, self).setUp()
284
 
        self.registry = workingtree.WorkingTreeFormatRegistry()
285
 
 
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.")
292
 
 
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())
298
 
 
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())
304
 
 
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)
312
 
 
313
 
 
314
 
class TestWorkingTreeFormat3(TestCaseWithTransport):
315
 
    """Tests specific to WorkingTreeFormat3."""
316
 
 
317
 
    def test_disk_layout(self):
318
 
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
319
 
        control.create_repository()
320
 
        control.create_branch()
321
 
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
322
 
        # we want:
323
 
        # format 'Bazaar-NG Working Tree format 3'
324
 
        # inventory = blank inventory
325
 
        # pending-merges = ''
326
 
        # stat-cache = ??
327
 
        # no inventory.basis yet
328
 
        t = control.get_workingtree_transport(None)
329
 
        self.assertEqualDiff('Bazaar-NG Working Tree format 3',
330
 
                             t.get('format').read())
331
 
        self.assertEqualDiff(t.get('inventory').read(),
332
 
                              '<inventory format="5">\n'
333
 
                              '</inventory>\n',
334
 
                             )
335
 
        self.assertEqualDiff('### bzr hashcache v5\n',
336
 
                             t.get('stat-cache').read())
337
 
        self.assertFalse(t.has('inventory.basis'))
338
 
        # no last-revision file means 'None' or 'NULLREVISION'
339
 
        self.assertFalse(t.has('last-revision'))
340
 
        # TODO RBC 20060210 do a commit, check the inventory.basis is created
341
 
        # correctly and last-revision file becomes present.
342
 
 
343
 
    def test_uses_lockdir(self):
344
 
        """WorkingTreeFormat3 uses its own LockDir:
345
 
 
346
 
            - lock is a directory
347
 
            - when the WorkingTree is locked, LockDir can see that
348
 
        """
349
 
        t = self.get_transport()
350
 
        url = self.get_url()
351
 
        dir = bzrdir.BzrDirMetaFormat1().initialize(url)
352
 
        repo = dir.create_repository()
353
 
        branch = dir.create_branch()
354
 
        try:
355
 
            tree = workingtree_3.WorkingTreeFormat3().initialize(dir)
356
 
        except errors.NotLocalUrl:
357
 
            raise TestSkipped('Not a local URL')
358
 
        self.assertIsDirectory('.bzr', t)
359
 
        self.assertIsDirectory('.bzr/checkout', t)
360
 
        self.assertIsDirectory('.bzr/checkout/lock', t)
361
 
        our_lock = LockDir(t, '.bzr/checkout/lock')
362
 
        self.assertEquals(our_lock.peek(), None)
363
 
        tree.lock_write()
364
 
        self.assertTrue(our_lock.peek())
365
 
        tree.unlock()
366
 
        self.assertEquals(our_lock.peek(), None)
367
 
 
368
 
    def test_missing_pending_merges(self):
369
 
        control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
370
 
        control.create_repository()
371
 
        control.create_branch()
372
 
        tree = workingtree_3.WorkingTreeFormat3().initialize(control)
373
 
        tree._transport.delete("pending-merges")
374
 
        self.assertEqual([], tree.get_parent_ids())
375
 
 
376
 
 
377
 
class InstrumentedTree(object):
378
 
    """A instrumented tree to check the needs_tree_write_lock decorator."""
379
 
 
380
 
    def __init__(self):
381
 
        self._locks = []
382
 
 
383
 
    def lock_tree_write(self):
384
 
        self._locks.append('t')
385
 
 
386
 
    @needs_tree_write_lock
387
 
    def method_with_tree_write_lock(self, *args, **kwargs):
388
 
        """A lock_tree_write decorated method that returns its arguments."""
389
 
        return args, kwargs
390
 
 
391
 
    @needs_tree_write_lock
392
 
    def method_that_raises(self):
393
 
        """This method causes an exception when called with parameters.
394
 
 
395
 
        This allows the decorator code to be checked - it should still call
396
 
        unlock.
397
 
        """
398
 
 
399
 
    def unlock(self):
400
 
        self._locks.append('u')
401
 
 
402
 
 
403
 
class TestInstrumentedTree(TestCase):
404
 
 
405
 
    def test_needs_tree_write_lock(self):
406
 
        """@needs_tree_write_lock should be semantically transparent."""
407
 
        tree = InstrumentedTree()
408
 
        self.assertEqual(
409
 
            'method_with_tree_write_lock',
410
 
            tree.method_with_tree_write_lock.__name__)
411
 
        self.assertDocstring(
412
 
            "A lock_tree_write decorated method that returns its arguments.",
413
 
            tree.method_with_tree_write_lock)
414
 
        args = (1, 2, 3)
415
 
        kwargs = {'a':'b'}
416
 
        result = tree.method_with_tree_write_lock(1,2,3, a='b')
417
 
        self.assertEqual((args, kwargs), result)
418
 
        self.assertEqual(['t', 'u'], tree._locks)
419
 
        self.assertRaises(TypeError, tree.method_that_raises, 'foo')
420
 
        self.assertEqual(['t', 'u', 't', 'u'], tree._locks)
421
 
 
422
 
 
423
 
class TestRevert(TestCaseWithTransport):
424
 
 
425
 
    def test_revert_conflicts_recursive(self):
426
 
        this_tree = self.make_branch_and_tree('this-tree')
427
 
        self.build_tree_contents([('this-tree/foo/',),
428
 
                                  ('this-tree/foo/bar', 'bar')])
429
 
        this_tree.add(['foo', 'foo/bar'])
430
 
        this_tree.commit('created foo/bar')
431
 
        other_tree = this_tree.bzrdir.sprout('other-tree').open_workingtree()
432
 
        self.build_tree_contents([('other-tree/foo/bar', 'baz')])
433
 
        other_tree.commit('changed bar')
434
 
        self.build_tree_contents([('this-tree/foo/bar', 'qux')])
435
 
        this_tree.commit('changed qux')
436
 
        this_tree.merge_from_branch(other_tree.branch)
437
 
        self.assertEqual(1, len(this_tree.conflicts()))
438
 
        this_tree.revert(['foo'])
439
 
        self.assertEqual(0, len(this_tree.conflicts()))
440
 
 
441
 
 
442
 
class TestAutoResolve(TestCaseWithTransport):
443
 
 
444
 
    def test_auto_resolve(self):
445
 
        base = self.make_branch_and_tree('base')
446
 
        self.build_tree_contents([('base/hello', 'Hello')])
447
 
        base.add('hello', 'hello_id')
448
 
        base.commit('Hello')
449
 
        other = base.bzrdir.sprout('other').open_workingtree()
450
 
        self.build_tree_contents([('other/hello', 'hELLO')])
451
 
        other.commit('Case switch')
452
 
        this = base.bzrdir.sprout('this').open_workingtree()
453
 
        self.assertPathExists('this/hello')
454
 
        self.build_tree_contents([('this/hello', 'Hello World')])
455
 
        this.commit('Add World')
456
 
        this.merge_from_branch(other.branch)
457
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
458
 
                         this.conflicts())
459
 
        this.auto_resolve()
460
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
461
 
                         this.conflicts())
462
 
        self.build_tree_contents([('this/hello', '<<<<<<<')])
463
 
        this.auto_resolve()
464
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
465
 
                         this.conflicts())
466
 
        self.build_tree_contents([('this/hello', '=======')])
467
 
        this.auto_resolve()
468
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
469
 
                         this.conflicts())
470
 
        self.build_tree_contents([('this/hello', '\n>>>>>>>')])
471
 
        remaining, resolved = this.auto_resolve()
472
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
473
 
                         this.conflicts())
474
 
        self.assertEqual([], resolved)
475
 
        self.build_tree_contents([('this/hello', 'hELLO wORLD')])
476
 
        remaining, resolved = this.auto_resolve()
477
 
        self.assertEqual([], this.conflicts())
478
 
        self.assertEqual([conflicts.TextConflict('hello', 'hello_id')],
479
 
                         resolved)
480
 
        self.assertPathDoesNotExist('this/hello.BASE')
481
 
 
482
 
    def test_auto_resolve_dir(self):
483
 
        tree = self.make_branch_and_tree('tree')
484
 
        self.build_tree(['tree/hello/'])
485
 
        tree.add('hello', 'hello-id')
486
 
        file_conflict = conflicts.TextConflict('file', 'hello-id')
487
 
        tree.set_conflicts(conflicts.ConflictList([file_conflict]))
488
 
        tree.auto_resolve()
489
 
 
490
 
 
491
 
class TestFindTrees(TestCaseWithTransport):
492
 
 
493
 
    def test_find_trees(self):
494
 
        self.make_branch_and_tree('foo')
495
 
        self.make_branch_and_tree('foo/bar')
496
 
        # Sticking a tree inside a control dir is heinous, so let's skip it
497
 
        self.make_branch_and_tree('foo/.bzr/baz')
498
 
        self.make_branch('qux')
499
 
        trees = workingtree.WorkingTree.find_trees('.')
500
 
        self.assertEqual(2, len(list(trees)))
 
48
class TestWorkingTree(TestCaseInTempDir):
 
49
 
 
50
    def test_listfiles(self):
 
51
        branch = Branch.initialize('.')
 
52
        os.mkdir('dir')
 
53
        print >> open('file', 'w'), "content"
 
54
        os.symlink('target', 'symlink')
 
55
        tree = branch.working_tree()
 
56
        files = list(tree.list_files())
 
57
        self.assertEqual(files[0], ('dir', '?', 'directory', None, TreeDirectory()))
 
58
        self.assertEqual(files[1], ('file', '?', 'file', None, TreeFile()))
 
59
        self.assertEqual(files[2], ('symlink', '?', 'symlink', None, TreeLink()))