/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
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
23
from bzrlib.osutils import file_kind
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
24
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
25
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
26
# TODO: test diff unversioned dir that exists
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: include dangling in the diff output.
34
# TODO: test items are only emitted once when a specific_files list names a dir
35
#       whose parent is now a child.
36
# TODO: test require_versioned
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
37
# TODO: explicitly test specific_files listing a non-dir, and listing a symlink
38
#       (it should not follow the link)
39
# TODO: test specific_files when the target tree has a file and the source a
40
#       dir with children, same id and same path. 
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
41
# TODO: test comparisons between trees with different root ids. mbp 20070301
2255.2.189 by Martin Pool
Add and fix up basic comparison of subtrees.
42
#
43
# TODO: More comparisons between trees with subtrees in different states.
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/'])
325
        # try:
326
        os.symlink('target', 'tree2/link')
327
        links_supported = True
328
        # except ???:
329
        #   links_supported = False
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)
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
337
        self.assertEqual([(u'dir', None, 'directory'), (u'file', None, 'file'),
338
            (u'link', None, 'symlink')], d.unversioned)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
339
2012.1.1 by Aaron Bentley
Implement change iterator
340
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
341
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
342
    """Test the comparison iterator"""
343
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
344
    def do_iter_changes(self, tree1, tree2, **extra_args):
345
        """Helper to run _iter_changes from tree1 to tree2.
346
        
347
        :param tree1, tree2:  The source and target trees. These will be locked
348
            automatically.
349
        :param **extra_args: Extra args to pass to _iter_changes. This is not
350
            inspected by this test helper.
351
        """
352
        tree1.lock_read()
353
        tree2.lock_read()
354
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
355
            # sort order of output is not strictly defined
356
            return sorted(self.intertree_class(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
357
                ._iter_changes(**extra_args))
358
        finally:
359
            tree1.unlock()
360
            tree2.unlock()
361
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
362
    def make_tree_with_special_names(self):
363
        """Create a tree with filenames chosen to exercise the walk order."""
364
        tree1 = self.make_branch_and_tree('tree1')
365
        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
366
        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.
367
        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.
368
        tree2.commit('initial', rev_id='rev-1')
369
        tree1, tree2 = self.mutable_trees_to_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.
370
        return (tree1, tree2, paths, path_ids)
371
372
    def make_trees_with_special_names(self):
373
        """Both trees will use the special names.
374
375
        But the contents will differ for each file.
376
        """
377
        tree1 = self.make_branch_and_tree('tree1')
378
        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
379
        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.
380
        paths, path_ids = self._create_special_names(tree1, 'tree1')
381
        paths, path_ids = self._create_special_names(tree2, 'tree2')
382
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
383
        return (tree1, tree2, paths, path_ids)
384
385
    def _create_special_names(self, tree, base_path):
386
        """Create a tree with paths that expose differences in sort orders."""
387
        # Each directory will have a single file named 'f' inside
388
        dirs = ['a',
389
                'a-a',
390
                'a/a',
391
                'a/a-a',
392
                'a/a/a',
393
                'a/a/a-a',
394
                'a/a/a/a',
395
                'a/a/a/a-a',
396
                'a/a/a/a/a',
397
               ]
398
        with_slashes = []
399
        paths = []
400
        path_ids = []
401
        for d in dirs:
402
            with_slashes.append(base_path + '/' + d + '/')
403
            with_slashes.append(base_path + '/' + d + '/f')
404
            paths.append(d)
405
            paths.append(d+'/f')
406
            path_ids.append(d.replace('/', '_') + '-id')
407
            path_ids.append(d.replace('/', '_') + '_f-id')
408
        self.build_tree(with_slashes)
409
        tree.add(paths, path_ids)
410
        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.
411
2012.1.1 by Aaron Bentley
Implement change iterator
412
    def test_compare_empty_trees(self):
413
        tree1 = self.make_branch_and_tree('1')
414
        tree2 = self.make_to_branch_and_tree('2')
415
        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.
416
        tree2 = self.get_tree_no_parents_no_content(tree2)
417
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
418
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
419
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
420
    def added(self, tree, file_id):
421
        entry = tree.inventory[file_id]
422
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
423
        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.
424
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
425
                (None, entry.executable))
426
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.
427
    def content_changed(self, tree, file_id):
428
        entry = tree.inventory[file_id]
429
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
430
        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.
431
                (entry.name, entry.name), (entry.kind, entry.kind),
