/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
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
370
    def do_has_changes(self, tree1, tree2, **extra_args):
371
        tree1.lock_read()
372
        tree2.lock_read()
373
        try:
374
            return tree1.has_changes(tree2)
375
        finally:
376
            tree1.unlock()
377
            tree2.unlock()
378
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
379
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
380
        """Convert the working trees into test trees.
381
382
        Read lock them, and add the unlock to the cleanup.
383
        """
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
384
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
385
        tree1.lock_read()
386
        self.addCleanup(tree1.unlock)
387
        tree2.lock_read()
388
        self.addCleanup(tree2.unlock)
389
        return tree1, tree2
390
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
391
    def make_tree_with_special_names(self):
392
        """Create a tree with filenames chosen to exercise the walk order."""
393
        tree1 = self.make_branch_and_tree('tree1')
394
        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
395
        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.
396
        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.
397
        tree2.commit('initial', rev_id='rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
398
        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.
399
        return (tree1, tree2, paths, path_ids)
400
401
    def make_trees_with_special_names(self):
402
        """Both trees will use the special names.
403
404
        But the contents will differ for each file.
405
        """
406
        tree1 = self.make_branch_and_tree('tree1')
407
        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
408
        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.
409
        paths, path_ids = self._create_special_names(tree1, 'tree1')
410
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
411
        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.
412
        return (tree1, tree2, paths, path_ids)
413
414
    def _create_special_names(self, tree, base_path):
415
        """Create a tree with paths that expose differences in sort orders."""
416
        # Each directory will have a single file named 'f' inside
417
        dirs = ['a',
418
                'a-a',
419
                'a/a',
420
                'a/a-a',
421
                'a/a/a',
422
                'a/a/a-a',
423
                'a/a/a/a',
424
                'a/a/a/a-a',
425
                'a/a/a/a/a',
426
               ]
427
        with_slashes = []
428
        paths = []
429
        path_ids = []
430
        for d in dirs:
431
            with_slashes.append(base_path + '/' + d + '/')
432
            with_slashes.append(base_path + '/' + d + '/f')
433
            paths.append(d)
434
            paths.append(d+'/f')
435
            path_ids.append(d.replace('/', '_') + '-id')
436
            path_ids.append(d.replace('/', '_') + '_f-id')
437
        self.build_tree(with_slashes)
438
        tree.add(paths, path_ids)
439
        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.
440
2012.1.1 by Aaron Bentley
Implement change iterator
441
    def test_compare_empty_trees(self):
442
        tree1 = self.make_branch_and_tree('1')
443
        tree2 = self.make_to_branch_and_tree('2')
444
        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.
445
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
446
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3254.1.2 by Aaron Bentley
Fix doiter_changes
447
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
448
        self.assertEquals(False, self.do_has_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
449
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
450
    def added(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
451
        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.
452
        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.
453
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
454
                (None, entry.executable))
455
3363.14.7 by Aaron Bentley
Get more tests passing
456
    @staticmethod
457
    def get_path_entry(tree, file_id):
458
        iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id])
459
        return iterator.next()
