~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/per_workingtree/test_workingtree.py

  • Committer: Patch Queue Manager
  • Date: 2016-04-21 04:10:52 UTC
  • mfrom: (6616.1.1 fix-en-user-guide)
  • Revision ID: pqm@pqm.ubuntu.com-20160421041052-clcye7ns1qcl2n7w
(richard-wilbur) Ensure build of English use guide always uses English text
 even when user's locale specifies a different language. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2012, 2016 Canonical Ltd
2
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
3
#           and others
4
4
#
19
19
from cStringIO import StringIO
20
20
import errno
21
21
import os
22
 
import sys
23
22
 
24
23
from bzrlib import (
25
24
    branch,
26
 
    branchbuilder,
27
25
    bzrdir,
 
26
    config,
 
27
    controldir,
28
28
    errors,
29
29
    osutils,
 
30
    revision as _mod_revision,
 
31
    symbol_versioning,
30
32
    tests,
 
33
    trace,
31
34
    urlutils,
32
 
    workingtree,
33
 
    )
34
 
from bzrlib.errors import (NotBranchError, NotVersionedError,
35
 
                           UnsupportedOperation, PathsNotVersionedError)
 
35
    )
 
36
from bzrlib.errors import (
 
37
    UnsupportedOperation,
 
38
    PathsNotVersionedError,
 
39
    )
36
40
from bzrlib.inventory import Inventory
 
41
from bzrlib.mutabletree import MutableTree
37
42
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
38
 
from bzrlib.tests import TestSkipped, TestNotApplicable
 
43
from bzrlib.tests import (
 
44
    features,
 
45
    TestSkipped,
 
46
    TestNotApplicable,
 
47
    )
39
48
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
40
 
from bzrlib.trace import mutter
41
 
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
42
 
                                WorkingTree, WorkingTree2)
 
49
from bzrlib.workingtree import (
 
50
    TreeDirectory,
 
51
    TreeFile,
 
52
    TreeLink,
 
53
    InventoryWorkingTree,
 
54
    WorkingTree,
 
55
    )
43
56
from bzrlib.conflicts import ConflictList, TextConflict, ContentsConflict
44
57
 
45
58
 
46
59
class TestWorkingTree(TestCaseWithWorkingTree):
47
60
 
 
61
    def requireBranchReference(self):
 
62
        test_branch = self.make_branch('test-branch')
 
63
        try:
 
64
            # if there is a working tree now, this is not supported.
 
65
            test_branch.bzrdir.open_workingtree()
 
66
            raise TestNotApplicable("only on trees that can be separate"
 
67
                " from their branch.")
 
68
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
69
            pass
 
70
 
 
71
    def test_branch_builder(self):
 
72
        # Just a smoke test that we get a branch at the specified relpath
 
73
        builder = self.make_branch_builder('foobar')
 
74
        br = branch.Branch.open(self.get_url('foobar'))
 
75
 
48
76
    def test_list_files(self):
49
77
        tree = self.make_branch_and_tree('.')
50
78
        self.build_tree(['dir/', 'file'])
104
132
        self.assertEqual(('filename', 'V', 'directory', 'file-id'),
105
133
                         result[0][:4])
106
134
 
 
135
    def test_get_config_stack(self):
 
136
        # Smoke test that all working trees succeed getting a config
 
137
        wt = self.make_branch_and_tree('.')
 
138
        conf = wt.get_config_stack()
 
139
        self.assertIsInstance(conf, config.Stack)
 
140
 
107
141
    def test_open_containing(self):
108
 
        branch = self.make_branch_and_tree('.').branch
109
 
        local_base = urlutils.local_path_from_url(branch.base)
 
142
        local_wt = self.make_branch_and_tree('.')
 
143
        local_url = local_wt.bzrdir.root_transport.base
 
144
        local_base = urlutils.local_path_from_url(local_url)
 
145
        del local_wt
110
146
 
111
147
        # Empty opens '.'
112
148
        wt, relpath = WorkingTree.open_containing()
144
180
 
145
181
    def test_lock_locks_branch(self):
146
182
        tree = self.make_branch_and_tree('.')
 