432
                (entry.executable, entry.executable))
433
434
    def kind_changed(self, from_tree, to_tree, file_id):
435
        old_entry = from_tree.inventory[file_id]
436
        new_entry = to_tree.inventory[file_id]
437
        path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
438
        from_path = from_tree.id2path(file_id)
439
        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.
440
                (old_entry.name, new_entry.name), (old_entry.kind, new_entry.kind),
441
                (old_entry.executable, new_entry.executable))
442
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
443
    def missing(self, file_id, from_path, to_path, parent_id, kind):
444
        _, from_basename = os.path.split(from_path)
445
        _, to_basename = os.path.split(to_path)
446
        # missing files have both paths, but no kind.
447
        return (file_id, (from_path, to_path), True, (True, True),
448
            (parent_id, parent_id),
449
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
450
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
451
    def deleted(self, tree, file_id):
452
        entry = tree.inventory[file_id]
453
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
454
        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.
455
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
456
                (entry.executable, None))
457
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
458
    def renamed(self, from_tree, to_tree, file_id, content_changed):
459
        from_entry = from_tree.inventory[file_id]
460
        to_entry = to_tree.inventory[file_id]
461
        from_path = from_tree.id2path(file_id)
462
        to_path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
463
        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.
464
            (from_entry.parent_id, to_entry.parent_id),
465
            (from_entry.name, to_entry.name),
466
            (from_entry.kind, to_entry.kind),
467
            (from_entry.executable, to_entry.executable))
468
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.
469
    def unchanged(self, tree, file_id):
470
        entry = tree.inventory[file_id]
471
        parent = entry.parent_id
472
        name = entry.name
473
        kind = entry.kind
474
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
475
        path = tree.id2path(file_id)
476
        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.
477
               (parent, parent), (name, name), (kind, kind),
478
               (executable, executable))
479
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
480
    def unversioned(self, tree, path):
481
        """Create an unversioned result."""
482
        _, basename = os.path.split(path)
483
        kind = file_kind(tree.abspath(path))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
484
        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.
485
                (None, basename), (None, kind),
486
                (None, False))
487
2012.1.1 by Aaron Bentley
Implement change iterator
488
    def test_empty_to_abc_content(self):
489
        tree1 = self.make_branch_and_tree('1')
490
        tree2 = self.make_to_branch_and_tree('2')
491
        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.
492
        tree2 = self.get_tree_no_parents_abc_content(tree2)
493
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
494
        tree1.lock_read()
495
        tree2.lock_read()
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
496
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
497
            self.added(tree2, 'root-id'),
498
            self.added(tree2, 'a-id'),
499
            self.added(tree2, 'b-id'),
500
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
501
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
502
        tree1.unlock()
503
        tree2.unlock()
504
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
505
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
506
    def test_empty_to_abc_content_a_only(self):
507
        tree1 = self.make_branch_and_tree('1')
508
        tree2 = self.make_to_branch_and_tree('2')
509
        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.
510
        tree2 = self.get_tree_no_parents_abc_content(tree2)
511
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
512
        tree1.lock_read()
513
        tree2.lock_read()