460
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.
461
    def content_changed(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
462
        path, entry = self.get_path_entry(tree, file_id)
463
        return (file_id, (path, path), True, (True, True),
464
                (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.
465
                (entry.name, entry.name), (entry.kind, entry.kind),
466
                (entry.executable, entry.executable))
467
468
    def kind_changed(self, from_tree, to_tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
469
        from_path, old_entry = self.get_path_entry(from_tree, file_id)
470
        path, new_entry = self.get_path_entry(to_tree, file_id)
471
        return (file_id, (from_path, path), True, (True, True),
472
                (old_entry.parent_id, new_entry.parent_id),
473
                (old_entry.name, new_entry.name),
474
                (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.
475
                (old_entry.executable, new_entry.executable))
476
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
477
    def missing(self, file_id, from_path, to_path, parent_id, kind):
478
        _, from_basename = os.path.split(from_path)
479
        _, to_basename = os.path.split(to_path)
480
        # missing files have both paths, but no kind.
481
        return (file_id, (from_path, to_path), True, (True, True),
482
            (parent_id, parent_id),
483
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
484
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
485
    def deleted(self, tree, file_id):
486
        entry = tree.inventory[file_id]
487
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
488
        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.
489
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
490
                (entry.executable, None))
491
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
492
    def renamed(self, from_tree, to_tree, file_id, content_changed):
3363.14.8 by Aaron Bentley
Fix more tests
493
        from_path, from_entry = self.get_path_entry(from_tree, file_id)
494
        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.
495
        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.
496
            (from_entry.parent_id, to_entry.parent_id),
497
            (from_entry.name, to_entry.name),
498
            (from_entry.kind, to_entry.kind),
499
            (from_entry.executable, to_entry.executable))
500
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.
501
    def unchanged(self, tree, file_id):
3363.14.8 by Aaron Bentley
Fix more tests
502
        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.
503
        parent = entry.parent_id
504
        name = entry.name
505
        kind = entry.kind
506
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
507
        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.
508
               (parent, parent), (name, name), (kind, kind),
509
               (executable, executable))
510
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
511
    def unversioned(self, tree, path):
512
        """Create an unversioned result."""
513
        _, basename = os.path.split(path)
3363.14.7 by Aaron Bentley
Get more tests passing
514
        kind = tree._comparison_data(None, path)[0]
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
515
        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.
516
                (None, basename), (None, kind),
517
                (None, False))
518
2012.1.1 by Aaron Bentley
Implement change iterator
519
    def test_empty_to_abc_content(self):
520
        tree1 = self.make_branch_and_tree('1')
521
        tree2 = self.make_to_branch_and_tree('2')
522
        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.
523
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
524
        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.
525
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
526
            self.added(tree2, 'root-id'),
527
            self.added(tree2, 'a-id'),
528
            self.added(tree2, 'b-id'),
529
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
530
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
531
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
532
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
533
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
534
    def test_empty_specific_files(self):
535
        tree1 = self.make_branch_and_tree('1')
536
        tree2 = self.make_to_branch_and_tree('2')
537
        tree1 = self.get_tree_no_parents_no_content(tree1)
538
        tree2 = self.get_tree_no_parents_abc_content(tree2)
539
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
540
        self.assertEqual([],
541
            self.do_iter_changes(tree1, tree2, specific_files=[]))
542
543
    def test_no_specific_files(self):
544
        tree1 = self.make_branch_and_tree('1')
545
        tree2 = self.make_to_branch_and_tree('2')
546
        tree1 = self.get_tree_no_parents_no_content(tree1)
547
        tree2 = self.get_tree_no_parents_abc_content(tree2)
548
        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
549
        expected_results = sorted([
550
            self.added(tree2, 'root-id'),
551
            self.added(tree2, 'a-id'),
552
            self.added(tree2, 'b-id'),
553
            self.added(tree2, 'c-id'),
554
            self.deleted(tree1, 'empty-root-id')])
555
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
556
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
557
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
558
    def test_empty_to_abc_content_a_only(self):
559
        tree1 = self.make_branch_and_tree('1')
560
        tree2 = self.make_to_branch_and_tree('2')
561
        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.
562
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
563
        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.
564
        self.assertEqual(
565
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
566
            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.
567
568
    def test_abc_content_to_empty_to_abc_content_a_only(self):
569
        tree1 = self.make_branch_and_tree('1')
570
        tree2 = self.make_to_branch_and_tree('2')
571
        tree1 = self.get_tree_no_parents_abc_content(tree1)
572
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
573
        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.
574
        self.assertEqual(
575
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
576
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
577
578
    def test_empty_to_abc_content_a_and_c_only(self):
579
        tree1 = self.make_branch_and_tree('1')
580
        tree2 = self.make_to_branch_and_tree('2')
581
        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.
582
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
583
        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.
584
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
585
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
586
            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
587
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
588
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
589
        tree1 = self.make_branch_and_tree('1')
590
        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.
591
        tree1 = self.get_tree_no_parents_abc_content(tree1)
592
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
593
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
594
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
595
            entry = tree1.inventory[file_id]
596
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
597
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
598
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
599
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
600
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
601
        expected_results = sorted([
602
            self.added(tree2, 'empty-root-id'),
603
            deleted('root-id'), deleted('a-id'),
604
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
605
        self.assertEqual(
606
            expected_results,
607
            self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
608
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
609
610
    def test_content_modification(self):
611
        tree1 = self.make_branch_and_tree('1')
612
        tree2 = self.make_to_branch_and_tree('2')
613
        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.
614
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
615
        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.
616
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
617
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
618
                           (root_id, root_id), ('a', 'a'),
619
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
620
                         self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
621
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
622
623
    def test_meta_modification(self):
624
        tree1 = self.make_branch_and_tree('1')
625
        tree2 = self.make_to_branch_and_tree('2')
626
        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.
627
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
628
        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.
629
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
630
                           ('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.
631
                          (False, True))],
632
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
633
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
634
    def test_empty_dir(self):
635
        """an empty dir should not cause glitches to surrounding files."""
636
        tree1 = self.make_branch_and_tree('1')
637
        tree2 = self.make_to_branch_and_tree('2')
638
        tree1 = self.get_tree_no_parents_abc_content(tree1)
639
        tree2 = self.get_tree_no_parents_abc_content(tree2)
640
        # the pathname is chosen to fall between 'a' and 'b'.
641
        self.build_tree(['1/a-empty/', '2/a-empty/'])
642
        tree1.add(['a-empty'], ['a-empty'])
643
        tree2.add(['a-empty'], ['a-empty'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
644
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
645
        expected = []
646
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
647
2012.1.1 by Aaron Bentley
Implement change iterator
648
    def test_file_rename(self):
649
        tree1 = self.make_branch_and_tree('1')
650
        tree2 = self.make_to_branch_and_tree('2')
651
        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.
652
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
653
        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.
654
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
655
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
656
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
657
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
658
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
659
660
    def test_file_rename_and_modification(self):
661
        tree1 = self.make_branch_and_tree('1')
662
        tree2 = self.make_to_branch_and_tree('2')
663
        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.
664
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
665
        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.
666
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
667
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
668
                           (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.
669
                           (False, False))],
670
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
671
672
    def test_file_rename_and_meta_modification(self):
673
        tree1 = self.make_branch_and_tree('1')
674
        tree2 = self.make_to_branch_and_tree('2')
675
        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.
676
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
677
        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.
678
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
679
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
680
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
681
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
682
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
683
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
684
    def test_missing_in_target(self):
685
        """Test with the target files versioned but absent from disk."""
686
        tree1 = self.make_branch_and_tree('1')
687
        tree2 = self.make_to_branch_and_tree('2')
688
        tree1 = self.get_tree_no_parents_abc_content(tree1)
689
        tree2 = self.get_tree_no_parents_abc_content(tree2)
690
        os.unlink('2/a')
691
        shutil.rmtree('2/b')
692
        # TODO ? have a symlink here?
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
693
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
694
        self.not_applicable_if_missing_in('a', tree2)
695
        self.not_applicable_if_missing_in('b', tree2)
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
696
        root_id = tree1.path2id('')
697
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
698
            self.missing('a-id', 'a', 'a', root_id, 'file'),
699
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
700
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
701
            ])
702
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
703
704
    def test_missing_and_renamed(self):
705
        tree1 = self.make_branch_and_tree('tree1')
706
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
707
        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.
708
        self.build_tree(['tree1/file'])
709
        tree1.add(['file'], ['file-id'])
710
        self.build_tree(['tree2/directory/'])
711
        tree2.add(['directory'], ['file-id'])
712
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
713
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
714
        self.not_applicable_if_missing_in('directory', tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
715
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
716
        root_id = tree1.path2id('')
717
        expected = sorted([
718
            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.
719
            ])
720
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
721
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)
722
    def test_only_in_source_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(['tree1/file'])
727
        tree1.add(['file'], ['file-id'])
728
        os.unlink('tree1/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', 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)
731
        root_id = tree1.path2id('')
732
        expected = [('file-id', ('file', None), False, (True, False),
733
            (root_id, None), ('file', None), (None, None), (False, None))]
734
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
735
736
    def test_only_in_target_and_missing(self):
737
        tree1 = self.make_branch_and_tree('tree1')
738
        tree2 = self.make_to_branch_and_tree('tree2')
739
        tree2.set_root_id(tree1.get_root_id())
740
        self.build_tree(['tree2/file'])
741
        tree2.add(['file'], ['file-id'])
742
        os.unlink('tree2/file')
743
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
744
        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)
745
        root_id = tree1.path2id('')
746
        expected = [('file-id', (None, 'file'), False, (False, True),
747
            (None, root_id), (None, 'file'), (None, None), (None, False))]
748
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
749
2012.1.1 by Aaron Bentley
Implement change iterator
750
    def test_unchanged_with_renames_and_modifications(self):
751
        """want_unchanged should generate a list of unchanged entries."""
752
        tree1 = self.make_branch_and_tree('1')
753
        tree2 = self.make_to_branch_and_tree('2')
754
        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.
755
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
756
        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.
757
        root_id = tree1.path2id('')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
758
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.
759
        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.
760
            self.unchanged(tree1, 'b-id'),
761
            ('a-id', ('a', 'd'), True, (True, True),
762
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
763
            (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.
764
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
765
766
    def test_compare_subtrees(self):
767
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
768
        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.
769
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
770
        tree1.set_root_id('root-id')
771
        subtree1 = self.make_branch_and_tree('1/sub')
772
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
773
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
774
775
        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
776
        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.
777
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
778
        tree2.set_root_id('root-id')
779
        subtree2 = self.make_to_branch_and_tree('2/sub')
780
        subtree2.set_root_id('subtree-id')
781
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
782
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
783
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
784
        self.assertEqual([], list(tree2.iter_changes(tree1)))
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
785
        subtree1.commit('commit', rev_id='commit-a')
786
        self.assertEqual([
787
            ('root-id',
788
             (u'', u''),
789
             False,
790
             (True, True),
791
             (None, None),
792
             (u'', u''),
793
             ('directory', 'directory'),
794
             (False, False)),
795
            ('subtree-id',
796
             ('sub', 'sub',),
797
             False,
798
             (True, True),
799
             ('root-id', 'root-id'),
800
             ('sub', 'sub'),
801
             ('tree-reference', 'tree-reference'),
802
             (False, False))],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
803
                         list(tree2.iter_changes(tree1,
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
804
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
805
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
806
    def test_disk_in_subtrees_skipped(self):
807
        """subtrees are considered not-in-the-current-tree.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
808
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
809
        This test tests the trivial case, where the basis has no paths in the
810
        current trees subtree.
811
        """
812
        tree1 = self.make_branch_and_tree('1')
813
        tree1.set_root_id('root-id')
814
        tree2 = self.make_to_branch_and_tree('2')
815
        if not tree2.supports_tree_reference():
816
            return
817
        tree2.set_root_id('root-id')
818
        subtree2 = self.make_to_branch_and_tree('2/sub')
819
        subtree2.set_root_id('subtree-id')
4100.2.4 by Aaron Bentley
More support for not autodetecting tree refs
820
        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.
821
        self.build_tree(['2/sub/file'])
822
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
823
824
        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.
825
        # this should filter correctly from above
826
        self.assertEqual([self.added(tree2, 'subtree-id')],
827
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
828
        # and when the path is named
829
        self.assertEqual([self.added(tree2, 'subtree-id')],
830
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
831
                want_unversioned=True))
832
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
833
    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.
834
        tree1 = self.make_branch_and_tree('tree1')
835
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
836
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
837
        self.build_tree(['tree1/a', 'tree1/c',
838
                         'tree2/a', 'tree2/b', 'tree2/c'])
839
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
840
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
841
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
842
        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.
843
844
        # We should ignore the fact that 'b' exists in tree-2
845
        # because the want_unversioned parameter was not given.
846
        expected = sorted([
847
            self.content_changed(tree2, 'a-id'),
848
            self.content_changed(tree2, 'c-id'),
849
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
850
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
851
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
852
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
853
    def test_unversioned_paths_in_tree(self):
854
        tree1 = self.make_branch_and_tree('tree1')
855
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
856
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
857
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
858
        if has_symlinks():
859
            os.symlink('target', 'tree2/link')
860
            links_supported = True
861
        else:
862
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
863
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
864
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
865
        expected = [
866
            self.unversioned(tree2, 'file'),
867
            self.unversioned(tree2, 'dir'),
868
            ]
869
        if links_supported:
870
            expected.append(self.unversioned(tree2, 'link'))
871
        expected = sorted(expected)
872
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
873
            want_unversioned=True))
874
875
    def test_unversioned_paths_in_tree_specific_files(self):
876
        tree1 = self.make_branch_and_tree('tree1')
877
        tree2 = self.make_to_branch_and_tree('tree2')
878
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
879
        if has_symlinks():
880
            os.symlink('target', 'tree2/link')
881
            links_supported = True
882
        else:
883
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
884
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
885
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
886
        expected = [
887
            self.unversioned(tree2, 'file'),
888
            self.unversioned(tree2, 'dir'),
889
            ]
890
        specific_files=['file', 'dir']
891
        if links_supported:
892
            expected.append(self.unversioned(tree2, 'link'))
893
            specific_files.append('link')
894
        expected = sorted(expected)
895
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
896
            specific_files=specific_files, require_versioned=False,
897
            want_unversioned=True))
898
899
    def test_unversioned_paths_in_target_matching_source_old_names(self):
900
        # its likely that naive implementations of unversioned file support
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
901
        # 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.
902
        # due to a rename, not due to unversioning it.
903
        # That is, if the old tree has a versioned file 'foo', and
904
        # the new tree has the same file but versioned as 'bar', and also
905
        # has an unknown file 'foo', we should get back output for
906
        # both foo and bar.
907
        tree1 = self.make_branch_and_tree('tree1')
908
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
909
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
910
        self.build_tree(['tree2/file', 'tree2/dir/',
911
            'tree1/file', 'tree2/movedfile',
912
            'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
913
        if has_symlinks():
914
            os.symlink('target', 'tree1/link')
915
            os.symlink('target', 'tree2/link')
916
            os.symlink('target', 'tree2/movedlink')
917
            links_supported = True
918
        else:
919
            links_supported = False
920
        tree1.add(['file', 'dir'], ['file-id', 'dir-id'])
921
        tree2.add(['movedfile', 'moveddir'], ['file-id', 'dir-id'])
922
        if links_supported:
923
            tree1.add(['link'], ['link-id'])
924
            tree2.add(['movedlink'], ['link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
925
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
926
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
927
        root_id = tree1.path2id('')
928
        expected = [
929
            self.renamed(tree1, tree2, 'dir-id', False),
930
            self.renamed(tree1, tree2, 'file-id', True),
931
            self.unversioned(tree2, 'file'),
932
            self.unversioned(tree2, 'dir'),
933
            ]
934
        specific_files=['file', 'dir']
935
        if links_supported:
936
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
937
            expected.append(self.unversioned(tree2, 'link'))
938
            specific_files.append('link')
939
        expected = sorted(expected)
940
        # run once with, and once without specific files, to catch
941
        # potentially different code paths.
942
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
943
            require_versioned=False,
944
            want_unversioned=True))
945
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
946
            specific_files=specific_files, require_versioned=False,
947
            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.
948
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
949
    def test_similar_filenames(self):
950
        """Test when we have a few files with similar names."""
951
        tree1 = self.make_branch_and_tree('tree1')
952
        tree2 = self.make_branch_and_tree('tree2')
953
        tree2.set_root_id(tree1.get_root_id())
954
955
        # The trees are actually identical, but they happen to contain
956
        # similarly named files.
957
        self.build_tree(['tree1/a/',
958
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
959
                         'tree1/a/b/c/',
960
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
961
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
962
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
963
                         'tree2/a/',
964
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
965
                         'tree2/a/b/c/',
966
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
967
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
968
                         'tree2/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
969
                        ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
970
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
971
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
972
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
973
                  ['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
974
975
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
976
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
977
978
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
979
                                                  want_unversioned=True))
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
980
        expected = sorted([
981
            self.unchanged(tree2, tree2.get_root_id()),
982
            self.unchanged(tree2, 'a-id'),
983
            self.unchanged(tree2, 'b-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
984
            self.unchanged(tree2, 'c-id'),
985
            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.
986
            self.unchanged(tree2, 'a-c-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
987
            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.
988
            ])
989
        self.assertEqual(expected,
990
                         self.do_iter_changes(tree1, tree2,
991
                                              want_unversioned=True,
992
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
993
994
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
995
    def test_unversioned_subtree_only_emits_root(self):
996
        tree1 = self.make_branch_and_tree('tree1')
997
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
998
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
999
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
1000
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1001
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
1002
        expected = [
1003
            self.unversioned(tree2, 'dir'),
1004
            ]
1005
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1006
            want_unversioned=True))
1007
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.
1008
    def make_trees_with_symlinks(self):
1009
        tree1 = self.make_branch_and_tree('tree1')
1010
        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
1011
        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.
1012
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
1013
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
1014
        os.symlink('original', 'tree1/changed')
1015
        os.symlink('original', 'tree1/removed')
1016
        os.symlink('original', 'tree1/tofile')
1017
        os.symlink('original', 'tree1/todir')
1018
        # we make the unchanged link point at unknown to catch incorrect
1019
        # symlink-following code in the specified_files test.
1020
        os.symlink('unknown', 'tree1/unchanged')
1021
        os.symlink('new',      'tree2/added')
1022
        os.symlink('new',      'tree2/changed')
1023
        os.symlink('new',      'tree2/fromfile')
1024
        os.symlink('new',      'tree2/fromdir')
1025
        os.symlink('unknown', 'tree2/unchanged')
1026
        from_paths_and_ids = [
1027
            'fromdir',
1028
            'fromfile',
1029
            'changed',
1030
            'removed',
1031
            'todir',
1032
            'tofile',
1033
            'unchanged',
1034
            ]
1035
        to_paths_and_ids = [
1036
            'added',
1037
            'fromdir',
1038
            'fromfile',
1039
            'changed',
1040
            'todir',
1041
            'tofile',
1042
            'unchanged',
1043
            ]
1044
        tree1.add(from_paths_and_ids, from_paths_and_ids)
1045
        tree2.add(to_paths_and_ids, to_paths_and_ids)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1046
        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.
1047
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1048
    def test_versioned_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1049
        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.
1050
        tree1, tree2 = self.make_trees_with_symlinks()
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1051
        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.
1052
        root_id = tree1.path2id('')
1053
        expected = [
1054
            self.unchanged(tree1, tree1.path2id('')),
1055
            self.added(tree2, 'added'),
1056
            self.content_changed(tree2, 'changed'),
1057
            self.kind_changed(tree1, tree2, 'fromdir'),
1058
            self.kind_changed(tree1, tree2, 'fromfile'),
1059
            self.deleted(tree1, 'removed'),
1060
            self.unchanged(tree2, 'unchanged'),
1061
            self.unversioned(tree2, 'unknown'),
1062
            self.kind_changed(tree1, tree2, 'todir'),
1063
            self.kind_changed(tree1, tree2, 'tofile'),
1064
            ]
1065
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1066
        self.assertEqual(expected,
1067
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
1068
                want_unversioned=True))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1069
        self.assertEquals(True, self.do_has_changes(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.
1070
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1071
    def test_versioned_symlinks_specific_files(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1072
        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.
1073
        tree1, tree2 = self.make_trees_with_symlinks()
1074
        root_id = tree1.path2id('')
1075
        expected = [
1076
            self.added(tree2, 'added'),
1077
            self.content_changed(tree2, 'changed'),
1078
            self.kind_changed(tree1, tree2, 'fromdir'),
1079
            self.kind_changed(tree1, tree2, 'fromfile'),
1080
            self.deleted(tree1, 'removed'),
1081
            self.kind_changed(tree1, tree2, 'todir'),
1082
            self.kind_changed(tree1, tree2, 'tofile'),
1083
            ]
1084
        expected = sorted(expected)
1085
        # we should get back just the changed links. We pass in 'unchanged' to
1086
        # make sure that it is correctly not returned - and neither is the
1087
        # unknown path 'unknown' which it points at.
1088
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1089
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
1090
            'removed', 'unchanged', 'todir', 'tofile']))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1091
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
1092
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1093
    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.
1094
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
1095
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1096
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1097
        self.assertEquals(True, self.do_has_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.
1098
1099
    def test_trees_with_special_names(self):
1100
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1101
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1102
                          if f_id.endswith('_f-id'))
1103
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1104
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2255.7.34 by John Arbash Meinel
Clean up test_bad_files, and fix a bug in _iter_changes when
1105
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1106
    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.
1107
        tree1 = self.make_branch_and_tree('tree1')
1108
        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
1109
        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.
1110
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1111
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1112
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1113
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1114
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1115
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1116
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1117
        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.
1118
        # 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.
1119
        expected = sorted([
1120
            self.content_changed(tree2, 'a-id'),
1121
            self.content_changed(tree2, 'g-id'),
1122
            self.deleted(tree1, 'b-id'),
1123
            self.deleted(tree1, 'c-id'),
1124
            self.deleted(tree1, 'd-id'),
1125
            self.deleted(tree1, 'e-id'),
1126
            ])
1127
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1128
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1129
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1130
    def test_added_unicode(self):
1131
        tree1 = self.make_branch_and_tree('tree1')
1132
        tree2 = self.make_to_branch_and_tree('tree2')
1133
        root_id = tree1.get_root_id()
1134
        tree2.set_root_id(root_id)
1135
1136
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1137
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1138
        a_id = u'\u03b1-id'.encode('utf8')
1139
        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.
1140
        try:
1141
            self.build_tree([u'tree1/\u03b1/',
1142
                             u'tree2/\u03b1/',
1143
                             u'tree2/\u03b1/\u03c9-added',
1144
                            ])
1145
        except UnicodeError:
1146
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1147
        tree1.add([u'\u03b1'], [a_id])
1148
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1149
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1150
        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.
1151
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1152
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1153
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1154
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1155
                         self.do_iter_changes(tree1, tree2,
1156
                                              specific_files=[u'\u03b1']))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1157
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1158
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1159
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1160
        tree1 = self.make_branch_and_tree('tree1')
1161
        tree2 = self.make_to_branch_and_tree('tree2')
1162
        root_id = tree1.get_root_id()
1163
        tree2.set_root_id(root_id)
1164
1165
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1166
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1167
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1168
        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.
1169
        try:
1170
            self.build_tree([u'tree1/\u03b1/',
1171
                             u'tree1/\u03b1/\u03c9-deleted',
1172
                             u'tree2/\u03b1/',
1173
                            ])
1174
        except UnicodeError:
1175
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1176
        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.
1177
        tree2.add([u'\u03b1'], [a_id])
1178
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1179
        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.
1180
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1181
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1182
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1183
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1184
                         self.do_iter_changes(tree1, tree2,
1185
                                              specific_files=[u'\u03b1']))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1186
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1187
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1188
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1189
        tree1 = self.make_branch_and_tree('tree1')
1190
        tree2 = self.make_to_branch_and_tree('tree2')
1191
        root_id = tree1.get_root_id()
1192
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1193
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1194
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1195
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1196
        a_id = u'\u03b1-id'.encode('utf8')
1197
        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.
1198
        try:
1199
            self.build_tree([u'tree1/\u03b1/',
1200
                             u'tree1/\u03b1/\u03c9-modified',
1201
                             u'tree2/\u03b1/',
1202
                             u'tree2/\u03b1/\u03c9-modified',
1203
                            ])
1204
        except UnicodeError:
1205
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1206
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1207
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1208
1209
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1210
1211
        self.assertEqual([self.content_changed(tree1, mod_id)],
1212
                         self.do_iter_changes(tree1, tree2))
1213
        self.assertEqual([self.content_changed(tree1, mod_id)],
1214
                         self.do_iter_changes(tree1, tree2,
1215
                                              specific_files=[u'\u03b1']))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1216
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1217
1218
    def test_renamed_unicode(self):
1219
        tree1 = self.make_branch_and_tree('tree1')
1220
        tree2 = self.make_to_branch_and_tree('tree2')
1221
        root_id = tree1.get_root_id()
1222
        tree2.set_root_id(root_id)
1223
1224
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1225
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1226
        a_id = u'\u03b1-id'.encode('utf8')
1227
        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.
1228
        try:
1229
            self.build_tree([u'tree1/\u03b1/',
1230
                             u'tree2/\u03b1/',
1231
                            ])
1232
        except UnicodeError:
1233
            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.
1234
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1235
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1236
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1237
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1238
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1239
1240
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1241
1242
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1243
                         self.do_iter_changes(tree1, tree2))
1244
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1245
                         self.do_iter_changes(tree1, tree2,
1246
                                              specific_files=[u'\u03b1']))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1247
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1248
1249
    def test_unchanged_unicode(self):
1250
        tree1 = self.make_branch_and_tree('tree1')
1251
        tree2 = self.make_to_branch_and_tree('tree2')
1252
        root_id = tree1.get_root_id()
1253
        tree2.set_root_id(root_id)
1254
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1255
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1256
        a_id = u'\u03b1-id'.encode('utf8')
1257
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1258
        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.
1259
        try:
1260
            self.build_tree([u'tree1/\u03b1/',
1261
                             u'tree2/\u03b1/',
1262
                            ])
1263
        except UnicodeError:
1264
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1265
        self.build_tree_contents([
1266
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1267
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1268
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1269
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1270
            ])
1271
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1272
                  [a_id, subfile_id, rootfile_id])
1273
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1274
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1275
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1276
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1277
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1278
        expected = sorted([
1279
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1280
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1281
            self.unchanged(tree1, subfile_id),
1282
            self.unchanged(tree1, rootfile_id),
1283
            ])
1284
        self.assertEqual(expected,
1285
                         self.do_iter_changes(tree1, tree2,
1286
                                              include_unchanged=True))
1287
1288
        # We should also be able to select just a subset
1289
        expected = sorted([
1290
            self.unchanged(tree1, a_id),
1291
            self.unchanged(tree1, subfile_id),
1292
            ])
1293
        self.assertEqual(expected,
1294
                         self.do_iter_changes(tree1, tree2,
1295
                                              specific_files=[u'\u03b1'],
1296
                                              include_unchanged=True))
1297
1298
    def test_unknown_unicode(self):
1299
        tree1 = self.make_branch_and_tree('tree1')
1300
        tree2 = self.make_to_branch_and_tree('tree2')
1301
        root_id = tree1.get_root_id()
1302
        tree2.set_root_id(root_id)
1303
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1304
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1305
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1306
        try:
1307
            self.build_tree([u'tree1/\u03b1/',
1308
                             u'tree2/\u03b1/',
1309
                             u'tree2/\u03b1/unknown_dir/',
1310
                             u'tree2/\u03b1/unknown_file',
1311
                             u'tree2/\u03b1/unknown_dir/file',
1312
                             u'tree2/\u03c9-unknown_root_file',
1313
                            ])
1314
        except UnicodeError:
1315
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1316
        tree1.add([u'\u03b1'], [a_id])
1317
        tree2.add([u'\u03b1'], [a_id])
1318
1319
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1320
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1321
1322
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1323
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1324
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1325
            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.
1326
            # a/unknown_dir/file should not be included because we should not
1327
            # recurse into unknown_dir
1328
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1329
            ])
1330
        self.assertEqual(expected,
1331
                         self.do_iter_changes(tree1, tree2,
1332
                                              require_versioned=False,
1333
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1334
        self.assertEqual([], # Without want_unversioned we should get nothing
1335
                         self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1336
        self.assertEquals(False, self.do_has_changes(tree1, tree2))
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1337
1338
        # We should also be able to select just a subset
1339
        expected = sorted([
1340
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1341
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1342
            ])
1343
        self.assertEqual(expected,
1344
                         self.do_iter_changes(tree1, tree2,
1345
                                              specific_files=[u'\u03b1'],
1346
                                              require_versioned=False,
1347
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1348
        self.assertEqual([], # Without want_unversioned we should get nothing
1349
                         self.do_iter_changes(tree1, tree2,
1350
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1351
1352
    def test_unknown_empty_dir(self):
1353
        tree1 = self.make_branch_and_tree('tree1')
1354
        tree2 = self.make_to_branch_and_tree('tree2')
1355
        root_id = tree1.get_root_id()
1356
        tree2.set_root_id(root_id)
1357
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1358
        # Start with 2 identical trees
1359
        self.build_tree(['tree1/a/', 'tree1/b/',
1360
                         'tree2/a/', 'tree2/b/'])
1361
        self.build_tree_contents([('tree1/b/file', 'contents\n'),
1362
                                  ('tree2/b/file', 'contents\n')])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1363
        tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1364
        tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1365
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1366
        # Now create some unknowns in tree2
1367
        # We should find both a/file and a/dir as unknown, but we shouldn't
1368
        # recurse into a/dir to find that a/dir/subfile is also unknown.
1369
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1370
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1371
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1372
        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()
1373
1374
        expected = sorted([
1375
            self.unversioned(tree2, u'a/file'),
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1376
            self.unversioned(tree2, u'a/dir'),
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1377
            ])
1378
        self.assertEqual(expected,
1379
                         self.do_iter_changes(tree1, tree2,
1380
                                              require_versioned=False,
1381
                                              want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1382
1383
    def test_rename_over_deleted(self):
1384
        tree1 = self.make_branch_and_tree('tree1')
1385
        tree2 = self.make_to_branch_and_tree('tree2')
1386
        root_id = tree1.get_root_id()
1387
        tree2.set_root_id(root_id)
1388
1389
        # The final changes should be:
1390
        #   touch a b c d
1391
        #   add a b c d
1392
        #   commit
1393
        #   rm a d
1394
        #   mv b a
1395
        #   mv c d
1396
        self.build_tree_contents([
1397
            ('tree1/a', 'a contents\n'),
1398
            ('tree1/b', 'b contents\n'),
1399
            ('tree1/c', 'c contents\n'),
1400
            ('tree1/d', 'd contents\n'),
1401
            ('tree2/a', 'b contents\n'),
1402
            ('tree2/d', 'c contents\n'),
1403
            ])
1404
        tree1.add(['a', 'b', 'c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
1405
        tree2.add(['a', 'd'], ['b-id', 'c-id'])
1406
1407
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1408
1409
        expected = sorted([
1410
            self.deleted(tree1, 'a-id'),
1411
            self.deleted(tree1, 'd-id'),
1412
            self.renamed(tree1, tree2, 'b-id', False),
1413
            self.renamed(tree1, tree2, 'c-id', False),
1414
            ])
1415
        self.assertEqual(expected,
1416
                         self.do_iter_changes(tree1, tree2))
4503.1.1 by Vincent Ladeuil
Add tree.has_changes() to quickly check iter_changes().
1417
        self.assertEquals(True, self.do_has_changes(tree1, tree2))
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1418
1419
    def test_deleted_and_unknown(self):
1420
        """Test a file marked removed, but still present on disk."""
1421
        tree1 = self.make_branch_and_tree('tree1')
1422
        tree2 = self.make_to_branch_and_tree('tree2')
1423
        root_id = tree1.get_root_id()
1424
        tree2.set_root_id(root_id)
1425
1426
        # The final changes should be:
1427
        # bzr add a b c
1428
        # bzr rm --keep b
1429
        self.build_tree_contents([
1430
            ('tree1/a', 'a contents\n'),
1431
            ('tree1/b', 'b contents\n'),
1432
            ('tree1/c', 'c contents\n'),
1433
            ('tree2/a', 'a contents\n'),
1434
            ('tree2/b', 'b contents\n'),
1435
            ('tree2/c', 'c contents\n'),
1436
            ])
1437
        tree1.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
1438
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1439
1440
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1441
        self.not_applicable_if_cannot_represent_unversioned(tree2)
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1442
1443
        expected = sorted([
1444
            self.deleted(tree1, 'b-id'),
1445
            self.unversioned(tree2, 'b'),
1446
            ])
1447
        self.assertEqual(expected,
1448
                         self.do_iter_changes(tree1, tree2,
1449
                                              want_unversioned=True))
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1450
        expected = sorted([
1451
            self.deleted(tree1, 'b-id'),
1452
            ])
1453
        self.assertEqual(expected,
1454
                         self.do_iter_changes(tree1, tree2,
1455
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1456
1457
    def test_renamed_and_added(self):
1458
        """Test when we have renamed a file, and put another in its place."""
1459
        tree1 = self.make_branch_and_tree('tree1')
1460
        tree2 = self.make_to_branch_and_tree('tree2')
1461
        root_id = tree1.get_root_id()
1462
        tree2.set_root_id(root_id)
1463
1464
        # The final changes are:
1465
        # bzr add b c
1466
        # bzr mv b a
1467
        # bzr mv c d
1468
        # bzr add b c
1469
1470
        self.build_tree_contents([
1471
            ('tree1/b', 'b contents\n'),
1472
            ('tree1/c', 'c contents\n'),
1473
            ('tree2/a', 'b contents\n'),
1474
            ('tree2/b', 'new b contents\n'),
1475
            ('tree2/c', 'new c contents\n'),
1476
            ('tree2/d', 'c contents\n'),
1477
            ])
1478
        tree1.add(['b', 'c'], ['b1-id', 'c1-id'])
1479
        tree2.add(['a', 'b', 'c', 'd'], ['b1-id', 'b2-id', 'c2-id', 'c1-id'])
1480
1481
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1482
1483
        expected = sorted([
1484
            self.renamed(tree1, tree2, 'b1-id', False),
1485
            self.renamed(tree1, tree2, 'c1-id', False),
1486
            self.added(tree2, 'b2-id'),
1487
            self.added(tree2, 'c2-id'),
1488
            ])
1489
        self.assertEqual(expected,
1490
                         self.do_iter_changes(tree1, tree2,
1491
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1492
1493
    def test_renamed_and_unknown(self):
1494
        """A file was moved on the filesystem, but not in bzr."""
1495
        tree1 = self.make_branch_and_tree('tree1')
1496
        tree2 = self.make_to_branch_and_tree('tree2')
1497
        root_id = tree1.get_root_id()
1498
        tree2.set_root_id(root_id)
1499
1500
        # The final changes are:
1501
        # bzr add a b
1502
        # mv a a2
1503
1504
        self.build_tree_contents([
1505
            ('tree1/a', 'a contents\n'),
1506
            ('tree1/b', 'b contents\n'),
1507
            ('tree2/a', 'a contents\n'),
1508
            ('tree2/b', 'b contents\n'),
1509
            ])
1510
        tree1.add(['a', 'b'], ['a-id', 'b-id'])
1511
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1512
        os.rename('tree2/a', 'tree2/a2')
1513
1514
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
4241.6.7 by Vincent Ladeuil
Add InterCHKRevisionTree
1515
        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
1516
1517
        expected = sorted([
1518
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),
1519
            self.unversioned(tree2, 'a2'),
1520
            ])
1521
        self.assertEqual(expected,
1522
                         self.do_iter_changes(tree1, tree2,
1523
                                              want_unversioned=True))