183
        self.assertEqual(None, tree.branch.peek_lock_mode())
147
184
        tree.lock_read()
148
185
        self.assertEqual('r', tree.branch.peek_lock_mode())
149
186
        tree.unlock()
158
195
        tree = self.make_branch_and_tree('.')
159
196
 
160
197
        self.build_tree(['hello.txt'])
161
 
        file('hello.txt', 'w').write('initial hello')
 
198
        with file('hello.txt', 'w') as f: f.write('initial hello')
162
199
 
163
200
        self.assertRaises(PathsNotVersionedError,
164
201
                          tree.revert, ['hello.txt'])
166
203
        tree.commit('create initial hello.txt')
167
204
 
168
205
        self.check_file_contents('hello.txt', 'initial hello')
169
 
        file('hello.txt', 'w').write('new hello')
 
206
        with file('hello.txt', 'w') as f: f.write('new hello')
170
207
        self.check_file_contents('hello.txt', 'new hello')
171
208
 
172
209
        # revert file modified since last revision
180
217
        self.check_file_contents('hello.txt.~1~', 'new hello')
181
218
 
182
219
        # backup files are numbered
183
 
        file('hello.txt', 'w').write('new hello2')
 
220
        with file('hello.txt', 'w') as f: f.write('new hello2')
184
221
        tree.revert(['hello.txt'])
185
222
        self.check_file_contents('hello.txt', 'initial hello')
186
223
        self.check_file_contents('hello.txt.~1~', 'new hello')
189
226
    def test_revert_missing(self):
190
227
        # Revert a file that has been deleted since last commit
191
228
        tree = self.make_branch_and_tree('.')
192
 
        file('hello.txt', 'w').write('initial hello')
 
229
        with file('hello.txt', 'w') as f: f.write('initial hello')
193
230
        tree.add('hello.txt')
194
231
        tree.commit('added hello.txt')
195
232
        os.unlink('hello.txt')
196
233
        tree.remove('hello.txt')
197
234
        tree.revert(['hello.txt'])
198
 
        self.failUnlessExists('hello.txt')
 
235
        self.assertPathExists('hello.txt')
199
236
 
200
237
    def test_versioned_files_not_unknown(self):
201
238
        tree = self.make_branch_and_tree('.')
202
239
        self.build_tree(['hello.txt'])
203
240
        tree.add('hello.txt')
204
 
        self.assertEquals(list(tree.unknowns()),
 
241
        self.assertEqual(list(tree.unknowns()),
205
242
                          [])
206
243
 
207
244
    def test_unknowns(self):
210
247
                         'hello.txt.~1~'])
211
248
        self.build_tree_contents([('.bzrignore', '*.~*\n')])
212
249
        tree.add('.bzrignore')