514
        self.assertEqual(
515
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
516
            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.
517
        tree1.unlock()
518
        tree2.unlock()
519
520
    def test_abc_content_to_empty_to_abc_content_a_only(self):
521
        tree1 = self.make_branch_and_tree('1')
522
        tree2 = self.make_to_branch_and_tree('2')
523
        tree1 = self.get_tree_no_parents_abc_content(tree1)
524
        tree2 = self.get_tree_no_parents_no_content(tree2)
525
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
526
        tree1.lock_read()
527
        tree2.lock_read()
528
        self.assertEqual(
529
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
530
            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.
531
        tree1.unlock()
532
        tree2.unlock()
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
533
534
    def test_empty_to_abc_content_a_and_c_only(self):
535
        tree1 = self.make_branch_and_tree('1')
536
        tree2 = self.make_to_branch_and_tree('2')
537
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
538
        tree2 = self.get_tree_no_parents_abc_content(tree2)
539
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
540
        tree1.lock_read()
541
        tree2.lock_read()
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
542
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
543
        tree1.unlock()
544
        tree2.unlock()
545
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
546
            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
547
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
548
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
549
        tree1 = self.make_branch_and_tree('1')
550
        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.
551
        tree1 = self.get_tree_no_parents_abc_content(tree1)
552
        tree2 = self.get_tree_no_parents_no_content(tree2)
553
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
554
        tree1.lock_read()
555
        tree2.lock_read()
2012.1.1 by Aaron Bentley
Implement change iterator
556
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
557
            entry = tree1.inventory[file_id]
558
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
559
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
560
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
561
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
562
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
563
        expected_results = sorted([
564
            self.added(tree2, 'empty-root-id'),
565
            deleted('root-id'), deleted('a-id'),
566
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
567
        tree1.unlock()
568
        tree2.unlock()
569
        self.assertEqual(
570
            expected_results,
571
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
572
573
    def test_content_modification(self):
574
        tree1 = self.make_branch_and_tree('1')
575
        tree2 = self.make_to_branch_and_tree('2')
576
        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.
577
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
578
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
579
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
580
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
581
                           (root_id, root_id), ('a', 'a'),
582
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
583
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
584
585
    def test_meta_modification(self):
586
        tree1 = self.make_branch_and_tree('1')
587
        tree2 = self.make_to_branch_and_tree('2')
588
        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.
589
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
590
        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.
591
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
592
                           ('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.
593
                          (False, True))],
594
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
595
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
596
    def test_empty_dir(self):
597
        """an empty dir should not cause glitches to surrounding files."""
598
        tree1 = self.make_branch_and_tree('1')
599
        tree2 = self.make_to_branch_and_tree('2')
600
        tree1 = self.get_tree_no_parents_abc_content(tree1)
601
        tree2 = self.get_tree_no_parents_abc_content(tree2)
602
        # the pathname is chosen to fall between 'a' and 'b'.
603
        self.build_tree(['1/a-empty/', '2/a-empty/'])
604
        tree1.add(['a-empty'], ['a-empty'])
605
        tree2.add(['a-empty'], ['a-empty'])
606
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
607
        expected = []
608
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
609
2012.1.1 by Aaron Bentley
Implement change iterator
610
    def test_file_rename(self):
611
        tree1 = self.make_branch_and_tree('1')
612
        tree2 = self.make_to_branch_and_tree('2')
613
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
614
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
615
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
616
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
617
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
618
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
619
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
620
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
621
622
    def test_file_rename_and_modification(self):
623
        tree1 = self.make_branch_and_tree('1')
624
        tree2 = self.make_to_branch_and_tree('2')
625
        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.
626
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
627
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
628
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
629
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
630
                           (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.
631
                           (False, False))],
632
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
633
634
    def test_file_rename_and_meta_modification(self):
635
        tree1 = self.make_branch_and_tree('1')
636
        tree2 = self.make_to_branch_and_tree('2')
637
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
638
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
639
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
640
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
641
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
642
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
643
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
644
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
645
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
646
    def test_missing_in_target(self):
647
        """Test with the target files versioned but absent from disk."""
648
        tree1 = self.make_branch_and_tree('1')
649
        tree2 = self.make_to_branch_and_tree('2')
650
        tree1 = self.get_tree_no_parents_abc_content(tree1)
651
        tree2 = self.get_tree_no_parents_abc_content(tree2)
652
        os.unlink('2/a')
653
        shutil.rmtree('2/b')
654
        # TODO ? have a symlink here?
655
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
656
        root_id = tree1.path2id('')
657
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
658
            self.missing('a-id', 'a', 'a', root_id, 'file'),
659
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
660
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
661
            ])
662
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
663
664
    def test_missing_and_renamed(self):
665
        tree1 = self.make_branch_and_tree('tree1')
666
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
667
        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.
668
        self.build_tree(['tree1/file'])
669
        tree1.add(['file'], ['file-id'])
670
        self.build_tree(['tree2/directory/'])
671
        tree2.add(['directory'], ['file-id'])
672
        os.rmdir('tree2/directory')
673
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
674
        tree1.lock_read()
675
        self.addCleanup(tree1.unlock)
676
        tree2.lock_read()
677
        self.addCleanup(tree2.unlock)
678
        root_id = tree1.path2id('')
679
        expected = sorted([
680
            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.
681
            ])
682
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
683
2012.1.1 by Aaron Bentley
Implement change iterator
684
    def test_unchanged_with_renames_and_modifications(self):
685
        """want_unchanged should generate a list of unchanged entries."""
686
        tree1 = self.make_branch_and_tree('1')
687
        tree2 = self.make_to_branch_and_tree('2')
688
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
689
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
690
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
691
        root_id = tree1.path2id('')
2255.2.118 by Robert Collins
Change _iter_changes tests to lock the tested trees - its an iterator interface so implicit locks dont ensure the tree is locked - callers need to lock and thus so do our tests.
692
        tree1.lock_read()
693
        self.addCleanup(tree1.unlock)
694
        tree2.lock_read()
695
        self.addCleanup(tree2.unlock)
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.
696
        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.
697
            self.unchanged(tree1, 'b-id'),
698
            ('a-id', ('a', 'd'), True, (True, True),
699
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
700
            (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.
701
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
702
703
    def test_compare_subtrees(self):
704
        """want_unchanged should generate a list of unchanged entries."""
705
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
706
        if not tree1.supports_tree_reference():
707
            raise tests.TestSkipped('Tree %s does not support references'
708
                % (tree1,))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
709
        tree1.set_root_id('root-id')
710
        subtree1 = self.make_branch_and_tree('1/sub')
711
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
712
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
713
714
        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
715
        if not tree2.supports_tree_reference():
716
            raise tests.TestSkipped('Tree %s does not support references'
717
                % (tree2,))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
718
        tree2.set_root_id('root-id')
719
        subtree2 = self.make_to_branch_and_tree('2/sub')
720
        subtree2.set_root_id('subtree-id')
721
        tree2.add_reference(subtree2)
2255.13.1 by Martin Pool
review fixes from robert
722
723
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
724
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
725
        tree1.lock_read()
726
        tree2.lock_read()
727
        try:
728
            self.assertEqual([], list(tree2._iter_changes(tree1)))
729
            subtree1.commit('commit', rev_id='commit-a')
2255.2.189 by Martin Pool
Add and fix up basic comparison of subtrees.
730
            self.assertEqual([
731
                ('root-id',
732
                 (u'', u''),
733
                 False,
734
                 (True, True),
735
                 (None, None),
736
                 (u'', u''),
737
                 ('directory', 'directory'),
738
                 (False, False)),
739
                ('subtree-id',
740
                 ('sub', 'sub',),
741
                 False,
742
                 (True, True),
743
                 ('root-id', 'root-id'),
744
                 ('sub', 'sub'),
745
                 ('tree-reference', 'tree-reference'),
746
                 (False, False))],
747
                             list(tree2._iter_changes(tree1,
748
                                 include_unchanged=True)))
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
749
        finally:
750
            tree1.unlock()
751
            tree2.unlock()
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
752
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
753
    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.
754
        tree1 = self.make_branch_and_tree('tree1')
755
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
756
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
757
        self.build_tree(['tree1/a', 'tree1/c',
758
                         'tree2/a', 'tree2/b', 'tree2/c'])
759
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
760
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
761
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
762
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
763
        tree1.lock_read()
764
        self.addCleanup(tree1.unlock)
765
        tree2.lock_read()
766
        self.addCleanup(tree2.unlock)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
767
768
        # We should ignore the fact that 'b' exists in tree-2
769
        # because the want_unversioned parameter was not given.
770
        expected = sorted([
771
            self.content_changed(tree2, 'a-id'),
772
            self.content_changed(tree2, 'c-id'),
773
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
774
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
775
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
776
    def test_unversioned_paths_in_tree(self):
777
        tree1 = self.make_branch_and_tree('tree1')
778
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
779
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
780
        self.build_tree(['tree2/file', 'tree2/dir/'])
781
        # try:
782
        os.symlink('target', 'tree2/link')
783
        links_supported = True
784
        # except ???:
785
        #   links_supported = False
786
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
787
        tree1.lock_read()
788
        self.addCleanup(tree1.unlock)
789
        tree2.lock_read()
790
        self.addCleanup(tree2.unlock)
791
        expected = [
792
            self.unversioned(tree2, 'file'),
793
            self.unversioned(tree2, 'dir'),
794
            ]
795
        if links_supported:
796
            expected.append(self.unversioned(tree2, 'link'))
797
        expected = sorted(expected)
798
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
799
            want_unversioned=True))
800
801
    def test_unversioned_paths_in_tree_specific_files(self):
802
        tree1 = self.make_branch_and_tree('tree1')
803
        tree2 = self.make_to_branch_and_tree('tree2')
804
        self.build_tree(['tree2/file', 'tree2/dir/'])
805
        # try:
806
        os.symlink('target', 'tree2/link')
807
        links_supported = True
808
        # except ???:
809
        #   links_supported = False
810
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
811
        tree1.lock_read()
812
        self.addCleanup(tree1.unlock)
813
        tree2.lock_read()
814
        self.addCleanup(tree2.unlock)
815
        expected = [
816
            self.unversioned(tree2, 'file'),
817
            self.unversioned(tree2, 'dir'),
818
            ]
819
        specific_files=['file', 'dir']
820
        if links_supported:
821
            expected.append(self.unversioned(tree2, 'link'))
822
            specific_files.append('link')
823
        expected = sorted(expected)
824
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
825
            specific_files=specific_files, require_versioned=False,
826
            want_unversioned=True))
827
828
    def test_unversioned_paths_in_target_matching_source_old_names(self):
829
        # its likely that naive implementations of unversioned file support
830
        # will fail if the path was versioned, but is not any more, 
831
        # due to a rename, not due to unversioning it.
832
        # That is, if the old tree has a versioned file 'foo', and
833
        # the new tree has the same file but versioned as 'bar', and also
834
        # has an unknown file 'foo', we should get back output for
835
        # both foo and bar.
836
        tree1 = self.make_branch_and_tree('tree1')
837
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
838
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
839
        self.build_tree(['tree2/file', 'tree2/dir/',
840
            'tree1/file', 'tree2/movedfile',
841
            'tree1/dir/', 'tree2/moveddir/'])
842
        # try:
843
        os.symlink('target', 'tree1/link')
844
        os.symlink('target', 'tree2/link')
845
        os.symlink('target', 'tree2/movedlink')
846
        links_supported = True
847
        # except ???:
848
        #   links_supported = False
849
        tree1.add(['file', 'dir', 'link'], ['file-id', 'dir-id', 'link-id'])
850
        tree2.add(['movedfile', 'moveddir', 'movedlink'],
851
            ['file-id', 'dir-id', 'link-id'])
852
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
853
        root_id = tree1.path2id('')
854
        tree1.lock_read()
855
        self.addCleanup(tree1.unlock)
856
        tree2.lock_read()
857
        self.addCleanup(tree2.unlock)
858
        expected = [
859
            self.renamed(tree1, tree2, 'dir-id', False),
860
            self.renamed(tree1, tree2, 'file-id', True),
861
            self.unversioned(tree2, 'file'),
862
            self.unversioned(tree2, 'dir'),
863
            ]
864
        specific_files=['file', 'dir']
865
        if links_supported:
866
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
867
            expected.append(self.unversioned(tree2, 'link'))
868
            specific_files.append('link')
869
        expected = sorted(expected)
870
        # run once with, and once without specific files, to catch
871
        # potentially different code paths.
872
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
873
            require_versioned=False,
874
            want_unversioned=True))
