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