/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1852.15.19 by John Arbash Meinel
[merge] bzr.dev 2255
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
2
# Authors:  Robert Collins <robert.collins@canonical.com>
2255.13.4 by Martin Pool
merge
3
#           and others
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
from cStringIO import StringIO
20
import os
1711.7.19 by John Arbash Meinel
file:// urls look slightly different on win32
21
import sys
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
22
23
import bzrlib
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
24
from bzrlib import branch, bzrdir, errors, osutils, urlutils, workingtree
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
25
from bzrlib.errors import (NotBranchError, NotVersionedError,
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
26
                           UnsupportedOperation, PathsNotVersionedError)
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
27
from bzrlib.inventory import Inventory
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
28
from bzrlib.osutils import pathjoin, getcwd, has_symlinks
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
29
from bzrlib.tests import TestSkipped
30
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
31
from bzrlib.trace import mutter
32
from bzrlib.workingtree import (TreeEntry, TreeDirectory, TreeFile, TreeLink,
33
                                WorkingTree)
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
34
from bzrlib.conflicts import ConflictList, TextConflict, ContentsConflict
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
35
1711.7.19 by John Arbash Meinel
file:// urls look slightly different on win32
36
1711.8.2 by John Arbash Meinel
Test that WorkingTree locks Branch before self, and unlocks self before Branch
37
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
38
class TestWorkingTree(TestCaseWithWorkingTree):
39
1732.1.8 by John Arbash Meinel
Adding a test for list_files
40
    def test_list_files(self):
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
41
        tree = self.make_branch_and_tree('.')
