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