213
 
        self.assertEquals(list(tree.unknowns()),
 
250
        self.assertEqual(list(tree.unknowns()),
214
251
                          ['hello.txt'])
215
252
 
216
253
    def test_initialize(self):
233
270
 
234
271
        wt.commit('create initial state')
235
272
 
236
 
        revid = b.revision_history()[0]
 
273
        revid = b.last_revision()
237
274
        self.log('first revision_id is {%s}' % revid)
238
275
 
239
 
        inv = b.repository.get_inventory(revid)
240
 
        self.log('contents of inventory: %r' % inv.entries())
 
276
        tree = b.repository.revision_tree(revid)
 
277
        self.log('contents of tree: %r' % list(tree.iter_entries_by_dir()))
241
278
 
242
 
        self.check_inventory_shape(inv,
243
 
                                   ['dir/', 'dir/sub/', 'dir/sub/file'])
 
279
        self.check_tree_shape(tree, ['dir/', 'dir/sub/', 'dir/sub/file'])
244
280
        wt.rename_one('dir', 'newdir')
245
281
 
246
282
        wt.lock_read()
247
 
        self.check_inventory_shape(wt.inventory,
 
283
        self.check_tree_shape(wt,
248
284
                                   ['newdir/', 'newdir/sub/', 'newdir/sub/file'])
249
285
        wt.unlock()
250
286
        wt.rename_one('newdir/sub', 'newdir/newsub')
251
287
        wt.lock_read()
252
 
        self.check_inventory_shape(wt.inventory,
253
 
                                   ['newdir/', 'newdir/newsub/',
 
288
        self.check_tree_shape(wt, ['newdir/', 'newdir/newsub/',
254
289
                                    'newdir/newsub/file'])
255
290
        wt.unlock()
256
291
 
264
299
        wt = self.make_branch_and_tree('.')
265
300
        self.build_tree(['foo/',
266
301
                         'foo/hello'])
267
 
        self.assertRaises(NotVersionedError,
268
 
                          wt.add,
269
 
                          'foo/hello')
 
302
        if not wt._format.supports_versioned_directories:
 
303
            wt.add('foo/hello')
 
304
        else:
 
305
            self.assertRaises(NotVersionedError,
 
306
                              wt.add,
 
307
                              'foo/hello')
270
308
 
271
309
    def test_add_missing(self):
272
310
        # adding a msising file -> NoSuchFile
295
333
        cloned = cloned_dir.open_workingtree()
296
334
        self.assertEqual(cloned.get_parent_ids(), wt.get_parent_ids())
297
335
 
 
336
    def test_clone_empty(self):
 
337
        wt = self.make_branch_and_tree('source')
 
338
        cloned_dir = wt.bzrdir.clone('target', revision_id=_mod_revision.NULL_REVISION)
 
339
        cloned = cloned_dir.open_workingtree()
 
340
        self.assertEqual(cloned.get_parent_ids(), wt.get_parent_ids())
 
341
 
298
342
    def test_last_revision(self):
299
343
        wt = self.make_branch_and_tree('source')
300
344
        self.assertEqual([], wt.get_parent_ids())
312
356
        wt.set_last_revision('null:')
313
357
        wt.commit('A', allow_pointless=True, rev_id='A')
314
358
        self.assertEqual(['A'], wt.get_parent_ids())
315
 
        # None is aways in the branch
 
359
        # null: is aways in the branch
316
360
        wt.set_last_revision('null:')
317
361
        self.assertEqual([], wt.get_parent_ids())
318
362
        # and now we can set it to 'A'
319
363
        # because some formats mutate the branch to set it on the tree
320
364
        # we need to alter the branch to let this pass.
321
 
        try:
322
 
            wt.branch.set_revision_history(['A', 'B'])
323
 
        except errors.NoSuchRevision, e:
324
 
            self.assertEqual('B', e.revision)
 
365
        if getattr(wt.branch, "_set_revision_history", None) is None:
325
366
            raise TestSkipped("Branch format does not permit arbitrary"
326
367
                              " history")
 
368
        wt.branch._set_revision_history(['A', 'B'])
327
369
        wt.set_last_revision('A')
328
370
        self.assertEqual(['A'], wt.get_parent_ids())
329
371
        self.assertRaises(errors.ReservedId, wt.set_last_revision, 'A:')
337
379
        # that formats where initialising a branch does not initialise a
338
380
        # tree - and thus have separable entities - support skewing the
339
381
        # two things.
340
 
        branch = self.make_branch('tree')
341
 
        try:
342
 
            # if there is a working tree now, this is not supported.
343
 
            branch.bzrdir.open_workingtree()
344
 
            return
345
 
        except errors.NoWorkingTree:
346
 
            pass
347
 
        wt = branch.bzrdir.create_workingtree()
 
382
        self.requireBranchReference()
 
383
        wt = self.make_branch_and_tree('tree')
348
384
        wt.commit('A', allow_pointless=True, rev_id='A')
349
385
        wt.set_last_revision(None)
350
386
        self.assertEqual([], wt.get_parent_ids())
390
426
        wt.set_parent_ids(['B'])
391
427
        tree = wt.basis_tree()
392
428
        tree.lock_read()
393
 
        self.failUnless(tree.has_filename('bar'))
 
429
        self.assertTrue(tree.has_filename('bar'))
394
430
        tree.unlock()
395
431
        wt.set_parent_ids(['A'])
396
432
        tree = wt.basis_tree()
397
433
        tree.lock_read()
398
 
        self.failUnless(tree.has_filename('foo'))
 
434
        self.assertTrue(tree.has_filename('foo'))
399
435
        tree.unlock()
400
436
 
401
437
    def test_clone_tree_revision(self):
427
463
            revision_id='a')
428
464
        self.assertEqual(['a'], made_tree.get_parent_ids())
429
465
 
 
466
    def test_post_build_tree_hook(self):
 
467
        calls = []
 
468
        def track_post_build_tree(tree):
 
469
            calls.append(tree.last_revision())
 
470
        source = self.make_branch_and_tree('source')
 
471
        source.commit('a', rev_id='a', allow_pointless=True)
 
472
        source.commit('b', rev_id='b', allow_pointless=True)
 
473
        self.build_tree(['new/'])
 
474
        made_control = self.bzrdir_format.initialize('new')
 
475
        source.branch.repository.clone(made_control)
 
476
        source.branch.clone(made_control)
 
477
        MutableTree.hooks.install_named_hook("post_build_tree",
 
478
            track_post_build_tree, "Test")
 
479
        made_tree = self.workingtree_format.initialize(made_control,
 
480
            revision_id='a')
 
481
        self.assertEqual(['a'], calls)
 
482
 
430
483
    def test_update_sets_last_revision(self):
431
484
        # working tree formats from the meta-dir format and newer support
432
485
        # setting the last revision on a tree independently of that on the
436
489
        # that formats where initialising a branch does not initialise a
437
490
        # tree - and thus have separable entities - support skewing the
438
491
        # two things.
439
 
        main_branch = self.make_branch('tree')
440
 
        try:
441
 
            # if there is a working tree now, this is not supported.
442
 
            main_branch.bzrdir.open_workingtree()
443
 
            return
444
 
        except errors.NoWorkingTree:
445
 
            pass
446
 
        wt = main_branch.bzrdir.create_workingtree()
 
492
        self.requireBranchReference()
 
493
        wt = self.make_branch_and_tree('tree')
447
494
        # create an out of date working tree by making a checkout in this
448
495
        # current format
449
496
        self.build_tree(['checkout/', 'tree/file'])
450
497
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
451
 
        branch.BranchReferenceFormat().initialize(checkout,
452
 
            target_branch=main_branch)
 
498
        checkout.set_branch_reference(wt.branch)
453
499
        old_tree = self.workingtree_format.initialize(checkout)
454
500
        # now commit to 'tree'
455
501
        wt.add('file')
456
502
        wt.commit('A', rev_id='A')
457
503
        # and update old_tree
458
504
        self.assertEqual(0, old_tree.update())
459
 
        self.failUnlessExists('checkout/file')
 
505
        self.assertPathExists('checkout/file')
460
506
        self.assertEqual(['A'], old_tree.get_parent_ids())
461
507
 
462
508
    def test_update_sets_root_id(self):
477
523
        wt.commit('A', rev_id='A')
478
524
        # and update checkout
479
525
        self.assertEqual(0, checkout.update())
480
 
        self.failUnlessExists('checkout/file')
 
526
        self.assertPathExists('checkout/file')
481
527
        self.assertEqual(wt.get_root_id(), checkout.get_root_id())
482
528
        self.assertNotEqual(None, wt.get_root_id())
483
529
 
504
550
        # that formats where initialising a branch does not initialise a
505
551
        # tree - and thus have separable entities - support skewing the
506
552
        # two things.
507
 
        main_branch = self.make_branch('tree')
508
 
        try:
509
 
            # if there is a working tree now, this is not supported.
510
 
            main_branch.bzrdir.open_workingtree()
511
 
            return
512
 
        except errors.NoWorkingTree:
513
 
            pass
514
 
        wt = main_branch.bzrdir.create_workingtree()
 
553
        self.requireBranchReference()
 
554
        wt = self.make_branch_and_tree('tree')
515
555
        # create an out of date working tree by making a checkout in this
516
556
        # current format
517
557
        self.build_tree(['checkout/', 'tree/file'])
518
558
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
519
 
        branch.BranchReferenceFormat().initialize(checkout,
520
 
            target_branch=main_branch)
 
559
        checkout.set_branch_reference(wt.branch)
521
560
        old_tree = self.workingtree_format.initialize(checkout)
522
561
        # now commit to 'tree'
523
562
        wt.add('file')
558
597
            a.close()
559
598
        this.revert()
560
599
        self.assertFileEqual('a test\n', 'b1/a')
561
 
        self.failUnlessExists('b1/b.~1~')
562
 
        self.failIfExists('b1/c')
563
 
        self.failIfExists('b1/a.~1~')
564
 
        self.failUnlessExists('b1/d')
 
600
        self.assertPathExists('b1/b.~1~')
 
601
        self.assertPathDoesNotExist('b1/c')
 
602
        self.assertPathDoesNotExist('b1/a.~1~')
 
603
        self.assertPathExists('b1/d')
565
604
 
566
605
    def test_update_updates_bound_branch_no_local_commits(self):
567
606
        # doing an update in a tree updates the branch its bound to too.
605
644
        # which should have pivoted the local tip into a merge
606
645
        self.assertEqual([master_tip, 'bar'], tree.get_parent_ids())
607
646
        # and the local branch history should match the masters now.
608
 
        self.assertEqual(master_tree.branch.revision_history(),
609
 
            tree.branch.revision_history())
 
647
        self.assertEqual(master_tree.branch.last_revision(),
 
648
            tree.branch.last_revision())
610
649
 
611
650
    def test_update_takes_revision_parameter(self):
612
651
        wt = self.make_branch_and_tree('wt')
626
665
        # FIXME: This doesn't really test that it works; also this is not
627
666
        # implementation-independent. mbp 20070226
628
667
        tree = self.make_branch_and_tree('master')
 
668
        if not isinstance(tree, InventoryWorkingTree):
 
669
            raise TestNotApplicable("merge-hashes is specific to bzr "
 
670
                "working trees")
629
671
        tree._transport.put_bytes('merge-hashes', 'asdfasdf')
630
672
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
631
673
 
639
681
            tree.add(['somefile'], ['file-id'])
640
682
            tree.set_merge_modified(d)
641
683
            mm = tree.merge_modified()
642
 
            self.assertEquals(mm, d)
 
684
            self.assertEqual(mm, d)
643
685
        finally:
644
686
            tree.unlock()
645
687
        mm = tree.merge_modified()
646
 
        self.assertEquals(mm, d)
 
688
        self.assertEqual(mm, d)
647
689
 
648
690
    def test_conflicts(self):
649
691
        from bzrlib.tests.test_conflicts import example_conflicts
665
707
    def make_merge_conflicts(self):
666
708
        from bzrlib.merge import merge_inner
667
709
        tree = self.make_branch_and_tree('mine')
668
 
        file('mine/bloo', 'wb').write('one')
669
 
        file('mine/blo', 'wb').write('on')
 
710
        with file('mine/bloo', 'wb') as f: f.write('one')
 
711
        with file('mine/blo', 'wb') as f: f.write('on')
670
712
        tree.add(['bloo', 'blo'])
671
713
        tree.commit("blah", allow_pointless=False)
672
714
        base = tree.branch.repository.revision_tree(tree.last_revision())
673
 
        bzrdir.BzrDir.open("mine").sprout("other")
674
 
        file('other/bloo', 'wb').write('two')
 
715
        controldir.ControlDir.open("mine").sprout("other")
 
716
        with file('other/bloo', 'wb') as f: f.write('two')
675
717
        othertree = WorkingTree.open('other')
676
718
        othertree.commit('blah', allow_pointless=False)
677
 
        file('mine/bloo', 'wb').write('three')
 
719
        with file('mine/bloo', 'wb') as f: f.write('three')
678
720
        tree.commit("blah", allow_pointless=False)
679
721
        merge_inner(tree.branch, othertree, base, this_tree=tree)
680
722
        return tree
730
772
    def test_format_description(self):
731
773
        tree = self.make_branch_and_tree('tree')
732
774
        text = tree._format.get_format_description()
733
 
        self.failUnless(len(text))
 
775
        self.assertTrue(len(text))
734
776
 
735
777
    def test_branch_attribute_is_not_settable(self):
736
778
        # the branch attribute is an aspect of the working tree, not a
767
809
            tree.lock_read()
768
810
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
769
811
                    [(path, ie.kind) for path,ie in
770
 
                                tree.inventory.iter_entries()])
 
812
                                tree.iter_entries_by_dir()])