875
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
876
            specific_files=specific_files, require_versioned=False,
877
            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.
878
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
879
    def test_unversioned_subtree_only_emits_root(self):
880
        tree1 = self.make_branch_and_tree('tree1')
881
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
882
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
883
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
884
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
885
        expected = [
886
            self.unversioned(tree2, 'dir'),
887
            ]
888
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
889
            want_unversioned=True))
890
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.
891
    def make_trees_with_symlinks(self):
892
        tree1 = self.make_branch_and_tree('tree1')
893
        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
894
        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.
895
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
896
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
897
        # try:
898
        os.symlink('original', 'tree1/changed')
899
        os.symlink('original', 'tree1/removed')
900
        os.symlink('original', 'tree1/tofile')
901
        os.symlink('original', 'tree1/todir')
902
        # we make the unchanged link point at unknown to catch incorrect
903
        # symlink-following code in the specified_files test.
904
        os.symlink('unknown', 'tree1/unchanged')
905
        os.symlink('new',      'tree2/added')
906
        os.symlink('new',      'tree2/changed')
907
        os.symlink('new',      'tree2/fromfile')
908
        os.symlink('new',      'tree2/fromdir')
909
        os.symlink('unknown', 'tree2/unchanged')
910
        from_paths_and_ids = [
911
            'fromdir',
912
            'fromfile',
913
            'changed',
914
            'removed',
915
            'todir',
916
            'tofile',
917
            'unchanged',
918
            ]
