/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2255.2.152 by Martin Pool
(broken) merge aaron's workingtree format changes
1
# Copyright (C) 2006, 2007 Canonical Ltd
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
16
17
"""Tests for the InterTree.compare() function."""
18
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
19
import os
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
20
import shutil
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
21
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
22
from bzrlib import (
23
    errors,
24
    tests,
25
    workingtree_4,
26
    )
2321.3.4 by Alexander Belchenko
test intertree_implementations: skip tests with symlinks on platforms that don't have symlinks support
27
from bzrlib.osutils import file_kind, has_symlinks
3619.4.4 by Robert Collins
Review feedback.
28
from bzrlib.tests import TestNotApplicable
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
29
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
30
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
31
# TODO: test the include_root option.
32
# TODO: test that renaming a directory x->y does not emit a rename for the
33
#       child x/a->y/a.
34
# TODO: test that renaming a directory x-> does not emit a rename for the child
35
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
36
#        -> that is, when the renamed parent is not processed by the function.
37
# TODO: test items are only emitted once when a specific_files list names a dir
38
#       whose parent is now a child.
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
39
# TODO: test specific_files when the target tree has a file and the source a
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
40
#       dir with children, same id and same path.
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
41
# TODO: test comparisons between trees with different root ids. mbp 20070301
2255.2.189 by Martin Pool
Add and fix up basic comparison of subtrees.
42
#
43
# TODO: More comparisons between trees with subtrees in different states.
2255.2.236 by Martin Pool
Review cleanups: mostly updating or removing todo comments.
44
#
45
# TODO: Many tests start out by setting the tree roots ids the same, maybe
46
#       that should just be the default for these tests, by changing
47
#       make_branch_and_tree.  mbp 20070307
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
48
49
class TestCompare(TestCaseWithTwoTrees):
50
51
    def test_compare_empty_trees(self):
52
        tree1 = self.make_branch_and_tree('1')
53
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
54
        tree2.set_root_id(tree1.get_root_id())
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
55
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
56
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
57
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
58
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
59
        self.assertEqual([], d.added)
60
        self.assertEqual([], d.modified)
61
        self.assertEqual([], d.removed)
62
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
63
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
64
65
    def test_empty_to_abc_content(self):
66
        tree1 = self.make_branch_and_tree('1')
67
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
68
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
69
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
70
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
71
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
72
        d = self.intertree_class(tree1, tree2).compare()
73
        self.assertEqual([('a', 'a-id', 'file'),
74
                          ('b', 'b-id', 'directory'),
75
                          ('b/c', 'c-id', 'file'),
76
                         ], d.added)
77
        self.assertEqual([], d.modified)
78
        self.assertEqual([], d.removed)
79
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
80
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
81
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
82
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
83
        # This test depends on the ability for some trees to have a difference
84
        # between a 'versioned present' and 'versioned not present' (aka
85
        # dangling) file. In this test there are two trees each with a separate
86
        # dangling file, and the dangling files should be considered absent for
87
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
88
        tree1 = self.make_branch_and_tree('1')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
89
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
90
        tree2.set_root_id(tree1.get_root_id())
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
91
        self.build_tree(['2/a'])
92
        tree2.add('a')
93
        os.unlink('2/a')
94
        self.build_tree(['1/b'])
95
        tree1.add('b')
96
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
97
        # the conversion to test trees here will leave the trees intact for the
98
        # default intertree, but may perform a commit for other tree types,
99
        # which may reduce the validity of the test. XXX: Think about how to
100
        # address this.
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
101
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
102
        d = self.intertree_class(tree1, tree2).compare()
103
        self.assertEqual([], d.added)
104
        self.assertEqual([], d.modified)
105
        self.assertEqual([], d.removed)
106
        self.assertEqual([], d.renamed)
107
        self.assertEqual([], d.unchanged)
108
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
109
    def test_abc_content_to_empty(self):
110
        tree1 = self.make_branch_and_tree('1')
111
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
112
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
113
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
114
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
115
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
116
        d = self.intertree_class(tree1, tree2).compare()
117
        self.assertEqual([], d.added)
118
        self.assertEqual([], d.modified)
119
        self.assertEqual([('a', 'a-id', 'file'),
120
                          ('b', 'b-id', 'directory'),
121
                          ('b/c', 'c-id', 'file'),
122
                         ], d.removed)
123
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
124
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
125
126
    def test_content_modification(self):
127
        tree1 = self.make_branch_and_tree('1')
128
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
129
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
130
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
131
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
132
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
133
        d = self.intertree_class(tree1, tree2).compare()
134
        self.assertEqual([], d.added)
135
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
136
        self.assertEqual([], d.removed)
137
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
138
        self.assertEqual([], d.unchanged)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
139
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
140
    def test_meta_modification(self):
141
        tree1 = self.make_branch_and_tree('1')
142
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
143
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
144
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
145
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
146
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
147
        d = self.intertree_class(tree1, tree2).compare()
148
        self.assertEqual([], d.added)
149
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
150
        self.assertEqual([], d.removed)
151
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
152
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
153
154
    def test_file_rename(self):
155
        tree1 = self.make_branch_and_tree('1')
156
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
157
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
158
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
159
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
160
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
161
        d = self.intertree_class(tree1, tree2).compare()
162
        self.assertEqual([], d.added)
163
        self.assertEqual([], d.modified)
164
        self.assertEqual([], d.removed)