771
813
            tree.unlock()
772
814
        finally:
773
815
            osutils.normalized_filename = orig
789
831
    def test__write_inventory(self):
790
832
        # The private interface _write_inventory is currently used by transform.
791
833
        tree = self.make_branch_and_tree('.')
 
834
        if not isinstance(tree, InventoryWorkingTree):
 
835
            raise TestNotApplicable("_write_inventory does not exist on "
 
836
                "non-inventory working trees")
792
837
        # if we write write an inventory then do a walkdirs we should get back
793
838
        # missing entries, and actual, and unknowns as appropriate.
794
839
        self.build_tree(['present', 'unknown'])
915
960
        else:
916
961
            case_sensitive = True
917
962
        tree = self.make_branch_and_tree('test')
918
 
        if tree.__class__ == WorkingTree2:
919
 
            raise TestSkipped('WorkingTree2 is not supported')
920
963
        self.assertEqual(case_sensitive, tree.case_sensitive)
 
964
        if not isinstance(tree, InventoryWorkingTree):
 
965
            raise TestNotApplicable("get_format_string is only available "
 
966
                                    "on bzr working trees")
 
967
        # now we cheat, and make a file that matches the case-sensitive name
 
968
        t = tree.bzrdir.get_workingtree_transport(None)
 
969
        try:
 