919
        to_paths_and_ids = [
920
            'added',
921
            'fromdir',
922
            'fromfile',
923
            'changed',
924
            'todir',
925
            'tofile',
926
            'unchanged',
927
            ]
928
        tree1.add(from_paths_and_ids, from_paths_and_ids)
929
        tree2.add(to_paths_and_ids, to_paths_and_ids)
930
        # except ???:
931
        #   raise TestSkipped('OS does not support symlinks')
932
        #   links_supported = False
933
        return self.mutable_trees_to_test_trees(tree1, tree2)
934
2255.2.182 by Martin Pool
merge dirstate and trunk
935
    def make_trees_with_subtrees(self):
936
        # trees containing tree references
937
        # TODO: might have to skip if the format can't do tree references
938
        tree1 = self.make_branch_and_tree('tree1')
939
        tree2 = self.make_to_branch_and_tree('tree2')
940
        self.build_tree(['tree1/fromdir/', 'tree1/common/',
941
            'tree2/todir/', 'tree2/common/'])
942
        # TODO: actually add the references
943
        return self.mutable_trees_to_test_trees(tree1, tree2)
944
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
945
    def test_versioned_symlinks(self):
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.
946
        tree1, tree2 = self.make_trees_with_symlinks()
947
        root_id = tree1.path2id('')