1732.1.8 by John Arbash Meinel
Adding a test for list_files
42
        self.build_tree(['dir/', 'file'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
43
        if has_symlinks():
44
            os.symlink('target', 'symlink')
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
45
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
46
        files = list(tree.list_files())
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
47
        tree.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
48
        self.assertEqual(files[0], ('dir', '?', 'directory', None, TreeDirectory()))
49
        self.assertEqual(files[1], ('file', '?', 'file', None, TreeFile()))
50
        if has_symlinks():
51
            self.assertEqual(files[2], ('symlink', '?', 'symlink', None, TreeLink()))
52
1732.1.8 by John Arbash Meinel
Adding a test for list_files
53
    def test_list_files_sorted(self):
54
        tree = self.make_branch_and_tree('.')
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
55
        self.build_tree(['dir/', 'file', 'dir/file', 'dir/b',
56
                         'dir/subdir/', 'a', 'dir/subfile',
57
                         'zz_dir/', 'zz_dir/subfile'])
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
58
        tree.lock_read()
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
59
        files = [(path, kind) for (path, v, kind, file_id, entry)
60
                               in tree.list_files()]
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
61
        tree.unlock()
1732.1.8 by John Arbash Meinel
Adding a test for list_files
62
        self.assertEqual([
63
            ('a', 'file'),
64
            ('dir', 'directory'),
65
            ('file', 'file'),
1732.1.25 by John Arbash Meinel
Fix list_files test, we don't need to check if children are empty if we fall off the loop.
66
            ('zz_dir', 'directory'),
1732.1.8 by John Arbash Meinel
Adding a test for list_files
67
            ], files)
68
1732.1.25 by John Arbash Meinel
Fix list_files test, we don't need to check if children are empty if we fall off the loop.
69
        tree.add(['dir', 'zz_dir'])
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
70
        tree.lock_read()
1836.1.18 by John Arbash Meinel
Cleaned up the last failing tests. All tests pass again.
71
        files = [(path, kind) for (path, v, kind, file_id, entry)
72
                               in tree.list_files()]
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
73
        tree.unlock()
1732.1.8 by John Arbash Meinel
Adding a test for list_files
74
        self.assertEqual([
75
            ('a', 'file'),
76
            ('dir', 'directory'),
77
            ('dir/b', 'file'),
78
            ('dir/file', 'file'),
79
            ('dir/subdir', 'directory'),
80
            ('dir/subfile', 'file'),
81
            ('file', 'file'),
1732.1.22 by John Arbash Meinel
Bug in list_files if the last entry in a directory is another directory
82
            ('zz_dir', 'directory'),
83
            ('zz_dir/subfile', 'file'),
1732.1.8 by John Arbash Meinel
Adding a test for list_files
84
            ], files)
85
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
86
    def test_open_containing(self):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
87
        branch = self.make_branch_and_tree('.').branch
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
88
        local_base = urlutils.local_path_from_url(branch.base)
89
90
        # Empty opens '.'
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
91
        wt, relpath = WorkingTree.open_containing()
92
        self.assertEqual('', relpath)
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
93
        self.assertEqual(wt.basedir + '/', local_base)
94
95
        # '.' opens this dir
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
96
        wt, relpath = WorkingTree.open_containing(u'.')
97
        self.assertEqual('', relpath)
1711.7.28 by John Arbash Meinel
clean up the WorkingTree.open_containing tests
98
        self.assertEqual(wt.basedir + '/', local_base)
99
100
        # './foo' finds '.' and a relpath of 'foo'
101
        wt, relpath = WorkingTree.open_containing('./foo')
102
        self.assertEqual('foo', relpath)
103
        self.assertEqual(wt.basedir + '/', local_base)
104
105
        # abspath(foo) finds '.' and relpath of 'foo'
106
        wt, relpath = WorkingTree.open_containing('./foo')
107
        wt, relpath = WorkingTree.open_containing(getcwd() + '/foo')
108
        self.assertEqual('foo', relpath)
109
        self.assertEqual(wt.basedir + '/', local_base)
110
111
        # can even be a url: finds '.' and relpath of 'foo'
112
        wt, relpath = WorkingTree.open_containing('./foo')
113
        wt, relpath = WorkingTree.open_containing(
114
                    urlutils.local_path_to_url(getcwd() + '/foo'))
115
        self.assertEqual('foo', relpath)
116
        self.assertEqual(wt.basedir + '/', local_base)
117
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
118
119
    def test_basic_relpath(self):
120
        # for comprehensive relpath tests, see whitebox.py.
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
121
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
122
        self.assertEqual('child',
123
                         tree.relpath(pathjoin(getcwd(), 'child')))
124
125
    def test_lock_locks_branch(self):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
126
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
127
        tree.lock_read()
128
        self.assertEqual('r', tree.branch.peek_lock_mode())
129
        tree.unlock()
130
        self.assertEqual(None, tree.branch.peek_lock_mode())
131
        tree.lock_write()
132
        self.assertEqual('w', tree.branch.peek_lock_mode())
133
        tree.unlock()
134
        self.assertEqual(None, tree.branch.peek_lock_mode())
135
 
136
    def test_revert(self):
137
        """Test selected-file revert"""
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
138
        tree = self.make_branch_and_tree('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
139
140
        self.build_tree(['hello.txt'])
141
        file('hello.txt', 'w').write('initial hello')
142
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
143
        self.assertRaises(PathsNotVersionedError,
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
144
                          tree.revert, ['hello.txt'])
145
        tree.add(['hello.txt'])
146
        tree.commit('create initial hello.txt')
147
148
        self.check_file_contents('hello.txt', 'initial hello')
149
        file('hello.txt', 'w').write('new hello')
150
        self.check_file_contents('hello.txt', 'new hello')
151
152
        # revert file modified since last revision
153
        tree.revert(['hello.txt'])
154
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
155
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
156
157
        # reverting again does not clobber the backup
158
        tree.revert(['hello.txt'])
159
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
160
        self.check_file_contents('hello.txt.~1~', 'new hello')
1534.10.28 by Aaron Bentley
Use numbered backup files
161
        
162
        # backup files are numbered
163
        file('hello.txt', 'w').write('new hello2')
164
        tree.revert(['hello.txt'])
165
        self.check_file_contents('hello.txt', 'initial hello')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
166
        self.check_file_contents('hello.txt.~1~', 'new hello')
167
        self.check_file_contents('hello.txt.~2~', 'new hello2')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
168
1558.12.7 by Aaron Bentley
Fixed revert with missing files
169
    def test_revert_missing(self):
170
        # Revert a file that has been deleted since last commit
171
        tree = self.make_branch_and_tree('.')
172
        file('hello.txt', 'w').write('initial hello')
173
        tree.add('hello.txt')
174
        tree.commit('added hello.txt')
175
        os.unlink('hello.txt')
176
        tree.remove('hello.txt')
177
        tree.revert(['hello.txt'])
178
        self.failUnlessExists('hello.txt')
179
1740.6.1 by Martin Pool
Remove Scratch objects used by doctests
180
    def test_versioned_files_not_unknown(self):
181
        tree = self.make_branch_and_tree('.')
1831.1.1 by Martin Pool
[merge] remove default ignore list & update
182
        self.build_tree(['hello.txt'])
1740.6.1 by Martin Pool
Remove Scratch objects used by doctests
183
        tree.add('hello.txt')
184
        self.assertEquals(list(tree.unknowns()),
185
                          [])
1831.1.1 by Martin Pool
[merge] remove default ignore list & update
186
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
187
    def test_unknowns(self):
188
        tree = self.make_branch_and_tree('.')
189
        self.build_tree(['hello.txt',
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
190
                         'hello.txt.~1~'])
1765.1.1 by Robert Collins
Remove the default ignores list from bzr, lowering the minimum overhead in bzr add.
191
        self.build_tree_contents([('.bzrignore', '*.~*\n')])
192
        tree.add('.bzrignore')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
193
        self.assertEquals(list(tree.unknowns()),
194
                          ['hello.txt'])
195
196
    def test_initialize(self):
197
        # initialize should create a working tree and branch in an existing dir
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
198
        t = self.make_branch_and_tree('.')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
199
        b = branch.Branch.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
200
        self.assertEqual(t.branch.base, b.base)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
201
        t2 = WorkingTree.open('.')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
202
        self.assertEqual(t.basedir, t2.basedir)
203
        self.assertEqual(b.base, t2.branch.base)
204
        # TODO maybe we should check the branch format? not sure if its
205
        # appropriate here.
206
207
    def test_rename_dirs(self):
208
        """Test renaming directories and the files within them."""
209
        wt = self.make_branch_and_tree('.')
210
        b = wt.branch
211
        self.build_tree(['dir/', 'dir/sub/', 'dir/sub/file'])
212
        wt.add(['dir', 'dir/sub', 'dir/sub/file'])
213
214
        wt.commit('create initial state')
215
216
        revid = b.revision_history()[0]
217
        self.log('first revision_id is {%s}' % revid)
218
        
219
        inv = b.repository.get_revision_inventory(revid)
220
        self.log('contents of inventory: %r' % inv.entries())
221
222
        self.check_inventory_shape(inv,
223
                                   ['dir', 'dir/sub', 'dir/sub/file'])
224
        wt.rename_one('dir', 'newdir')
225
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
226
        wt.lock_read()
227
        self.check_inventory_shape(wt.inventory,
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
228
                                   ['newdir', 'newdir/sub', 'newdir/sub/file'])
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
229
        wt.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
230
        wt.rename_one('newdir/sub', 'newdir/newsub')
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
231
        wt.lock_read()
232
        self.check_inventory_shape(wt.inventory,
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
233
                                   ['newdir', 'newdir/newsub',
234
                                    'newdir/newsub/file'])
2255.2.57 by Robert Collins
Dirstate test change: TestWorkingTree.test_rename_dirs should lock around accessing the trees inventory.
235
        wt.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
236
237
    def test_add_in_unversioned(self):
238
        """Try to add a file in an unversioned directory.
239
240
        "bzr add" adds the parent as necessary, but simple working tree add
241
        doesn't do that.
242
        """
243
        from bzrlib.errors import NotVersionedError
244
        wt = self.make_branch_and_tree('.')
245
        self.build_tree(['foo/',
246
                         'foo/hello'])
247
        self.assertRaises(NotVersionedError,
248
                          wt.add,
249
                          'foo/hello')
250
251
    def test_add_missing(self):
252
        # adding a msising file -> NoSuchFile
253
        wt = self.make_branch_and_tree('.')
254
        self.assertRaises(errors.NoSuchFile, wt.add, 'fpp')
255
256
    def test_remove_verbose(self):
257
        #FIXME the remove api should not print or otherwise depend on the
258
        # text UI - RBC 20060124
259
        wt = self.make_branch_and_tree('.')
260
        self.build_tree(['hello'])
261
        wt.add(['hello'])
262
        wt.commit(message='add hello')
263
        stdout = StringIO()
264
        stderr = StringIO()
265
        self.assertEqual(None, self.apply_redirected(None, stdout, stderr,
266
                                                     wt.remove,
267
                                                     ['hello'],
268
                                                     verbose=True))
269
        self.assertEqual('?       hello\n', stdout.getvalue())
270
        self.assertEqual('', stderr.getvalue())
271
272
    def test_clone_trivial(self):
273
        wt = self.make_branch_and_tree('source')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
274
        cloned_dir = wt.bzrdir.clone('target')
275
        cloned = cloned_dir.open_workingtree()
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
276
        self.assertEqual(cloned.get_parent_ids(), wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
277
278
    def test_last_revision(self):
279
        wt = self.make_branch_and_tree('source')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
280
        self.assertEqual([], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
281
        wt.commit('A', allow_pointless=True, rev_id='A')
2249.5.7 by John Arbash Meinel
Make sure WorkingTree revision_ids are also returned as utf8 strings
282
        parent_ids = wt.get_parent_ids()
283
        self.assertEqual(['A'], parent_ids)
284
        for parent_id in parent_ids:
285
            self.assertIsInstance(parent_id, str)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
286
287
    def test_set_last_revision(self):
288
        wt = self.make_branch_and_tree('source')
1908.1.1 by Robert Collins
Relax WorkingTree.set_last-revision to allow any revision to be set.
289
        # set last-revision to one not in the history
290
        wt.set_last_revision('A')
291
        # set it back to None for an empty tree.
292
        wt.set_last_revision(None)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
293
        wt.commit('A', allow_pointless=True, rev_id='A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
294
        self.assertEqual(['A'], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
295
        # None is aways in the branch
296
        wt.set_last_revision(None)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
297
        self.assertEqual([], wt.get_parent_ids())
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
298
        # and now we can set it to 'A'
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
299
        # because some formats mutate the branch to set it on the tree
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
300
        # we need to alter the branch to let this pass.
2230.3.27 by Aaron Bentley
Skip arbitrary revision-history test for Branch6
301
        try:
302
            wt.branch.set_revision_history(['A', 'B'])
303
        except errors.NoSuchRevision, e:
304
            self.assertEqual('B', e.revision)
305
            raise TestSkipped("Branch format does not permit arbitrary"
306
                              " history")
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
307
        wt.set_last_revision('A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
308
        self.assertEqual(['A'], wt.get_parent_ids())
2229.2.1 by Aaron Bentley
Reject reserved ids in versiondfile, tree, branch and repository
309
        self.assertRaises(errors.ReservedId, wt.set_last_revision, 'A:')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
310
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
311
    def test_set_last_revision_different_to_branch(self):
312
        # working tree formats from the meta-dir format and newer support
313
        # setting the last revision on a tree independently of that on the 
314
        # branch. Its concievable that some future formats may want to 
315
        # couple them again (i.e. because its really a smart server and
316
        # the working tree will always match the branch). So we test
317
        # that formats where initialising a branch does not initialise a 
318
        # tree - and thus have separable entities - support skewing the 
319
        # two things.
320
        branch = self.make_branch('tree')
321
        try:
322
            # if there is a working tree now, this is not supported.
323
            branch.bzrdir.open_workingtree()
324
            return
325
        except errors.NoWorkingTree:
326
            pass
327
        wt = branch.bzrdir.create_workingtree()
328
        wt.commit('A', allow_pointless=True, rev_id='A')
329
        wt.set_last_revision(None)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
330
        self.assertEqual([], wt.get_parent_ids())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
331
        self.assertEqual('A', wt.branch.last_revision())
332
        # and now we can set it back to 'A'
333
        wt.set_last_revision('A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
334
        self.assertEqual(['A'], wt.get_parent_ids())
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
335
        self.assertEqual('A', wt.branch.last_revision())
336
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
337
    def test_clone_and_commit_preserves_last_revision(self):
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
338
        """Doing a commit into a clone tree does not affect the source."""
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
339
        wt = self.make_branch_and_tree('source')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
340
        cloned_dir = wt.bzrdir.clone('target')
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
341
        wt.commit('A', allow_pointless=True, rev_id='A')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
342
        self.assertNotEqual(cloned_dir.open_workingtree().get_parent_ids(),
343
                            wt.get_parent_ids())
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
344
345
    def test_clone_preserves_content(self):
346
        wt = self.make_branch_and_tree('source')
2255.2.51 by John Arbash Meinel
simple rewrap for 79 char lines
347
        self.build_tree(['added', 'deleted', 'notadded'],
348
                        transport=wt.bzrdir.transport.clone('..'))
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
349
        wt.add('deleted', 'deleted')
350
        wt.commit('add deleted')
351
        wt.remove('deleted')
352
        wt.add('added', 'added')
353
        cloned_dir = wt.bzrdir.clone('target')
354
        cloned = cloned_dir.open_workingtree()
355
        cloned_transport = cloned.bzrdir.transport.clone('..')
356
        self.assertFalse(cloned_transport.has('deleted'))
357
        self.assertTrue(cloned_transport.has('added'))
358
        self.assertFalse(cloned_transport.has('notadded'))
359
        self.assertEqual('added', cloned.path2id('added'))
360
        self.assertEqual(None, cloned.path2id('deleted'))
361
        self.assertEqual(None, cloned.path2id('notadded'))
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
362
        
363
    def test_basis_tree_returns_last_revision(self):
364
        wt = self.make_branch_and_tree('.')
365
        self.build_tree(['foo'])
366
        wt.add('foo', 'foo-id')
367
        wt.commit('A', rev_id='A')
368
        wt.rename_one('foo', 'bar')
369
        wt.commit('B', rev_id='B')
1908.6.3 by Robert Collins
Tidy up the last_revision_id and add_pending_merge conversion to use cleaner apis.
370
        wt.set_parent_ids(['B'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
371
        tree = wt.basis_tree()
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
372
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
373
        self.failUnless(tree.has_filename('bar'))
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
374
        tree.unlock()
1908.6.3 by Robert Collins
Tidy up the last_revision_id and add_pending_merge conversion to use cleaner apis.
375
        wt.set_parent_ids(['A'])
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
376
        tree = wt.basis_tree()
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
377
        tree.lock_read()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
378
        self.failUnless(tree.has_filename('foo'))
2255.2.30 by Robert Collins
Some workingtree_implementations/test_workingtree.py test work - add DirStateRevisionTree.has_filename, locks around appropriate calls in tests.
379
        tree.unlock()
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
380
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
381
    def test_clone_tree_revision(self):
382
        # make a tree with a last-revision,
383
        # and clone it with a different last-revision, this should switch
384
        # do it.
385
        #
386
        # also test that the content is merged
387
        # and conflicts recorded.
388
        # This should merge between the trees - local edits should be preserved
389
        # but other changes occured.
390
        # we test this by having one file that does
391
        # not change between two revisions, and another that does -
392
        # if the changed one is not changed, fail,
393
        # if the one that did not change has lost a local change, fail.
394
        # 
395
        raise TestSkipped('revision limiting is not implemented yet.')
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
396
397
    def test_initialize_with_revision_id(self):
398
        # a bzrdir can construct a working tree for itself @ a specific revision.
399
        source = self.make_branch_and_tree('source')
400
        source.commit('a', rev_id='a', allow_pointless=True)
401
        source.commit('b', rev_id='b', allow_pointless=True)
402
        self.build_tree(['new/'])
403
        made_control = self.bzrdir_format.initialize('new')
404
        source.branch.repository.clone(made_control)
405
        source.branch.clone(made_control)
406
        made_tree = self.workingtree_format.initialize(made_control, revision_id='a')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
407
        self.assertEqual(['a'], made_tree.get_parent_ids())
1508.1.23 by Robert Collins
Test that the working tree last revision is indeed set during commit.
408
1508.1.24 by Robert Collins
Add update command for use with checkouts.
409
    def test_update_sets_last_revision(self):
410
        # working tree formats from the meta-dir format and newer support
411
        # setting the last revision on a tree independently of that on the 
412
        # branch. Its concievable that some future formats may want to 
413
        # couple them again (i.e. because its really a smart server and
414
        # the working tree will always match the branch). So we test
415
        # that formats where initialising a branch does not initialise a 
416
        # tree - and thus have separable entities - support skewing the 
417
        # two things.
418
        main_branch = self.make_branch('tree')
419
        try:
420
            # if there is a working tree now, this is not supported.
421
            main_branch.bzrdir.open_workingtree()
422
            return
423
        except errors.NoWorkingTree:
424
            pass
425
        wt = main_branch.bzrdir.create_workingtree()
426
        # create an out of date working tree by making a checkout in this
427
        # current format
428
        self.build_tree(['checkout/', 'tree/file'])
429
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
430
        branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
431
        old_tree = self.workingtree_format.initialize(checkout)
432
        # now commit to 'tree'
433
        wt.add('file')
434
        wt.commit('A', rev_id='A')
435
        # and update old_tree
436
        self.assertEqual(0, old_tree.update())
437
        self.failUnlessExists('checkout/file')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
438
        self.assertEqual(['A'], old_tree.get_parent_ids())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
439
1731.1.33 by Aaron Bentley
Revert no-special-root changes
440
    def test_update_sets_root_id(self):
441
        """Ensure tree root is set properly by update.
442
        
443
        Since empty trees don't have root_ids, but workingtrees do,
444
        an update of a checkout of revision 0 to a new revision,  should set
445
        the root id.
446
        """
447
        wt = self.make_branch_and_tree('tree')
448
        main_branch = wt.branch
449
        # create an out of date working tree by making a checkout in this
450
        # current format
451
        self.build_tree(['checkout/', 'tree/file'])
1731.1.43 by Aaron Bentley
Merge more checkout changes
452
        checkout = main_branch.create_checkout('checkout')
1731.1.33 by Aaron Bentley
Revert no-special-root changes
453
        # now commit to 'tree'
454
        wt.add('file')
455
        wt.commit('A', rev_id='A')
456
        # and update checkout 
457
        self.assertEqual(0, checkout.update())
458
        self.failUnlessExists('checkout/file')
459
        self.assertEqual(wt.get_root_id(), checkout.get_root_id())
460
        self.assertNotEqual(None, wt.get_root_id())
461
1508.1.24 by Robert Collins
Add update command for use with checkouts.
462
    def test_update_returns_conflict_count(self):
463
        # working tree formats from the meta-dir format and newer support
464
        # setting the last revision on a tree independently of that on the 
465
        # branch. Its concievable that some future formats may want to 
466
        # couple them again (i.e. because its really a smart server and
467
        # the working tree will always match the branch). So we test
468
        # that formats where initialising a branch does not initialise a 
469
        # tree - and thus have separable entities - support skewing the 
470
        # two things.
471
        main_branch = self.make_branch('tree')
472
        try:
473
            # if there is a working tree now, this is not supported.
474
            main_branch.bzrdir.open_workingtree()
475
            return
476
        except errors.NoWorkingTree:
477
            pass
478
        wt = main_branch.bzrdir.create_workingtree()
479
        # create an out of date working tree by making a checkout in this
480
        # current format
481
        self.build_tree(['checkout/', 'tree/file'])
482
        checkout = bzrdir.BzrDirMetaFormat1().initialize('checkout')
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
483
        branch.BranchReferenceFormat().initialize(checkout, main_branch)
1508.1.24 by Robert Collins
Add update command for use with checkouts.
484
        old_tree = self.workingtree_format.initialize(checkout)
485
        # now commit to 'tree'
486
        wt.add('file')
487
        wt.commit('A', rev_id='A')
488
        # and add a file file to the checkout
489
        self.build_tree(['checkout/file'])
490
        old_tree.add('file')
491
        # and update old_tree
492
        self.assertEqual(1, old_tree.update())
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
493
        self.assertEqual(['A'], old_tree.get_parent_ids())
1508.1.24 by Robert Collins
Add update command for use with checkouts.
494
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
495
    def test_merge_revert(self):
496
        from bzrlib.merge import merge_inner
497
        this = self.make_branch_and_tree('b1')
498
        open('b1/a', 'wb').write('a test\n')
499
        this.add('a')
500
        open('b1/b', 'wb').write('b test\n')
501
        this.add('b')
502
        this.commit(message='')
503
        base = this.bzrdir.clone('b2').open_workingtree()
504
        open('b2/a', 'wb').write('b test\n')
505
        other = this.bzrdir.clone('b3').open_workingtree()
506
        open('b3/a', 'wb').write('c test\n')
507
        open('b3/c', 'wb').write('c test\n')
508
        other.add('c')
509
510
        open('b1/b', 'wb').write('q test\n')
511
        open('b1/d', 'wb').write('d test\n')
512
        merge_inner(this.branch, other, base, this_tree=this)
513
        self.assertNotEqual(open('b1/a', 'rb').read(), 'a test\n')
514
        this.revert([])
515
        self.assertEqual(open('b1/a', 'rb').read(), 'a test\n')
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
516
        self.assertIs(os.path.exists('b1/b.~1~'), True)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
517
        self.assertIs(os.path.exists('b1/c'), False)
1534.10.29 by Aaron Bentley
Fixed backup numbering to match GNU standard better
518
        self.assertIs(os.path.exists('b1/a.~1~'), False)
1534.7.199 by Aaron Bentley
Moved merge/revert tests into test_workingtree.py
519
        self.assertIs(os.path.exists('b1/d'), True)
1534.7.200 by Aaron Bentley
Merge from mainline
520
1587.1.10 by Robert Collins
update updates working tree and branch together.
521
    def test_update_updates_bound_branch_no_local_commits(self):
522
        # doing an update in a tree updates the branch its bound to too.
523
        master_tree = self.make_branch_and_tree('master')
524
        tree = self.make_branch_and_tree('tree')
525
        try:
526
            tree.branch.bind(master_tree.branch)
527
        except errors.UpgradeRequired:
528
            # legacy branches cannot bind
529
            return
530
        master_tree.commit('foo', rev_id='foo', allow_pointless=True)
531
        tree.update()
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
532
        self.assertEqual(['foo'], tree.get_parent_ids())
1587.1.10 by Robert Collins
update updates working tree and branch together.
533
        self.assertEqual('foo', tree.branch.last_revision())
1587.1.11 by Robert Collins
Local commits appear to be working properly.
534
535
    def test_update_turns_local_commit_into_merge(self):
536
        # doing an update with a few local commits and no master commits
1587.1.13 by Robert Collins
Explain why update pivots more clearly in the relevant test.
537
        # makes pending-merges. 
538
        # this is done so that 'bzr update; bzr revert' will always produce
539
        # an exact copy of the 'logical branch' - the referenced branch for
540
        # a checkout, and the master for a bound branch.
541
        # its possible that we should instead have 'bzr update' when there
542
        # is nothing new on the master leave the current commits intact and
543
        # alter 'revert' to revert to the master always. But for now, its
544
        # good.
1587.1.11 by Robert Collins
Local commits appear to be working properly.
545
        master_tree = self.make_branch_and_tree('master')
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
546
        master_tip = master_tree.commit('first master commit')
1587.1.11 by Robert Collins
Local commits appear to be working properly.
547
        tree = self.make_branch_and_tree('tree')
548
        try:
549
            tree.branch.bind(master_tree.branch)
550
        except errors.UpgradeRequired:
551
            # legacy branches cannot bind
552
            return
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
553
        # sync with master
554
        tree.update()
555
        # work locally
1587.1.11 by Robert Collins
Local commits appear to be working properly.
556
        tree.commit('foo', rev_id='foo', allow_pointless=True, local=True)
557
        tree.commit('bar', rev_id='bar', allow_pointless=True, local=True)
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
558
        # sync with master prepatory to committing
1587.1.11 by Robert Collins
Local commits appear to be working properly.
559
        tree.update()
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
560
        # which should have pivoted the local tip into a merge
561
        self.assertEqual([master_tip, 'bar'], tree.get_parent_ids())
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
562
        # and the local branch history should match the masters now.
563
        self.assertEqual(master_tree.branch.revision_history(),
564
            tree.branch.revision_history())
1587.1.11 by Robert Collins
Local commits appear to be working properly.
565
2255.2.156 by Martin Pool
Merge WorkingTree implementation back from trunk
566
    def test_merge_modified_detects_corruption(self):
567
        # FIXME: This doesn't really test that it works; also this is not
568
        # implementation-independent. mbp 20070226
1558.3.3 by Aaron Bentley
Fix error handling for merge_modified
569
        tree = self.make_branch_and_tree('master')
1955.3.14 by John Arbash Meinel
Correctly fix the workingtree put() test fixes
570
        tree._control_files.put('merge-hashes', StringIO('asdfasdf'))
1558.3.3 by Aaron Bentley
Fix error handling for merge_modified
571
        self.assertRaises(errors.MergeModifiedFormatError, tree.merge_modified)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
572
2298.1.1 by Martin Pool
Add test for merge_modified
573
    def test_merge_modified(self):
574
        # merge_modified stores a map from file id to hash
575
        tree = self.make_branch_and_tree('tree')
576
        d = {'file-id': osutils.sha_string('hello')}
577
        self.build_tree_contents([('tree/somefile', 'hello')])
578
        tree.lock_write()
579
        try:
580
            tree.add(['somefile'], ['file-id'])
581
            tree.set_merge_modified(d)
582
            mm = tree.merge_modified()
583
            self.assertEquals(mm, d)
584
        finally:
585
            tree.unlock()
586
        mm = tree.merge_modified()
587
        self.assertEquals(mm, d)
588
1534.10.22 by Aaron Bentley
Got ConflictList implemented
589
    def test_conflicts(self):
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
590
        from bzrlib.tests.test_conflicts import example_conflicts
591
        tree = self.make_branch_and_tree('master')
592
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
593
            tree.set_conflicts(example_conflicts)
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
594
        except UnsupportedOperation:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
595
            raise TestSkipped('set_conflicts not supported')
1534.10.8 by Aaron Bentley
Implemented conflict_lines in terms of old system on WorkingTree
596
            
597
        tree2 = WorkingTree.open('master')
1534.10.22 by Aaron Bentley
Got ConflictList implemented
598
        self.assertEqual(tree2.conflicts(), example_conflicts)
1955.3.14 by John Arbash Meinel
Correctly fix the workingtree put() test fixes
599
        tree2._control_files.put('conflicts', StringIO(''))
600
        self.assertRaises(errors.ConflictFormatError, 
601
                          tree2.conflicts)
602
        tree2._control_files.put('conflicts', StringIO('a'))
603
        self.assertRaises(errors.ConflictFormatError, 
604
                          tree2.conflicts)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
605
606
    def make_merge_conflicts(self):
2255.2.32 by Robert Collins
Make test_clear_merge_conflicts pass for dirstate. This involved working
607
        from bzrlib.merge import merge_inner
1534.10.12 by Aaron Bentley
Merge produces new conflicts
608
        tree = self.make_branch_and_tree('mine')
609
        file('mine/bloo', 'wb').write('one')
1534.10.14 by Aaron Bentley
Made revert clear conflicts
610
        file('mine/blo', 'wb').write('on')
2255.2.32 by Robert Collins
Make test_clear_merge_conflicts pass for dirstate. This involved working
611
        tree.add(['bloo', 'blo'])
1534.10.12 by Aaron Bentley
Merge produces new conflicts
612
        tree.commit("blah", allow_pointless=False)
2255.5.3 by John Arbash Meinel
XXX Workaround the DirStateRevisionTree bug until we get a proper fix, tests pass again
613
        base = tree.branch.repository.revision_tree(tree.last_revision())
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
614
        bzrdir.BzrDir.open("mine").sprout("other")
1534.10.12 by Aaron Bentley
Merge produces new conflicts
615
        file('other/bloo', 'wb').write('two')
616
        othertree = WorkingTree.open('other')
617
        othertree.commit('blah', allow_pointless=False)
618
        file('mine/bloo', 'wb').write('three')
619
        tree.commit("blah", allow_pointless=False)
620
        merge_inner(tree.branch, othertree, base, this_tree=tree)
621
        return tree
622
623
    def test_merge_conflicts(self):
624
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
625
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
626
627
    def test_clear_merge_conflicts(self):
628
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
629
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
630
        try:
1534.10.22 by Aaron Bentley
Got ConflictList implemented
631
            tree.set_conflicts(ConflictList())
1534.10.12 by Aaron Bentley
Merge produces new conflicts
632
        except UnsupportedOperation:
633
            raise TestSkipped
1534.10.22 by Aaron Bentley
Got ConflictList implemented
634
        self.assertEqual(tree.conflicts(), ConflictList())
1534.10.14 by Aaron Bentley
Made revert clear conflicts
635
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
636
    def test_add_conflicts(self):
637
        tree = self.make_branch_and_tree('tree')
638
        try:
639
            tree.add_conflicts([TextConflict('path_a')])
640
        except UnsupportedOperation:
641
            raise TestSkipped()
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
642
        self.assertEqual(ConflictList([TextConflict('path_a')]),
643
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
644
        tree.add_conflicts([TextConflict('path_a')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
645
        self.assertEqual(ConflictList([TextConflict('path_a')]), 
646
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
647
        tree.add_conflicts([ContentsConflict('path_a')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
648
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
649
                                       TextConflict('path_a')]),
650
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
651
        tree.add_conflicts([TextConflict('path_b')])
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
652
        self.assertEqual(ConflictList([ContentsConflict('path_a'), 
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
653
                                       TextConflict('path_a'),
1551.7.13 by Aaron Bentley
Switched from actual, expected to expected, actual, for John.
654
                                       TextConflict('path_b')]),
655
                         tree.conflicts())
1551.7.11 by Aaron Bentley
Add WorkingTree.add_conflicts
656
1534.10.14 by Aaron Bentley
Made revert clear conflicts
657
    def test_revert_clear_conflicts(self):
658
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
659
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
660
        tree.revert(["blo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
661
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
662
        tree.revert(["bloo"])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
663
        self.assertEqual(len(tree.conflicts()), 0)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
664
665
    def test_revert_clear_conflicts2(self):
666
        tree = self.make_merge_conflicts()
1534.10.22 by Aaron Bentley
Got ConflictList implemented
667
        self.assertEqual(len(tree.conflicts()), 1)
1534.10.14 by Aaron Bentley
Made revert clear conflicts
668
        tree.revert([])
1534.10.22 by Aaron Bentley
Got ConflictList implemented
669
        self.assertEqual(len(tree.conflicts()), 0)
1624.3.22 by Olaf Conradi
Merge bzr.dev
670
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
671
    def test_format_description(self):
672
        tree = self.make_branch_and_tree('tree')
673
        text = tree._format.get_format_description()
674
        self.failUnless(len(text))
1681.1.1 by Robert Collins
Make WorkingTree.branch a read only property. (Robert Collins)
675
676
    def test_branch_attribute_is_not_settable(self):
677
        # the branch attribute is an aspect of the working tree, not a
678
        # configurable attribute
679
        tree = self.make_branch_and_tree('tree')
680
        def set_branch():
681
            tree.branch = tree.branch
682
        self.assertRaises(AttributeError, set_branch)
683
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
684
    def test_list_files_versioned_before_ignored(self):
685
        """A versioned file matching an ignore rule should not be ignored."""
686
        tree = self.make_branch_and_tree('.')
687
        self.build_tree(['foo.pyc'])
688
        # ensure that foo.pyc is ignored
689
        self.build_tree_contents([('.bzrignore', 'foo.pyc')])
690
        tree.add('foo.pyc', 'anid')
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
691
        tree.lock_read()
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
692
        files = sorted(list(tree.list_files()))
2255.2.52 by Robert Collins
Dirstate - fix workingtree.list_files to use the public interface to access the trees inventory.
693
        tree.unlock()
1713.3.1 by Robert Collins
Smoke tests for tree.list_files and bzr ignored when a versioned file matches an ignore rule.
694
        self.assertEqual((u'.bzrignore', '?', 'file', None), files[0][:-1])
695
        self.assertEqual((u'foo.pyc', 'V', 'file', 'anid'), files[1][:-1])
696
        self.assertEqual(2, len(files))
1711.8.2 by John Arbash Meinel
Test that WorkingTree locks Branch before self, and unlocks self before Branch
697
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
698
    def test_non_normalized_add_accessible(self):
699
        try:
700
            self.build_tree([u'a\u030a'])
701
        except UnicodeError:
702
            raise TestSkipped('Filesystem does not support unicode filenames')
703
        tree = self.make_branch_and_tree('.')
704
        orig = osutils.normalized_filename
705
        osutils.normalized_filename = osutils._accessible_normalized_filename
706
        try:
707
            tree.add([u'a\u030a'])
2255.2.58 by Robert Collins
Fix the way we used osutils.normalized_filename in dirstate to support overriding in tests - and document this in the original location it was used.
708
            tree.lock_read()
1907.1.3 by Aaron Bentley
Fixed unicode test cases
709
            self.assertEqual([('', 'directory'), (u'\xe5', 'file')],
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
710
                    [(path, ie.kind) for path,ie in 
711
                                tree.inventory.iter_entries()])
2255.2.58 by Robert Collins
Fix the way we used osutils.normalized_filename in dirstate to support overriding in tests - and document this in the original location it was used.
712
            tree.unlock()
1830.3.7 by John Arbash Meinel
Check that WorkingTree.add does the right thing.
713
        finally:
714
            osutils.normalized_filename = orig
715
716
    def test_non_normalized_add_inaccessible(self):
717
        try:
718
            self.build_tree([u'a\u030a'])
719
        except UnicodeError:
720
            raise TestSkipped('Filesystem does not support unicode filenames')
721
        tree = self.make_branch_and_tree('.')
722
        orig = osutils.normalized_filename
723
        osutils.normalized_filename = osutils._inaccessible_normalized_filename
724
        try:
725
            self.assertRaises(errors.InvalidNormalization,
726
                tree.add, [u'a\u030a'])
727
        finally:
728
            osutils.normalized_filename = orig
2123.3.9 by Steffen Eichenberg
added tests for deprecated API workingtree.move
729
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
730
    def test__write_inventory(self):
731
        # The private interface _write_inventory is currently used by transform.
732
        tree = self.make_branch_and_tree('.')
733
        # if we write write an inventory then do a walkdirs we should get back
734
        # missing entries, and actual, and unknowns as appropriate.
735
        self.build_tree(['present', 'unknown'])
2255.2.28 by Robert Collins
TestWorkingTree.test__write_inventory needs to lock the tree before calling _write_inventory for dirstate.
736
        inventory = Inventory(tree.path2id(''))
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
737
        inventory.add_path('missing', 'file', 'missing-id')
738
        inventory.add_path('present', 'file', 'present-id')
2255.2.28 by Robert Collins
TestWorkingTree.test__write_inventory needs to lock the tree before calling _write_inventory for dirstate.
739
        # there is no point in being able to write an inventory to an unlocked
740
        # tree object - its a low level api not a convenience api.
741
        tree.lock_write()
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
742
        tree._write_inventory(inventory)
2255.2.28 by Robert Collins
TestWorkingTree.test__write_inventory needs to lock the tree before calling _write_inventory for dirstate.
743
        tree.unlock()
1852.15.14 by Robert Collins
test that WorkingTree._write_inventory works as expected by the current code.
744
        tree.lock_read()
745
        try:
746
            present_stat = os.lstat('present')
747
            unknown_stat = os.lstat('unknown')
748
            expected_results = [
749
                (('', tree.inventory.root.file_id),
750
                 [('missing', 'missing', 'unknown', None, 'missing-id', 'file'),
751
                  ('present', 'present', 'file', present_stat, 'present-id', 'file'),
752
                  ('unknown', 'unknown', 'file', unknown_stat, None, None),
753
                 ]
754
                )]
755
            self.assertEqual(expected_results, list(tree.walkdirs()))
756
        finally:
757
            tree.unlock()
2255.7.56 by Robert Collins
Document behaviour of tree.path2id("path/").
758
759
    def test_path2id(self):
2255.7.62 by Robert Collins
Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
760
        # smoke test for path2id
2255.7.56 by Robert Collins
Document behaviour of tree.path2id("path/").
761
        tree = self.make_branch_and_tree('.')
762
        self.build_tree(['foo'])
763
        tree.add(['foo'], ['foo-id'])
764
        self.assertEqual('foo-id', tree.path2id('foo'))
765
        # the next assertion is for backwards compatability with WorkingTree3,
766
        # though its probably a bad idea, it makes things work. Perhaps
767
        # it should raise a deprecation warning?
768
        self.assertEqual('foo-id', tree.path2id('foo/'))
2255.7.62 by Robert Collins
Update the Tree.filter_unversioned_files docstring to reflect what the existing implementations actually do, and change the WorkingTree4 implementation to match a newly created test for it.
769
770
    def test_filter_unversioned_files(self):
771
        # smoke test for filter_unversioned_files
772
        tree = self.make_branch_and_tree('.')
773
        paths = ['here-and-versioned', 'here-and-not-versioned',
774
            'not-here-and-versioned', 'not-here-and-not-versioned']
775
        tree.add(['here-and-versioned', 'not-here-and-versioned'],
776
            kinds=['file', 'file'])
777
        self.build_tree(['here-and-versioned', 'here-and-not-versioned'])
778
        tree.lock_read()
779
        self.addCleanup(tree.unlock)
780
        self.assertEqual(
781
            set(['not-here-and-not-versioned', 'here-and-not-versioned']),
782
            tree.filter_unversioned_files(paths))
2255.2.200 by Martin Pool
Add simple test for WorkingTree.kind
783
784
    def test_detect_real_kind(self):
785
        # working trees report the real kind of the file on disk, not the kind
786
        # they had when they were first added
787
        # create one file of every interesting type
788
        tree = self.make_branch_and_tree('.')
789
        self.build_tree(['file', 'directory/'])
790
        names = ['file', 'directory']
791
        if has_symlinks():
792
            os.symlink('target', 'symlink')
793
            names.append('symlink')
794
        tree.add(names, [n + '-id' for n in names])
795
        if tree.supports_tree_reference():
796
            sub_tree = self.make_branch_and_tree('tree-reference')
797
            sub_tree.set_root_id('tree-reference-id')
798
            sub_tree.commit('message')
799
            names.append('tree-reference')
800
            tree.add_reference(sub_tree)
801
        # now when we first look, we should see everything with the same kind
802
        # with which they were initially added
803
        for n in names:
804
            actual_kind = tree.kind(n + '-id')
805
            self.assertEqual(n, actual_kind)
806
        # move them around so the names no longer correspond to the types
807
        os.rename(names[0], 'tmp')
808
        for i in range(1, len(names)):
809
            os.rename(names[i], names[i-1])
810
        os.rename('tmp', names[-1])
2255.2.202 by Martin Pool
WorkingTree_4.kind should report tree-references if they're
811
        # now look and expect to see the correct types again
812
        for i in range(len(names)):
813
            actual_kind = tree.kind(names[i-1] + '-id')
814
            expected_kind = names[i]
815
            self.assertEqual(expected_kind, actual_kind)