970
            content = tree._format.get_format_string()
 
971
        except NotImplementedError:
 
972
            # All-in-one formats didn't have a separate format string.
 
973
            content = tree.bzrdir._format.get_format_string()
 
974
        t.put_bytes(tree._format.case_sensitive_filename, content)
 
975
        tree = tree.bzrdir.open_workingtree()
 
976
        self.assertFalse(tree.case_sensitive)
 
977
 
 
978
    def test_supports_executable(self):
 
979
        self.build_tree(['filename'])
 
980
        tree = self.make_branch_and_tree('.')
 
981
        tree.add('filename')
 
982
        self.assertIsInstance(tree._supports_executable(), bool)
 
983
        if tree._supports_executable():
 
984
            tree.lock_read()
 
985
            try:
 
986
                self.assertFalse(tree.is_executable(tree.path2id('filename')))
 
987
            finally:
 
988
                tree.unlock()
 
989
            os.chmod('filename', 0755)
 
990
            self.addCleanup(tree.lock_read().unlock)
 
991
            self.assertTrue(tree.is_executable(tree.path2id('filename')))
 
992
        else:
 
993
            self.addCleanup(tree.lock_read().unlock)
 
994
            self.assertFalse(tree.is_executable(tree.path2id('filename')))
921
995
 