948
        tree1.lock_read()
949
        self.addCleanup(tree1.unlock)
950
        tree2.lock_read()
951
        self.addCleanup(tree2.unlock)
952
        expected = [
953
            self.unchanged(tree1, tree1.path2id('')),
954
            self.added(tree2, 'added'),
955
            self.content_changed(tree2, 'changed'),
956
            self.kind_changed(tree1, tree2, 'fromdir'),
957
            self.kind_changed(tree1, tree2, 'fromfile'),
958
            self.deleted(tree1, 'removed'),
959
            self.unchanged(tree2, 'unchanged'),
960
            self.unversioned(tree2, 'unknown'),
961
            self.kind_changed(tree1, tree2, 'todir'),
962
            self.kind_changed(tree1, tree2, 'tofile'),
963
            ]
964
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
965
        self.assertEqual(expected,
966
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
967
                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.
968
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
969
    def test_versioned_symlinks_specific_files(self):
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.
970
        tree1, tree2 = self.make_trees_with_symlinks()
971
        root_id = tree1.path2id('')
972
        tree1.lock_read()
973
        self.addCleanup(tree1.unlock)
974
        tree2.lock_read()
975
        self.addCleanup(tree2.unlock)
976
        expected = [
977
            self.added(tree2, 'added'),
978
            self.content_changed(tree2, 'changed'),
979
            self.kind_changed(tree1, tree2, 'fromdir'),
980
            self.kind_changed(tree1, tree2, 'fromfile'),
981
            self.deleted(tree1, 'removed'),
982
            self.kind_changed(tree1, tree2, 'todir'),
983
            self.kind_changed(tree1, tree2, 'tofile'),
984
            ]
985
        expected = sorted(expected)
986
        # we should get back just the changed links. We pass in 'unchanged' to
987
        # make sure that it is correctly not returned - and neither is the
988
        # unknown path 'unknown' which it points at.
989
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
990
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
991
            '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.
992
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
993
    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.
994
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
995
        tree1.lock_read()
996
        self.addCleanup(tree1.unlock)
997
        tree2.lock_read()
998
        self.addCleanup(tree2.unlock)
999
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1000
        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.
1001
1002
    def test_trees_with_special_names(self):
1003
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1004
        tree1.lock_read()
1005
        self.addCleanup(tree1.unlock)
1006
        tree2.lock_read()
1007
        self.addCleanup(tree2.unlock)
1008
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1009
                          if f_id.endswith('_f-id'))
1010
        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
1011
2255.2.182 by Martin Pool
merge dirstate and trunk
1012
    def test_trees_with_subtrees(self):
1013
        tree1, tree2 = self.make_trees_with_subtrees()
1014
        self.do_iter_changes(tree1, tree2)
1015
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1016
    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.
1017
        tree1 = self.make_branch_and_tree('tree1')
1018
        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
1019
        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.
1020
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1021
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1022
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1023
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1024
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1025
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1026
1027
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1028
        tree1.lock_read()
1029
        self.addCleanup(tree1.unlock)
1030
        tree2.lock_read()
1031
        self.addCleanup(tree2.unlock)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1032
        # 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.
1033
        expected = sorted([
1034
            self.content_changed(tree2, 'a-id'),
1035
            self.content_changed(tree2, 'g-id'),
1036
            self.deleted(tree1, 'b-id'),
1037
            self.deleted(tree1, 'c-id'),
1038
            self.deleted(tree1, 'd-id'),
1039
            self.deleted(tree1, 'e-id'),
1040
            ])
1041
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))