/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
1
# Copyright (C) 2007 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for WorkingTree.paths2ids.
18
19
This API probably needs to be exposed as a tree implementation test, but these
20
initial tests are for the specific cases being refactored from
21
find_ids_across_trees.
22
"""
23
24
from operator import attrgetter
25
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
26
from bzrlib import errors
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
27
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
28
29
30
class TestPaths2Ids(TestCaseWithWorkingTree):
31
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
32
    def assertExpectedIds(self, ids, tree, paths, trees=None,
33
        require_versioned=True):
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
34
        """Run paths2ids for tree, and check the result."""
35
        tree.lock_read()
36
        if trees:
37
            map(apply, map(attrgetter('lock_read'), trees))
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
38
            result = tree.paths2ids(paths, trees,
39
                require_versioned=require_versioned)
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
40
            map(apply, map(attrgetter('unlock'), trees))
41
        else:
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
42
            result = tree.paths2ids(paths,
43
                require_versioned=require_versioned)
2255.2.100 by Robert Collins
Create a paths2ids api to replace find_ids_across_trees, with tests.
44
        self.assertEqual(set(ids), result)
45
        tree.unlock()
46
47
    def test_find_single_root(self):
48
        tree = self.make_branch_and_tree('tree')
49
        self.assertExpectedIds([tree.path2id('')], tree, [''])
50
51
    def test_find_tree_and_clone_roots(self):
52
        tree = self.make_branch_and_tree('tree')
53
        clone = tree.bzrdir.clone('clone').open_workingtree()
54
        clone.lock_tree_write()
55
        clone_root_id = 'new-id'
56
        clone.set_root_id(clone_root_id)
57
        tree_root_id = tree.path2id('')
58
        clone.unlock()
59
        self.assertExpectedIds([tree_root_id, clone_root_id], tree, [''], [clone])
60
61
    def test_find_tree_basis_roots(self):
62
        tree = self.make_branch_and_tree('tree')
63
        tree.commit('basis')
64
        basis = tree.basis_tree()
65
        basis_root_id = basis.path2id('')
66
        tree.lock_tree_write()
67
        tree_root_id = 'new-id'
68
        tree.set_root_id(tree_root_id)
69
        tree.unlock()
70
        self.assertExpectedIds([tree_root_id, basis_root_id], tree, [''], [basis])
71
72
    def test_find_children_of_moved_directories(self):
73
        """Check the basic nasty corner case that path2ids should handle.
74
75
        This is the following situation:
76
        basis: 
77
          / ROOT
78
          /dir dir
79
          /dir/child-moves child-moves
80
          /dir/child-stays child-stays
81
          /dir/child-goes  child-goes
82
83
        current tree:
84
          / ROOT
85
          /child-moves child-moves
86
          /newdir newdir
87
          /newdir/dir  dir
88
          /newdir/dir/child-stays child-stays
89
          /newdir/dir/new-child   new-child
90
91
        In english: we move a directory under a directory that was a sibling,
92
        and at the same time remove, or move out of the directory, some of its
93
        children, and give it a new child previous absent or a sibling.
94
95
        current_tree.path2ids(['newdir'], [basis]) is meant to handle this
96
        correctly: that is it should return the ids:
97
          newdir because it was provided
98
          dir, because its under newdir in current
99
          child-moves because its under dir in old
100
          child-stays either because its under newdir/dir in current, or under dir in old
101
          child-goes because its under dir in old.
102
          new-child because its under dir in new
103
        
104
        Symmetrically, current_tree.path2ids(['dir'], [basis]) is meant to show
105
        new-child, even though its not under the path 'dir' in current, because
106
        its under a path selected by 'dir' in basis:
107
          dir because its selected in basis.
108
          child-moves because its under dir in old
109
          child-stays either because its under newdir/dir in current, or under dir in old
110
          child-goes because its under dir in old.
111
          new-child because its under dir in new.
112
        """
113
        tree = self.make_branch_and_tree('tree')
114
        self.build_tree(
115
            ['tree/dir/', 'tree/dir/child-moves', 'tree/dir/child-stays',
116
             'tree/dir/child-goes'])
117
        tree.add(['dir', 'dir/child-moves', 'dir/child-stays', 'dir/child-goes'],
118
                 ['dir', 'child-moves', 'child-stays', 'child-goes'])
119
        tree.commit('create basis')
120
        basis = tree.basis_tree()
121
        tree.unversion(['child-goes'])
122
        tree.rename_one('dir/child-moves', 'child-moves')
123
        self.build_tree(['tree/newdir/'])
124
        tree.add(['newdir'], ['newdir'])
125
        tree.rename_one('dir/child-stays', 'child-stays')
126
        tree.rename_one('dir', 'newdir/dir')
127
        tree.rename_one('child-stays', 'newdir/dir/child-stays')
128
        self.build_tree(['tree/newdir/dir/new-child'])
129
        tree.add(['newdir/dir/new-child'], ['new-child'])
130
        self.assertExpectedIds(
131
            ['newdir', 'dir', 'child-moves', 'child-stays', 'child-goes',
132
             'new-child'], tree, ['newdir'], [basis])
133
        self.assertExpectedIds(
134
            ['dir', 'child-moves', 'child-stays', 'child-goes', 'new-child'],
135
            tree, ['dir'], [basis])
2255.2.101 by Robert Collins
Finish making Tree.ids2paths support the file_ids_across_trees api.
136
137
    def test_unversioned_one_tree(self):
138
        tree = self.make_branch_and_tree('tree')
139
        self.build_tree(['tree/unversioned'])
140
        self.assertExpectedIds([], tree, ['unversioned'], require_versioned=False)
141
        tree.lock_read()
142
        self.assertRaises(errors.PathsNotVersionedError, tree.paths2ids, ['unversioned'])
143
        tree.unlock()
144
145
    def test_unversioned_multiple_trees(self):
146
        # in this test, the path is unversioned in only one tree, but it should
147
        # still raise an error.
148
        tree = self.make_branch_and_tree('tree')
149
        tree.commit('make basis')
150
        basis = tree.basis_tree()
151
        self.build_tree(['tree/unversioned'])
152
        self.assertExpectedIds([], tree, ['unversioned'], [basis],
153
            require_versioned=False)
154
        tree.lock_read()
155
        basis.lock_read()
156
        self.assertRaises(errors.PathsNotVersionedError, tree.paths2ids,
157
            ['unversioned'], [basis])
158
        self.assertRaises(errors.PathsNotVersionedError, basis.paths2ids,
159
            ['unversioned'], [tree])
160
        basis.unlock()
161
        tree.unlock()