922
996
    def test_all_file_ids_with_missing(self):
923
997
        tree = self.make_branch_and_tree('tree')
969
1043
            4 5-M
970
1044
            |
971
1045
            W
972
 
         """
973
 
        builder = branchbuilder.BranchBuilder(
974
 
            self.get_transport(),
975
 
            format=self.workingtree_format._matchingbzrdir)
 
1046
        """
 
1047
        format = self.workingtree_format.get_controldir_for_branch()
 
1048
        builder = self.make_branch_builder(".", format=format)
976
1049
        builder.start_series()
977
1050
        # mainline
978
1051
        builder.build_snapshot(
1054
1127
        self.assertEqual(0, wt.update(revision='1'))
1055
1128
        self.assertEqual('1', wt.last_revision())
1056
1129
        self.assertEqual(tip, wt.branch.last_revision())
1057
 
        self.failUnlessExists('checkout/file1')
1058
 
        self.failIfExists('checkout/file4')
1059
 
        self.failIfExists('checkout/file5')
 
1130
        self.assertPathExists('checkout/file1')
 
1131
        self.assertPathDoesNotExist('checkout/file4')
 
1132
        self.assertPathDoesNotExist('checkout/file5')
1060
1133
 
1061
1134
 
1062
1135
class TestIllegalPaths(TestCaseWithWorkingTree):
1065
1138
        if osutils.normalizes_filenames():
1066
1139
            # You *can't* create an illegal filename on OSX.
1067
1140
            raise tests.TestNotApplicable('OSX normalizes filenames')
1068
 
        self.requireFeature(tests.UTF8Filesystem)
 
1141
        self.requireFeature(features.UTF8Filesystem)
1069
1142
        # We require a UTF8 filesystem, because otherwise we would need to get
1070
1143
        # tricky to figure out how to create an illegal filename.
1071
1144
        # \xb5 is an illegal path because it should be \xc2\xb5 for UTF-8
1095
1168
 
1096
1169
class TestControlComponent(TestCaseWithWorkingTree):
1097
1170
    """WorkingTree implementations adequately implement ControlComponent."""
1098
 
    
 
1171
 
1099
1172
    def test_urls(self):
1100
1173
        wt = self.make_branch_and_tree('wt')
1101
1174
        self.assertIsInstance(wt.user_url, str)
1104
1177
        # above the control dir but we might need to relax that?
1105
1178
        self.assertEqual(wt.control_url.find(wt.user_url), 0)
1106
1179
        self.assertEqual(wt.control_url, wt.control_transport.base)
 
1180
 
 
1181
 
 
1182
class TestWorthSavingLimit(TestCaseWithWorkingTree):
 
1183
 
 
1184
    def make_wt_with_worth_saving_limit(self):
 
1185
        wt = self.make_branch_and_tree('wt')
 
1186
        if getattr(wt, '_worth_saving_limit', None) is None:
 
1187
            raise tests.TestNotApplicable('no _worth_saving_limit for'
 
1188
                                          ' this tree type')
 
1189
        wt.lock_write()
 
1190
        self.addCleanup(wt.unlock)
 
1191
        return wt
 
1192
 
 
1193
    def test_not_set(self):
 
1194
        # Default should be 10
 
1195
        wt = self.make_wt_with_worth_saving_limit()
 
1196
        self.assertEqual(10, wt._worth_saving_limit())
 
1197
        ds = wt.current_dirstate()
 
1198
        self.assertEqual(10, ds._worth_saving_limit)
 
1199
 
 
1200
    def test_set_in_branch(self):
 
1201
        wt = self.make_wt_with_worth_saving_limit()
 
1202
        conf = wt.get_config_stack()
 
1203
        conf.set('bzr.workingtree.worth_saving_limit', '20')
 
1204
        self.assertEqual(20, wt._worth_saving_limit())
 
1205
        ds = wt.current_dirstate()
 
1206
        self.assertEqual(10, ds._worth_saving_limit)
 
1207
 
 
1208
    def test_invalid(self):
 
1209
        wt = self.make_wt_with_worth_saving_limit()
 
1210
        conf = wt.get_config_stack()
 
1211
        conf.set('bzr.workingtree.worth_saving_limit', 'a')
 
1212
        # If the config entry is invalid, default to 10
 
1213
        warnings = []
 
1214
        def warning(*args):
 
1215
            warnings.append(args[0] % args[1:])
 
1216
        self.overrideAttr(trace, 'warning', warning)
 
1217
        self.assertEqual(10, wt._worth_saving_limit())
 
1218
        self.assertLength(1, warnings)
 
1219
        self.assertEqual('Value "a" is not valid for'
 
1220
                          ' "bzr.workingtree.worth_saving_limit"',
 
1221
                          warnings[0])
 
1222
 
 
1223
 
 
1224
class TestFormatAttributes(TestCaseWithWorkingTree):
 
1225
 
 
1226
    def test_versioned_directories(self):
 
1227
        self.assertSubset(
 
1228
            [self.workingtree_format.supports_versioned_directories],
 
1229
            (True, False))