165
        self.assertEqual([('a', 'd', 'a-id', 'file', False, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
166
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
167
168
    def test_file_rename_and_modification(self):
169
        tree1 = self.make_branch_and_tree('1')
170
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
171
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
172
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
173
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
174
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
175
        d = self.intertree_class(tree1, tree2).compare()
176
        self.assertEqual([], d.added)
177
        self.assertEqual([], d.modified)
178
        self.assertEqual([], d.removed)
179
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
180
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
181
182
    def test_file_rename_and_meta_modification(self):
183
        tree1 = self.make_branch_and_tree('1')
184
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
185
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
186
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
187
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
188
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
189
        d = self.intertree_class(tree1, tree2).compare()
190
        self.assertEqual([], d.added)
191
        self.assertEqual([], d.modified)
192
        self.assertEqual([], d.removed)
193
        self.assertEqual([('b/c', 'e', 'c-id', 'file', False, True)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
194
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
195
196
    def test_empty_to_abc_content_a_only(self):
197
        tree1 = self.make_branch_and_tree('1')
198
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
199
        tree2.set_root_id(tree1.get_root_id())
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
200
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
201
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
202
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
203
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
204
        self.assertEqual([('a', 'a-id', 'file')], d.added)
205
        self.assertEqual([], d.modified)
206
        self.assertEqual([], d.removed)
207
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
208
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
209
210
    def test_empty_to_abc_content_a_and_c_only(self):
211
        tree1 = self.make_branch_and_tree('1')
212
        tree2 = self.make_to_branch_and_tree('2')
213
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
214
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
215
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
216
        d = self.intertree_class(tree1, tree2).compare(
217
            specific_files=['a', 'b/c'])
218
        self.assertEqual(
219
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
220
            d.added)
221
        self.assertEqual([], d.modified)
222
        self.assertEqual([], d.removed)
223
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
224
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
225
226
    def test_empty_to_abc_content_b_only(self):
227
        """Restricting to a dir matches the children of the dir."""
228
        tree1 = self.make_branch_and_tree('1')
229
        tree2 = self.make_to_branch_and_tree('2')
230
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
231
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
232
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
233
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
234
        self.assertEqual(
235
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
236
            d.added)
237
        self.assertEqual([], d.modified)
238
        self.assertEqual([], d.removed)
239
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
240
        self.assertEqual([], d.unchanged)
241
242
    def test_unchanged_with_renames_and_modifications(self):
243
        """want_unchanged should generate a list of unchanged entries."""
244
        tree1 = self.make_branch_and_tree('1')
245
        tree2 = self.make_to_branch_and_tree('2')
246
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
247
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
248
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
249
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
250
        self.assertEqual([], d.added)
251
        self.assertEqual([], d.modified)
252
        self.assertEqual([], d.removed)
253
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
254
        self.assertEqual(
255
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
256
            d.unchanged)
257
258
    def test_extra_trees_finds_ids(self):
259
        """Ask for a delta between two trees with a path present in a third."""
260
        tree1 = self.make_branch_and_tree('1')
261
        tree2 = self.make_to_branch_and_tree('2')
262
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
263
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
264
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
265
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
266
        # the type of tree-3 does not matter - it is used as a lookup, not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
267
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
268
        # the lookup, in merged trees it can be fast-pathed. We probably want
269
        # two tests: one as is, and one with it as a pending merge.
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
270
        tree3 = self.make_branch_and_tree('3')
271
        tree3 = self.get_tree_no_parents_abc_content_6(tree3)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
272
        tree3.lock_read()
273
        self.addCleanup(tree3.unlock)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
274
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
275
        # has c-id at b/c with its exec flag toggled.
276
        # without extra_trees, we should get no modifications from this
277
        # so do one, to be sure the test is valid.
278
        d = self.intertree_class(tree1, tree2).compare(
279
            specific_files=['e'])
280
        self.assertEqual([], d.modified)
281
        # now give it an additional lookup:
282
        d = self.intertree_class(tree1, tree2).compare(
283
            specific_files=['e'], extra_trees=[tree3])
284
        self.assertEqual([], d.added)
285
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
286
        self.assertEqual([], d.removed)
287
        self.assertEqual([], d.renamed)
288
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
289
290
    def test_require_versioned(self):
291
        # this does not quite robustly test, as it is passing in missing paths
292
        # rather than present-but-not-versioned paths. At the moment there is
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
293
        # no mechanism for managing the test trees (which are readonly) to
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
294
        # get present-but-not-versioned files for trees that can do that.
295
        tree1 = self.make_branch_and_tree('1')
296
        tree2 = self.make_to_branch_and_tree('2')
297
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
298
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
299
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
300
        self.assertRaises(errors.PathsNotVersionedError,
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
301
            self.intertree_class(tree1, tree2).compare,
302
            specific_files=['d'],
303
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
304
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
305
    def test_default_ignores_unversioned_files(self):
306
        tree1 = self.make_branch_and_tree('tree1')
307
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
308
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
309
        self.build_tree(['tree1/a', 'tree1/c',
310
                         'tree2/a', 'tree2/b', 'tree2/c'])
311
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
312
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
313
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
314
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
315
        d = self.intertree_class(tree1, tree2).compare()
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
316
        self.assertEqual([], d.added)
317
        self.assertEqual([(u'a', 'a-id', 'file', True, False),
318
            (u'c', 'c-id', 'file', True, False)], d.modified)
319
        self.assertEqual([], d.removed)
320
        self.assertEqual([], d.renamed)
321
        self.assertEqual([], d.unchanged)
322
        self.assertEqual([], d.unversioned)
323
324
    def test_unversioned_paths_in_tree(self):
325
        tree1 = self.make_branch_and_tree('tree1')
326
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
327
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
328
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
329
        if has_symlinks():
330
            os.symlink('target', 'tree2/link')
331
            links_supported = True
332
        else:
333
            links_supported = False
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
334
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
335
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
336
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
337
        self.assertEqual([], d.added)
338
        self.assertEqual([], d.modified)
339
        self.assertEqual([], d.removed)
340
        self.assertEqual([], d.renamed)
341
        self.assertEqual([], d.unchanged)
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
342
        expected_unversioned = [(u'dir', None, 'directory'),
343
                                (u'file', None, 'file')]
344
        if links_supported:
345
            expected_unversioned.append((u'link', None, 'symlink'))
346
        self.assertEqual(expected_unversioned, d.unversioned)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
347
2012.1.1 by Aaron Bentley
Implement change iterator
348
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
349
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
350
    """Test the comparison iterator"""
351
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
352
    def do_iter_changes(self, tree1, tree2, **extra_args):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
353
        """Helper to run iter_changes from tree1 to tree2.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
354
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
355
        :param tree1, tree2:  The source and target trees. These will be locked
356
            automatically.
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
357
        :param **extra_args: Extra args to pass to iter_changes. This is not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
358
            inspected by this test helper.
359
        """
360
        tree1.lock_read()
361
        tree2.lock_read()
362
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
363
            # sort order of output is not strictly defined
364
            return sorted(self.intertree_class(tree1, tree2)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
365
                .iter_changes(**extra_args))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
366
        finally:
367
            tree1.unlock()
368
            tree2.unlock()
369
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
370
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
371
        """Convert the working trees into test trees.
372
373
        Read lock them, and add the unlock to the cleanup.
374
        """
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
375
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
376
        tree1.lock_read()
377
        self.addCleanup(tree1.unlock)
378
        tree2.lock_read()
379
        self.addCleanup(tree2.unlock)
380
        return tree1, tree2
381
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
382
    def make_tree_with_special_names(self):
383
        """Create a tree with filenames chosen to exercise the walk order."""
384
        tree1 = self.make_branch_and_tree('tree1')
385
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
386
        tree2.set_root_id(tree1.get_root_id())
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
387
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
388
        tree2.commit('initial', rev_id='rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
389
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
390
        return (tree1, tree2, paths, path_ids)
391
392
    def make_trees_with_special_names(self):
393
        """Both trees will use the special names.
394
395
        But the contents will differ for each file.
396
        """
397
        tree1 = self.make_branch_and_tree('tree1')
398
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
399
        tree2.set_root_id(tree1.get_root_id())
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
400
        paths, path_ids = self._create_special_names(tree1, 'tree1')
401
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
402
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
403
        return (tree1, tree2, paths, path_ids)
404
405
    def _create_special_names(self, tree, base_path):
406
        """Create a tree with paths that expose differences in sort orders."""
407
        # Each directory will have a single file named 'f' inside
408
        dirs = ['a',
409
                'a-a',
410
                'a/a',
411
                'a/a-a',
412
                'a/a/a',
413
                'a/a/a-a',
414
                'a/a/a/a',
415
                'a/a/a/a-a',
416
                'a/a/a/a/a',
417
               ]
418
        with_slashes = []
419
        paths = []
420
        path_ids = []
421
        for d in dirs:
422
            with_slashes.append(base_path + '/' + d + '/')
423
            with_slashes.append(base_path + '/' + d + '/f')
424
            paths.append(d)
425
            paths.append(d+'/f')
426
            path_ids.append(d.replace('/', '_') + '-id')
427
            path_ids.append(d.replace('/', '_') + '_f-id')
428
        self.build_tree(with_slashes)
429
        tree.add(paths, path_ids)
430
        return paths, path_ids
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
431
2012.1.1 by Aaron Bentley
Implement change iterator
432
    def test_compare_empty_trees(self):
433
        tree1 = self.make_branch_and_tree('1')
434
        tree2 = self.make_to_branch_and_tree('2')
435
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
436
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
437
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3254.1.2 by Aaron Bentley
Fix doiter_changes
438
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
439
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
440
    def added(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
441
        path, entry = self.get_path_entry(tree, file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
442
        return (file_id, (None, path), True, (False, True), (None, entry.parent_id),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
443
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
444
                (None, entry.executable))
445
3363.14.7 by Aaron Bentley
Get more tests passing
446
    @staticmethod
447
    def get_path_entry(tree, file_id):
448
        iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id])
449
        return iterator.next()
450
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
451
    def content_changed(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
452
        path, entry = self.get_path_entry(tree, file_id)
453
        return (file_id, (path, path), True, (True, True),
454
                (entry.parent_id, entry.parent_id),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
455
                (entry.name, entry.name), (entry.kind, entry.kind),
456
                (entry.executable, entry.executable))
457
458
    def kind_changed(self, from_tree, to_tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
459
        from_path, old_entry = self.get_path_entry(from_tree, file_id)
460
        path, new_entry = self.get_path_entry(to_tree, file_id)
461
        return (file_id, (from_path, path), True, (True, True),
462
                (old_entry.parent_id, new_entry.parent_id),
463
                (old_entry.name, new_entry.name),
464
                (old_entry.kind, new_entry.kind),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
465
                (old_entry.executable, new_entry.executable))
466
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
467
    def missing(self, file_id, from_path, to_path, parent_id, kind):
468
        _, from_basename = os.path.split(from_path)
469
        _, to_basename = os.path.split(to_path)
470
        # missing files have both paths, but no kind.
471
        return (file_id, (from_path, to_path), True, (True, True),
472
            (parent_id, parent_id),
473
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
474
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
475
    def deleted(self, tree, file_id):
476
        entry = tree.inventory[file_id]
477
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
478
        return (file_id, (path, None), True, (True, False), (entry.parent_id, None),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
479
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
480
                (entry.executable, None))
481
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
482
    def renamed(self, from_tree, to_tree, file_id, content_changed):
3363.14.8 by Aaron Bentley
Fix more tests
483
        from_path, from_entry = self.get_path_entry(from_tree, file_id)
484
        to_path, to_entry = self.get_path_entry(to_tree, file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
485
        return (file_id, (from_path, to_path), content_changed, (True, True),
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
486
            (from_entry.parent_id, to_entry.parent_id),
487
            (from_entry.name, to_entry.name),
488
            (from_entry.kind, to_entry.kind),
489
            (from_entry.executable, to_entry.executable))
490
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
491
    def unchanged(self, tree, file_id):
3363.14.8 by Aaron Bentley
Fix more tests
492
        path, entry = self.get_path_entry(tree, file_id)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
493
        parent = entry.parent_id
494
        name = entry.name
495
        kind = entry.kind
496
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
497
        return (file_id, (path, path), False, (True, True),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
498
               (parent, parent), (name, name), (kind, kind),
499
               (executable, executable))
500
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
501
    def unversioned(self, tree, path):
502
        """Create an unversioned result."""
503
        _, basename = os.path.split(path)
3363.14.7 by Aaron Bentley
Get more tests passing
504
        kind = tree._comparison_data(None, path)[0]
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
505
        return (None, (None, path), True, (False, False), (None, None),
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
506
                (None, basename), (None, kind),
507
                (None, False))
508
2012.1.1 by Aaron Bentley
Implement change iterator
509
    def test_empty_to_abc_content(self):
510
        tree1 = self.make_branch_and_tree('1')
511
        tree2 = self.make_to_branch_and_tree('2')
512
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
513
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
514
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
515
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
516
            self.added(tree2, 'root-id'),
517
            self.added(tree2, 'a-id'),
518
            self.added(tree2, 'b-id'),
519
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
520
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
521
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
522
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
523
    def test_empty_specific_files(self):
524
        tree1 = self.make_branch_and_tree('1')
525
        tree2 = self.make_to_branch_and_tree('2')
526
        tree1 = self.get_tree_no_parents_no_content(tree1)
527
        tree2 = self.get_tree_no_parents_abc_content(tree2)
528
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
529
        self.assertEqual([],
530
            self.do_iter_changes(tree1, tree2, specific_files=[]))
531
532
    def test_no_specific_files(self):
533
        tree1 = self.make_branch_and_tree('1')
534
        tree2 = self.make_to_branch_and_tree('2')
535
        tree1 = self.get_tree_no_parents_no_content(tree1)
536
        tree2 = self.get_tree_no_parents_abc_content(tree2)
537
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2796.1.2 by Aaron Bentley
Harmonize test_no_specific_files with test_empty_to_abc_content
538
        expected_results = sorted([
539
            self.added(tree2, 'root-id'),
540
            self.added(tree2, 'a-id'),
541
            self.added(tree2, 'b-id'),
542
            self.added(tree2, 'c-id'),
543
            self.deleted(tree1, 'empty-root-id')])
544
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
545
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
546
    def test_empty_to_abc_content_a_only(self):
547
        tree1 = self.make_branch_and_tree('1')
548
        tree2 = self.make_to_branch_and_tree('2')
549
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
550
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
551
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
552
        self.assertEqual(
553
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
554
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
555
556
    def test_abc_content_to_empty_to_abc_content_a_only(self):
557
        tree1 = self.make_branch_and_tree('1')
558
        tree2 = self.make_to_branch_and_tree('2')
559
        tree1 = self.get_tree_no_parents_abc_content(tree1)
560
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
561
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
562
        self.assertEqual(
563
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
564
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
565
566
    def test_empty_to_abc_content_a_and_c_only(self):
567
        tree1 = self.make_branch_and_tree('1')
568
        tree2 = self.make_to_branch_and_tree('2')
569
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
570
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
571
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
572
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
573
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
574
            self.do_iter_changes(tree1, tree2, specific_files=['a', 'b/c']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
575
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
576
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
577
        tree1 = self.make_branch_and_tree('1')
578
        tree2 = self.make_to_branch_and_tree('2')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
579
        tree1 = self.get_tree_no_parents_abc_content(tree1)
580
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
581
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
582
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
583
            entry = tree1.inventory[file_id]
584
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
585
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
586
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
587
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
588
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
589
        expected_results = sorted([
590
            self.added(tree2, 'empty-root-id'),
591
            deleted('root-id'), deleted('a-id'),
592
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
593
        self.assertEqual(
594
            expected_results,
595
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
596
597
    def test_content_modification(self):
598
        tree1 = self.make_branch_and_tree('1')
599
        tree2 = self.make_to_branch_and_tree('2')
600
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
601
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
602
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
603
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
604
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
605
                           (root_id, root_id), ('a', 'a'),
606
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
607
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
608
609
    def test_meta_modification(self):
610
        tree1 = self.make_branch_and_tree('1')
611
        tree2 = self.make_to_branch_and_tree('2')
612
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
613
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
614
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
615
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
616
                           ('b-id', 'b-id'), ('c', 'c'), ('file', 'file'),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
617
                          (False, True))],
618
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
619
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
620
    def test_empty_dir(self):
621
        """an empty dir should not cause glitches to surrounding files."""
622
        tree1 = self.make_branch_and_tree('1')
623
        tree2 = self.make_to_branch_and_tree('2')
624
        tree1 = self.get_tree_no_parents_abc_content(tree1)
625
        tree2 = self.get_tree_no_parents_abc_content(tree2)
626
        # the pathname is chosen to fall between 'a' and 'b'.
627
        self.build_tree(['1/a-empty/', '2/a-empty/'])
628
        tree1.add(['a-empty'], ['a-empty'])
629
        tree2.add(['a-empty'], ['a-empty'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
630
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
631
        expected = []
632
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
633
2012.1.1 by Aaron Bentley
Implement change iterator
634
    def test_file_rename(self):
635
        tree1 = self.make_branch_and_tree('1')
636
        tree2 = self.make_to_branch_and_tree('2')
637
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
638
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
639
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
640
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
641
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
642
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
643
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
644
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
645
646
    def test_file_rename_and_modification(self):
647
        tree1 = self.make_branch_and_tree('1')
648
        tree2 = self.make_to_branch_and_tree('2')
649
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
650
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
651
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
652
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
653
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
654
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
655
                           (False, False))],
656
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
657
658
    def test_file_rename_and_meta_modification(self):
659
        tree1 = self.make_branch_and_tree('1')
660
        tree2 = self.make_to_branch_and_tree('2')
661
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
662
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
663
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
664
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
665
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
666
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
667
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
668
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
669
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
670
    def test_missing_in_target(self):
671
        """Test with the target files versioned but absent from disk."""
672
        tree1 = self.make_branch_and_tree('1')
673
        tree2 = self.make_to_branch_and_tree('2')
674
        tree1 = self.get_tree_no_parents_abc_content(tree1)
675
        tree2 = self.get_tree_no_parents_abc_content(tree2)
676
        os.unlink('2/a')
677
        shutil.rmtree('2/b')
678
        # TODO ? have a symlink here?
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
679
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
680
        self.not_applicable_if_missing_in('a', tree2)
681
        self.not_applicable_if_missing_in('b', tree2)
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
682
        root_id = tree1.path2id('')
683
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
684
            self.missing('a-id', 'a', 'a', root_id, 'file'),
685
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
686
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
687
            ])
688
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
689
690
    def test_missing_and_renamed(self):
691
        tree1 = self.make_branch_and_tree('tree1')
692
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
693
        tree2.set_root_id(tree1.get_root_id())
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
694
        self.build_tree(['tree1/file'])
695
        tree1.add(['file'], ['file-id'])
696
        self.build_tree(['tree2/directory/'])
697
        tree2.add(['directory'], ['file-id'])
698
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
699
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
700
        self.not_applicable_if_missing_in('directory', tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
701
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
702
        root_id = tree1.path2id('')
703
        expected = sorted([
704
            self.missing('file-id', 'file', 'directory', root_id, 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
705
            ])
706
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
707
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
708
    def test_only_in_source_and_missing(self):
709
        tree1 = self.make_branch_and_tree('tree1')
710
        tree2 = self.make_to_branch_and_tree('tree2')
711
        tree2.set_root_id(tree1.get_root_id())
712
        self.build_tree(['tree1/file'])
713
        tree1.add(['file'], ['file-id'])
714
        os.unlink('tree1/file')
715
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
716
        self.not_applicable_if_missing_in('file', tree1)
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
717
        root_id = tree1.path2id('')
718
        expected = [('file-id', ('file', None), False, (True, False),
719
            (root_id, None), ('file', None), (None, None), (False, None))]
720
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
721
722
    def test_only_in_target_and_missing(self):
723
        tree1 = self.make_branch_and_tree('tree1')
724
        tree2 = self.make_to_branch_and_tree('tree2')
725
        tree2.set_root_id(tree1.get_root_id())
726
        self.build_tree(['tree2/file'])
727
        tree2.add(['file'], ['file-id'])
728
        os.unlink('tree2/file')
729
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
730
        self.not_applicable_if_missing_in('file', tree2)
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
731
        root_id = tree1.path2id('')
732
        expected = [('file-id', (None, 'file'), False, (False, True),
733
            (None, root_id), (None, 'file'), (None, None), (None, False))]
734
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
735
2012.1.1 by Aaron Bentley
Implement change iterator
736
    def test_unchanged_with_renames_and_modifications(self):
737
        """want_unchanged should generate a list of unchanged entries."""
738
        tree1 = self.make_branch_and_tree('1')
739
        tree2 = self.make_to_branch_and_tree('2')
740
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
741
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
742
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
743
        root_id = tree1.path2id('')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
744
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
745
        self.assertEqual(sorted([self.unchanged(tree1, root_id),
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
746
            self.unchanged(tree1, 'b-id'),
747
            ('a-id', ('a', 'd'), True, (True, True),
748
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
749
            (False, False)), self.unchanged(tree1, 'c-id')]),
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
750
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
751
752
    def test_compare_subtrees(self):
753
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
754
        if not tree1.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
755
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
756
        tree1.set_root_id('root-id')
757
        subtree1 = self.make_branch_and_tree('1/sub')
758
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
759
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
760
761
        tree2 = self.make_to_branch_and_tree('2')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
762
        if not tree2.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
763
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
764
        tree2.set_root_id('root-id')
765
        subtree2 = self.make_to_branch_and_tree('2/sub')
766
        subtree2.set_root_id('subtree-id')
767
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
768
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
769
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
770
        self.assertEqual([], list(tree2.iter_changes(tree1)))
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
771
        subtree1.commit('commit', rev_id='commit-a')
772
        self.assertEqual([
773
            ('root-id',
774
             (u'', u''),
775
             False,
776
             (True, True),
777
             (None, None),
778
             (u'', u''),
779
             ('directory', 'directory'),
780
             (False, False)),
781
            ('subtree-id',
782
             ('sub', 'sub',),
783
             False,
784
             (True, True),
785
             ('root-id', 'root-id'),
786
             ('sub', 'sub'),
787
             ('tree-reference', 'tree-reference'),
788
             (False, False))],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
789
                         list(tree2.iter_changes(tree1,
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
790
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
791
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
792
    def test_disk_in_subtrees_skipped(self):
793
        """subtrees are considered not-in-the-current-tree.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
794
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
795
        This test tests the trivial case, where the basis has no paths in the
796
        current trees subtree.
797
        """
798
        tree1 = self.make_branch_and_tree('1')
799
        tree1.set_root_id('root-id')
800
        tree2 = self.make_to_branch_and_tree('2')
801
        if not tree2.supports_tree_reference():
802
            return
803
        tree2.set_root_id('root-id')
804
        subtree2 = self.make_to_branch_and_tree('2/sub')
805
        subtree2.set_root_id('subtree-id')
4100.2.4 by Aaron Bentley
More support for not autodetecting tree refs
806
        tree2.add_reference(subtree2)
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
807
        self.build_tree(['2/sub/file'])
808
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
809
810
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
811
        # this should filter correctly from above
812
        self.assertEqual([self.added(tree2, 'subtree-id')],
813
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
814
        # and when the path is named
815
        self.assertEqual([self.added(tree2, 'subtree-id')],
816
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
817
                want_unversioned=True))
818
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
819
    def test_default_ignores_unversioned_files(self):
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
820
        tree1 = self.make_branch_and_tree('tree1')
821
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
822
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
823
        self.build_tree(['tree1/a', 'tree1/c',
824
                         'tree2/a', 'tree2/b', 'tree2/c'])
825
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
826
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
827
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
828
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
829
830
        # We should ignore the fact that 'b' exists in tree-2
831
        # because the want_unversioned parameter was not given.
832
        expected = sorted([
833
            self.content_changed(tree2, 'a-id'),
834
            self.content_changed(tree2, 'c-id'),
835
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
836
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
837
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
838
    def test_unversioned_paths_in_tree(self):
839
        tree1 = self.make_branch_and_tree('tree1')
840
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
841
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
842
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
843
        if has_symlinks():
844
            os.symlink('target', 'tree2/link')
845
            links_supported = True
846
        else:
847
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
848
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
849
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
850
        expected = [
851
            self.unversioned(tree2, 'file'),
852
            self.unversioned(tree2, 'dir'),
853
            ]
854
        if links_supported:
855
            expected.append(self.unversioned(tree2, 'link'))
856
        expected = sorted(expected)
857
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
858
            want_unversioned=True))
859
860
    def test_unversioned_paths_in_tree_specific_files(self):
861
        tree1 = self.make_branch_and_tree('tree1')
862
        tree2 = self.make_to_branch_and_tree('tree2')
863
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
864
        if has_symlinks():
865
            os.symlink('target', 'tree2/link')
866
            links_supported = True
867
        else:
868
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
869
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
870
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
871
        expected = [
872
            self.unversioned(tree2, 'file'),
873
            self.unversioned(tree2, 'dir'),
874
            ]
875
        specific_files=['file', 'dir']
876
        if links_supported:
877
            expected.append(self.unversioned(tree2, 'link'))
878
            specific_files.append('link')
879
        expected = sorted(expected)
880
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
881
            specific_files=specific_files, require_versioned=False,
882
            want_unversioned=True))
883
884
    def test_unversioned_paths_in_target_matching_source_old_names(self):
885
        # its likely that naive implementations of unversioned file support
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
886
        # will fail if the path was versioned, but is not any more,
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
887
        # due to a rename, not due to unversioning it.
888
        # That is, if the old tree has a versioned file 'foo', and
889
        # the new tree has the same file but versioned as 'bar', and also
890
        # has an unknown file 'foo', we should get back output for
891
        # both foo and bar.
892
        tree1 = self.make_branch_and_tree('tree1')
893
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
894
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
895
        self.build_tree(['tree2/file', 'tree2/dir/',
896
            'tree1/file', 'tree2/movedfile',
897
            'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
898
        if has_symlinks():
899
            os.symlink('target', 'tree1/link')
900
            os.symlink('target', 'tree2/link')
901
            os.symlink('target', 'tree2/movedlink')
902
            links_supported = True
903
        else:
904
            links_supported = False
905
        tree1.add(['file', 'dir'], ['file-id', 'dir-id'])
906
        tree2.add(['movedfile', 'moveddir'], ['file-id', 'dir-id'])
907
        if links_supported:
908
            tree1.add(['link'], ['link-id'])
909
            tree2.add(['movedlink'], ['link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
910
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
911
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
912
        root_id = tree1.path2id('')
913
        expected = [
914
            self.renamed(tree1, tree2, 'dir-id', False),
915
            self.renamed(tree1, tree2, 'file-id', True),
916
            self.unversioned(tree2, 'file'),
917
            self.unversioned(tree2, 'dir'),
918
            ]
919
        specific_files=['file', 'dir']
920
        if links_supported:
921
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
922
            expected.append(self.unversioned(tree2, 'link'))
923
            specific_files.append('link')
924
        expected = sorted(expected)
925
        # run once with, and once without specific files, to catch
926
        # potentially different code paths.
927
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
928
            require_versioned=False,
929
            want_unversioned=True))
930
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
931
            specific_files=specific_files, require_versioned=False,
932
            want_unversioned=True))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
933
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
934
    def test_similar_filenames(self):
935
        """Test when we have a few files with similar names."""
936
        tree1 = self.make_branch_and_tree('tree1')
937
        tree2 = self.make_branch_and_tree('tree2')
938
        tree2.set_root_id(tree1.get_root_id())
939
940
        # The trees are actually identical, but they happen to contain
941
        # similarly named files.
942
        self.build_tree(['tree1/a/',
943
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
944
                         'tree1/a/b/c/',
945
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
946
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
947
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
948
                         'tree2/a/',
949
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
950
                         'tree2/a/b/c/',
951
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
952
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
953
                         'tree2/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
954
                        ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
955
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
956
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
957
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
958
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
959
960
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
961
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
962
963
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
964
                                                  want_unversioned=True))
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
965
        expected = sorted([
966
            self.unchanged(tree2, tree2.get_root_id()),
967
            self.unchanged(tree2, 'a-id'),
968
            self.unchanged(tree2, 'b-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
969
            self.unchanged(tree2, 'c-id'),
970
            self.unchanged(tree2, 'd-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
971
            self.unchanged(tree2, 'a-c-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
972
            self.unchanged(tree2, 'e-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
973
            ])
974
        self.assertEqual(expected,
975
                         self.do_iter_changes(tree1, tree2,
976
                                              want_unversioned=True,
977
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
978
979
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
980
    def test_unversioned_subtree_only_emits_root(self):
981
        tree1 = self.make_branch_and_tree('tree1')
982
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
983
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
984
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
985
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
986
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
987
        expected = [
988
            self.unversioned(tree2, 'dir'),
989
            ]
990
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
991
            want_unversioned=True))
992
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
993
    def make_trees_with_symlinks(self):
994
        tree1 = self.make_branch_and_tree('tree1')
995
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
996
        tree2.set_root_id(tree1.get_root_id())
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
997
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
998
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
999
        os.symlink('original', 'tree1/changed')
1000
        os.symlink('original', 'tree1/removed')
1001
        os.symlink('original', 'tree1/tofile')
1002
        os.symlink('original', 'tree1/todir')
1003
        # we make the unchanged link point at unknown to catch incorrect
1004
        # symlink-following code in the specified_files test.
1005
        os.symlink('unknown', 'tree1/unchanged')
1006
        os.symlink('new',      'tree2/added')
1007
        os.symlink('new',      'tree2/changed')
1008
        os.symlink('new',      'tree2/fromfile')
1009
        os.symlink('new',      'tree2/fromdir')
1010
        os.symlink('unknown', 'tree2/unchanged')
1011
        from_paths_and_ids = [
1012
            'fromdir',
1013
            'fromfile',
1014
            'changed',
1015
            'removed',
1016
            'todir',
1017
            'tofile',
1018
            'unchanged',
1019
            ]
1020
        to_paths_and_ids = [
1021
            'added',
1022
            'fromdir',
1023
            'fromfile',
1024
            'changed',
1025
            'todir',
1026
            'tofile',
1027
            'unchanged',
1028
            ]
1029
        tree1.add(from_paths_and_ids, from_paths_and_ids)
1030
        tree2.add(to_paths_and_ids, to_paths_and_ids)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1031
        return self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1032
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1033
    def test_versioned_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1034
        self.requireFeature(tests.SymlinkFeature)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1035
        tree1, tree2 = self.make_trees_with_symlinks()
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1036
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1037
        root_id = tree1.path2id('')
1038
        expected = [
1039
            self.unchanged(tree1, tree1.path2id('')),
1040
            self.added(tree2, 'added'),
1041
            self.content_changed(tree2, 'changed'),
1042
            self.kind_changed(tree1, tree2, 'fromdir'),
1043
            self.kind_changed(tree1, tree2, 'fromfile'),
1044
            self.deleted(tree1, 'removed'),
1045
            self.unchanged(tree2, 'unchanged'),
1046
            self.unversioned(tree2, 'unknown'),
1047
            self.kind_changed(tree1, tree2, 'todir'),
1048
            self.kind_changed(tree1, tree2, 'tofile'),
1049
            ]
1050
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1051
        self.assertEqual(expected,
1052
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
1053
                want_unversioned=True))
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1054
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1055
    def test_versioned_symlinks_specific_files(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1056
        self.requireFeature(tests.SymlinkFeature)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
1057
        tree1, tree2 = self.make_trees_with_symlinks()
1058
        root_id = tree1.path2id('')
1059
        expected = [
1060
            self.added(tree2, 'added'),
1061
            self.content_changed(tree2, 'changed'),
1062
            self.kind_changed(tree1, tree2, 'fromdir'),
1063
            self.kind_changed(tree1, tree2, 'fromfile'),
1064
            self.deleted(tree1, 'removed'),
1065
            self.kind_changed(tree1, tree2, 'todir'),
1066
            self.kind_changed(tree1, tree2, 'tofile'),
1067
            ]
1068
        expected = sorted(expected)
1069
        # we should get back just the changed links. We pass in 'unchanged' to
1070
        # make sure that it is correctly not returned - and neither is the
1071
        # unknown path 'unknown' which it points at.
1072
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1073
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
1074
            'removed', 'unchanged', 'todir', 'tofile']))
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1075
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1076
    def test_tree_with_special_names(self):
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1077
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
1078
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1079
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
1080
1081
    def test_trees_with_special_names(self):
1082
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1083
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1084
                          if f_id.endswith('_f-id'))
1085
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
2255.7.34 by John Arbash Meinel
Clean up test_bad_files, and fix a bug in _iter_changes when
1086
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1087
    def test_trees_with_deleted_dir(self):
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1088
        tree1 = self.make_branch_and_tree('tree1')
1089
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
1090
        tree2.set_root_id(tree1.get_root_id())
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1091
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1092
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1093
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1094
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1095
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1096
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1097
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1098
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1099
        # We should notice that 'b' and all its children are deleted
2255.7.35 by John Arbash Meinel
Handle the case when a directory has been removed, and isn't the last entry.
1100
        expected = sorted([
1101
            self.content_changed(tree2, 'a-id'),
1102
            self.content_changed(tree2, 'g-id'),
1103
            self.deleted(tree1, 'b-id'),
1104
            self.deleted(tree1, 'c-id'),
1105
            self.deleted(tree1, 'd-id'),
1106
            self.deleted(tree1, 'e-id'),
1107
            ])
1108
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1109
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1110
    def test_added_unicode(self):
1111
        tree1 = self.make_branch_and_tree('tree1')
1112
        tree2 = self.make_to_branch_and_tree('tree2')
1113
        root_id = tree1.get_root_id()
1114
        tree2.set_root_id(root_id)
1115
1116
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1117
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1118
        a_id = u'\u03b1-id'.encode('utf8')
1119
        added_id = u'\u03c9_added_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1120
        try:
1121
            self.build_tree([u'tree1/\u03b1/',
1122
                             u'tree2/\u03b1/',
1123
                             u'tree2/\u03b1/\u03c9-added',
1124
                            ])
1125
        except UnicodeError:
1126
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1127
        tree1.add([u'\u03b1'], [a_id])
1128
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1129
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1130
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1131
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1132
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1133
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1134
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1135
                         self.do_iter_changes(tree1, tree2,
1136
                                              specific_files=[u'\u03b1']))
1137
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1138
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1139
        tree1 = self.make_branch_and_tree('tree1')
1140
        tree2 = self.make_to_branch_and_tree('tree2')
1141
        root_id = tree1.get_root_id()
1142
        tree2.set_root_id(root_id)
1143
1144
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1145
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1146
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1147
        deleted_id = u'\u03c9_deleted_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1148
        try:
1149
            self.build_tree([u'tree1/\u03b1/',
1150
                             u'tree1/\u03b1/\u03c9-deleted',
1151
                             u'tree2/\u03b1/',
1152
                            ])
1153
        except UnicodeError:
1154
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1155
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-deleted'], [a_id, deleted_id])
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1156
        tree2.add([u'\u03b1'], [a_id])
1157
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1158
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1159
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1160
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1161
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1162
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1163
                         self.do_iter_changes(tree1, tree2,
1164
                                              specific_files=[u'\u03b1']))
1165
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1166
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1167
        tree1 = self.make_branch_and_tree('tree1')
1168
        tree2 = self.make_to_branch_and_tree('tree2')
1169
        root_id = tree1.get_root_id()
1170
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1171
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1172
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1173
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1174
        a_id = u'\u03b1-id'.encode('utf8')
1175
        mod_id = u'\u03c9_mod_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1176
        try:
1177
            self.build_tree([u'tree1/\u03b1/',
1178
                             u'tree1/\u03b1/\u03c9-modified',
1179
                             u'tree2/\u03b1/',
1180
                             u'tree2/\u03b1/\u03c9-modified',
1181
                            ])
1182
        except UnicodeError:
1183
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1184
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1185
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1186
1187
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1188
1189
        self.assertEqual([self.content_changed(tree1, mod_id)],
1190
                         self.do_iter_changes(tree1, tree2))
1191
        self.assertEqual([self.content_changed(tree1, mod_id)],
1192
                         self.do_iter_changes(tree1, tree2,
1193
                                              specific_files=[u'\u03b1']))
1194
1195
    def test_renamed_unicode(self):
1196
        tree1 = self.make_branch_and_tree('tree1')
1197
        tree2 = self.make_to_branch_and_tree('tree2')
1198
        root_id = tree1.get_root_id()
1199
        tree2.set_root_id(root_id)
1200
1201
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1202
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1203
        a_id = u'\u03b1-id'.encode('utf8')
1204
        rename_id = u'\u03c9_rename_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1205
        try:
1206
            self.build_tree([u'tree1/\u03b1/',
1207
                             u'tree2/\u03b1/',
1208
                            ])
1209
        except UnicodeError:
1210
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1211
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1212
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1213
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1214
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1215
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1216
1217
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1218
1219
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1220
                         self.do_iter_changes(tree1, tree2))
1221
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1222
                         self.do_iter_changes(tree1, tree2,
1223
                                              specific_files=[u'\u03b1']))
1224
1225
    def test_unchanged_unicode(self):
1226
        tree1 = self.make_branch_and_tree('tree1')
1227
        tree2 = self.make_to_branch_and_tree('tree2')
1228
        root_id = tree1.get_root_id()
1229
        tree2.set_root_id(root_id)
1230
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1231
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1232
        a_id = u'\u03b1-id'.encode('utf8')
1233
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1234
        rootfile_id = u'\u03c9-root-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1235
        try:
1236
            self.build_tree([u'tree1/\u03b1/',
1237
                             u'tree2/\u03b1/',
1238
                            ])
1239
        except UnicodeError:
1240
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1241
        self.build_tree_contents([
1242
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1243
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1244
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1245
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1246
            ])
1247
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1248
                  [a_id, subfile_id, rootfile_id])
1249
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1250
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1251
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1252
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1253
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1254
        expected = sorted([
1255
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1256
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1257
            self.unchanged(tree1, subfile_id),
1258
            self.unchanged(tree1, rootfile_id),
1259
            ])
1260
        self.assertEqual(expected,
1261
                         self.do_iter_changes(tree1, tree2,
1262
                                              include_unchanged=True))
1263
1264
        # We should also be able to select just a subset
1265
        expected = sorted([
1266
            self.unchanged(tree1, a_id),
1267
            self.unchanged(tree1, subfile_id),
1268
            ])
1269
        self.assertEqual(expected,
1270
                         self.do_iter_changes(tree1, tree2,
1271
                                              specific_files=[u'\u03b1'],
1272
                                              include_unchanged=True))
1273
1274
    def test_unknown_unicode(self):
1275
        tree1 = self.make_branch_and_tree('tree1')
1276
        tree2 = self.make_to_branch_and_tree('tree2')
1277
        root_id = tree1.get_root_id()
1278
        tree2.set_root_id(root_id)
1279
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1280
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1281
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1282
        try:
1283
            self.build_tree([u'tree1/\u03b1/',
1284
                             u'tree2/\u03b1/',
1285
                             u'tree2/\u03b1/unknown_dir/',
1286
                             u'tree2/\u03b1/unknown_file',
1287
                             u'tree2/\u03b1/unknown_dir/file',
1288
                             u'tree2/\u03c9-unknown_root_file',
1289
                            ])
1290
        except UnicodeError:
1291
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1292
        tree1.add([u'\u03b1'], [a_id])
1293
        tree2.add([u'\u03b1'], [a_id])
1294
1295
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1296
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1297
1298
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1299
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1300
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1301
            self.unversioned(tree2, u'\u03c9-unknown_root_file'),
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1302
            # a/unknown_dir/file should not be included because we should not
1303
            # recurse into unknown_dir
1304
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1305
            ])
1306
        self.assertEqual(expected,
1307
                         self.do_iter_changes(tree1, tree2,
1308
                                              require_versioned=False,
1309
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1310
        self.assertEqual([], # Without want_unversioned we should get nothing
1311
                         self.do_iter_changes(tree1, tree2))
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1312
1313
        # We should also be able to select just a subset
1314
        expected = sorted([
1315
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1316
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1317
            ])
1318
        self.assertEqual(expected,
1319
                         self.do_iter_changes(tree1, tree2,
1320
                                              specific_files=[u'\u03b1'],
1321
                                              require_versioned=False,
1322
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1323
        self.assertEqual([], # Without want_unversioned we should get nothing
1324
                         self.do_iter_changes(tree1, tree2,
1325
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1326
1327
    def test_unknown_empty_dir(self):
1328
        tree1 = self.make_branch_and_tree('tree1')
1329
        tree2 = self.make_to_branch_and_tree('tree2')
1330
        root_id = tree1.get_root_id()
1331
        tree2.set_root_id(root_id)
1332
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1333
        # Start with 2 identical trees
1334
        self.build_tree(['tree1/a/', 'tree1/b/',
1335
                         'tree2/a/', 'tree2/b/'])
1336
        self.build_tree_contents([('tree1/b/file', 'contents\n'),
1337
                                  ('tree2/b/file', 'contents\n')])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1338
        tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1339
        tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1340
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1341
        # Now create some unknowns in tree2
1342
        # We should find both a/file and a/dir as unknown, but we shouldn't
1343
        # recurse into a/dir to find that a/dir/subfile is also unknown.
1344
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1345
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1346
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1347
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1348
1349
        expected = sorted([
1350
            self.unversioned(tree2, u'a/file'),
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1351
            self.unversioned(tree2, u'a/dir'),
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1352
            ])
1353
        self.assertEqual(expected,
1354
                         self.do_iter_changes(tree1, tree2,
1355
                                              require_versioned=False,
1356
                                              want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1357
1358
    def test_rename_over_deleted(self):
1359
        tree1 = self.make_branch_and_tree('tree1')
1360
        tree2 = self.make_to_branch_and_tree('tree2')
1361
        root_id = tree1.get_root_id()
1362
        tree2.set_root_id(root_id)
1363
1364
        # The final changes should be:
1365
        #   touch a b c d
1366
        #   add a b c d
1367
        #   commit
1368
        #   rm a d
1369
        #   mv b a
1370
        #   mv c d
1371
        self.build_tree_contents([
1372
            ('tree1/a', 'a contents\n'),
1373
            ('tree1/b', 'b contents\n'),
1374
            ('tree1/c', 'c contents\n'),
1375
            ('tree1/d', 'd contents\n'),
1376
            ('tree2/a', 'b contents\n'),
1377
            ('tree2/d', 'c contents\n'),
1378
            ])
1379
        tree1.add(['a', 'b', 'c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
1380
        tree2.add(['a', 'd'], ['b-id', 'c-id'])
1381
1382
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1383
1384
        expected = sorted([
1385
            self.deleted(tree1, 'a-id'),
1386
            self.deleted(tree1, 'd-id'),
1387
            self.renamed(tree1, tree2, 'b-id', False),
1388
            self.renamed(tree1, tree2, 'c-id', False),
1389
            ])
1390
        self.assertEqual(expected,
1391
                         self.do_iter_changes(tree1, tree2))
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1392
1393
    def test_deleted_and_unknown(self):
1394
        """Test a file marked removed, but still present on disk."""
1395
        tree1 = self.make_branch_and_tree('tree1')
1396
        tree2 = self.make_to_branch_and_tree('tree2')
1397
        root_id = tree1.get_root_id()
1398
        tree2.set_root_id(root_id)
1399
1400
        # The final changes should be:
1401
        # bzr add a b c
1402
        # bzr rm --keep b
1403
        self.build_tree_contents([
1404
            ('tree1/a', 'a contents\n'),
1405
            ('tree1/b', 'b contents\n'),
1406
            ('tree1/c', 'c contents\n'),
1407
            ('tree2/a', 'a contents\n'),
1408
            ('tree2/b', 'b contents\n'),
1409
            ('tree2/c', 'c contents\n'),
1410
            ])
1411
        tree1.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
1412
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1413
1414
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1415
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1416
1417
        expected = sorted([
1418
            self.deleted(tree1, 'b-id'),
1419
            self.unversioned(tree2, 'b'),
1420
            ])
1421
        self.assertEqual(expected,
1422
                         self.do_iter_changes(tree1, tree2,
1423
                                              want_unversioned=True))
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1424
        expected = sorted([
1425
            self.deleted(tree1, 'b-id'),
1426
            ])
1427
        self.assertEqual(expected,
1428
                         self.do_iter_changes(tree1, tree2,
1429
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1430
1431
    def test_renamed_and_added(self):
1432
        """Test when we have renamed a file, and put another in its place."""
1433
        tree1 = self.make_branch_and_tree('tree1')
1434
        tree2 = self.make_to_branch_and_tree('tree2')
1435
        root_id = tree1.get_root_id()
1436
        tree2.set_root_id(root_id)
1437
1438
        # The final changes are:
1439
        # bzr add b c
1440
        # bzr mv b a
1441
        # bzr mv c d
1442
        # bzr add b c
1443
1444
        self.build_tree_contents([
1445
            ('tree1/b', 'b contents\n'),
1446
            ('tree1/c', 'c contents\n'),
1447
            ('tree2/a', 'b contents\n'),
1448
            ('tree2/b', 'new b contents\n'),
1449
            ('tree2/c', 'new c contents\n'),
1450
            ('tree2/d', 'c contents\n'),
1451
            ])
1452
        tree1.add(['b', 'c'], ['b1-id', 'c1-id'])
1453
        tree2.add(['a', 'b', 'c', 'd'], ['b1-id', 'b2-id', 'c2-id', 'c1-id'])
1454
1455
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1456
1457
        expected = sorted([
1458
            self.renamed(tree1, tree2, 'b1-id', False),
1459
            self.renamed(tree1, tree2, 'c1-id', False),
1460
            self.added(tree2, 'b2-id'),
1461
            self.added(tree2, 'c2-id'),
1462
            ])
1463
        self.assertEqual(expected,
1464
                         self.do_iter_changes(tree1, tree2,
1465
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1466
1467
    def test_renamed_and_unknown(self):
1468
        """A file was moved on the filesystem, but not in bzr."""
1469
        tree1 = self.make_branch_and_tree('tree1')
1470
        tree2 = self.make_to_branch_and_tree('tree2')
1471
        root_id = tree1.get_root_id()
1472
        tree2.set_root_id(root_id)
1473
1474
        # The final changes are:
1475
        # bzr add a b
1476
        # mv a a2
1477
1478
        self.build_tree_contents([
1479
            ('tree1/a', 'a contents\n'),
1480
            ('tree1/b', 'b contents\n'),
1481
            ('tree2/a', 'a contents\n'),
1482
            ('tree2/b', 'b contents\n'),
1483
            ])
1484
        tree1.add(['a', 'b'], ['a-id', 'b-id'])
1485
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1486
        os.rename('tree2/a', 'tree2/a2')
1487
1488
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1489
        self.not_applicable_if_missing_in('a', tree2)
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1490
1491
        expected = sorted([
1492
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),
1493
            self.unversioned(tree2, 'a2'),
1494
            ])
1495
        self.assertEqual(expected,
1496
                         self.do_iter_changes(tree1, tree2,
1497
                                              want_unversioned=True))