/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
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
723
        tree1.lock_read()
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
724
        self.addCleanup(tree1.unlock)
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
725
        tree2.lock_read()
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
726
        self.addCleanup(tree2.unlock)
727
        self.assertEqual([], list(tree2._iter_changes(tree1)))
728
        subtree1.commit('commit', rev_id='commit-a')
729
        self.assertEqual([
730
            ('root-id',
731
             (u'', u''),
732
             False,
733
             (True, True),
734
             (None, None),
735
             (u'', u''),
736
             ('directory', 'directory'),
737
             (False, False)),
738
            ('subtree-id',
739
             ('sub', 'sub',),
740
             False,
741
             (True, True),
742
             ('root-id', 'root-id'),
743
             ('sub', 'sub'),
744
             ('tree-reference', 'tree-reference'),
745
             (False, False))],
746
                         list(tree2._iter_changes(tree1,
747
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
748
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
749
    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.
750
        tree1 = self.make_branch_and_tree('tree1')
751
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
752
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
753
        self.build_tree(['tree1/a', 'tree1/c',
754
                         'tree2/a', 'tree2/b', 'tree2/c'])
755
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
756
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
757
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
758
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
759
        tree1.lock_read()
760
        self.addCleanup(tree1.unlock)
761
        tree2.lock_read()
762
        self.addCleanup(tree2.unlock)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
763
764
        # We should ignore the fact that 'b' exists in tree-2
765
        # because the want_unversioned parameter was not given.
766
        expected = sorted([
767
            self.content_changed(tree2, 'a-id'),
768
            self.content_changed(tree2, 'c-id'),
769
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
770
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
771
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
772
    def test_unversioned_paths_in_tree(self):
773
        tree1 = self.make_branch_and_tree('tree1')
774
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
775
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
776
        self.build_tree(['tree2/file', 'tree2/dir/'])
777
        # try:
778
        os.symlink('target', 'tree2/link')
779
        links_supported = True
780
        # except ???:
781
        #   links_supported = False
782
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
783
        tree1.lock_read()
784
        self.addCleanup(tree1.unlock)
785
        tree2.lock_read()
786
        self.addCleanup(tree2.unlock)
787
        expected = [
788
            self.unversioned(tree2, 'file'),
789
            self.unversioned(tree2, 'dir'),
790
            ]
791
        if links_supported:
792
            expected.append(self.unversioned(tree2, 'link'))
793
        expected = sorted(expected)
794
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
795
            want_unversioned=True))
796
797
    def test_unversioned_paths_in_tree_specific_files(self):
798
        tree1 = self.make_branch_and_tree('tree1')
799
        tree2 = self.make_to_branch_and_tree('tree2')
800
        self.build_tree(['tree2/file', 'tree2/dir/'])
801
        # try:
802
        os.symlink('target', 'tree2/link')
803
        links_supported = True
804
        # except ???:
805
        #   links_supported = False
806
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
807
        tree1.lock_read()
808
        self.addCleanup(tree1.unlock)
809
        tree2.lock_read()
810
        self.addCleanup(tree2.unlock)
811
        expected = [
812
            self.unversioned(tree2, 'file'),
813
            self.unversioned(tree2, 'dir'),
814
            ]
815
        specific_files=['file', 'dir']
816
        if links_supported:
817
            expected.append(self.unversioned(tree2, 'link'))
818
            specific_files.append('link')
819
        expected = sorted(expected)
820
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
821
            specific_files=specific_files, require_versioned=False,
822
            want_unversioned=True))
823
824
    def test_unversioned_paths_in_target_matching_source_old_names(self):
825
        # its likely that naive implementations of unversioned file support
826
        # will fail if the path was versioned, but is not any more, 
827
        # due to a rename, not due to unversioning it.
828
        # That is, if the old tree has a versioned file 'foo', and
829
        # the new tree has the same file but versioned as 'bar', and also
830
        # has an unknown file 'foo', we should get back output for
831
        # both foo and bar.
832
        tree1 = self.make_branch_and_tree('tree1')
833
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
834
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
835
        self.build_tree(['tree2/file', 'tree2/dir/',
836
            'tree1/file', 'tree2/movedfile',
837
            'tree1/dir/', 'tree2/moveddir/'])
838
        # try:
839
        os.symlink('target', 'tree1/link')
840
        os.symlink('target', 'tree2/link')
841
        os.symlink('target', 'tree2/movedlink')
842
        links_supported = True
843
        # except ???:
844
        #   links_supported = False
845
        tree1.add(['file', 'dir', 'link'], ['file-id', 'dir-id', 'link-id'])
846
        tree2.add(['movedfile', 'moveddir', 'movedlink'],
847
            ['file-id', 'dir-id', 'link-id'])
848
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
849
        root_id = tree1.path2id('')
850
        tree1.lock_read()
851
        self.addCleanup(tree1.unlock)
852
        tree2.lock_read()
853
        self.addCleanup(tree2.unlock)
854
        expected = [
855
            self.renamed(tree1, tree2, 'dir-id', False),
856
            self.renamed(tree1, tree2, 'file-id', True),
857
            self.unversioned(tree2, 'file'),
858
            self.unversioned(tree2, 'dir'),
859
            ]
860
        specific_files=['file', 'dir']
861
        if links_supported:
862
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
863
            expected.append(self.unversioned(tree2, 'link'))
864
            specific_files.append('link')
865
        expected = sorted(expected)
866
        # run once with, and once without specific files, to catch
867
        # potentially different code paths.
868
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
869
            require_versioned=False,
870
            want_unversioned=True))
871
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
872
            specific_files=specific_files, require_versioned=False,
873
            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.
874
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
875
    def test_unversioned_subtree_only_emits_root(self):
876
        tree1 = self.make_branch_and_tree('tree1')
877
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
878
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
879
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
880
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
881
        expected = [
882
            self.unversioned(tree2, 'dir'),
883
            ]
884
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
885
            want_unversioned=True))
886
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.
887
    def make_trees_with_symlinks(self):
888
        tree1 = self.make_branch_and_tree('tree1')
889
        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
890
        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.
891
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
892
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
893
        # try:
894
        os.symlink('original', 'tree1/changed')
895
        os.symlink('original', 'tree1/removed')
896
        os.symlink('original', 'tree1/tofile')
897
        os.symlink('original', 'tree1/todir')
898
        # we make the unchanged link point at unknown to catch incorrect
899
        # symlink-following code in the specified_files test.
900
        os.symlink('unknown', 'tree1/unchanged')
901
        os.symlink('new',      'tree2/added')
902
        os.symlink('new',      'tree2/changed')
903
        os.symlink('new',      'tree2/fromfile')
904
        os.symlink('new',      'tree2/fromdir')
905
        os.symlink('unknown', 'tree2/unchanged')
906
        from_paths_and_ids = [
907
            'fromdir',
908
            'fromfile',
909
            'changed',
910
            'removed',
911
            'todir',
912
            'tofile',
913
            'unchanged',
914
            ]
915
        to_paths_and_ids = [
916
            'added',
917
            'fromdir',
918
            'fromfile',
919
            'changed',
920
            'todir',
921
            'tofile',
922
            'unchanged',
923
            ]
924
        tree1.add(from_paths_and_ids, from_paths_and_ids)
925
        tree2.add(to_paths_and_ids, to_paths_and_ids)
926
        # except ???:
927
        #   raise TestSkipped('OS does not support symlinks')
928
        #   links_supported = False
929
        return self.mutable_trees_to_test_trees(tree1, tree2)
930
2255.2.182 by Martin Pool
merge dirstate and trunk
931
    def make_trees_with_subtrees(self):
932
        # trees containing tree references
933
        # TODO: might have to skip if the format can't do tree references
934
        tree1 = self.make_branch_and_tree('tree1')
935
        tree2 = self.make_to_branch_and_tree('tree2')
936
        self.build_tree(['tree1/fromdir/', 'tree1/common/',
937
            'tree2/todir/', 'tree2/common/'])
938
        # TODO: actually add the references
939
        return self.mutable_trees_to_test_trees(tree1, tree2)
940
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
941
    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.
942
        tree1, tree2 = self.make_trees_with_symlinks()
943
        root_id = tree1.path2id('')
944
        tree1.lock_read()
945
        self.addCleanup(tree1.unlock)
946
        tree2.lock_read()
947
        self.addCleanup(tree2.unlock)
948
        expected = [
949
            self.unchanged(tree1, tree1.path2id('')),
950
            self.added(tree2, 'added'),
951
            self.content_changed(tree2, 'changed'),
952
            self.kind_changed(tree1, tree2, 'fromdir'),
953
            self.kind_changed(tree1, tree2, 'fromfile'),
954
            self.deleted(tree1, 'removed'),
955
            self.unchanged(tree2, 'unchanged'),
956
            self.unversioned(tree2, 'unknown'),
957
            self.kind_changed(tree1, tree2, 'todir'),
958
            self.kind_changed(tree1, tree2, 'tofile'),
959
            ]
960
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
961
        self.assertEqual(expected,
962
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
963
                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.
964
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
965
    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.
966
        tree1, tree2 = self.make_trees_with_symlinks()
967
        root_id = tree1.path2id('')
968
        tree1.lock_read()
969
        self.addCleanup(tree1.unlock)
970
        tree2.lock_read()
971
        self.addCleanup(tree2.unlock)
972
        expected = [
973
            self.added(tree2, 'added'),
974
            self.content_changed(tree2, 'changed'),
975
            self.kind_changed(tree1, tree2, 'fromdir'),
976
            self.kind_changed(tree1, tree2, 'fromfile'),
977
            self.deleted(tree1, 'removed'),
978
            self.kind_changed(tree1, tree2, 'todir'),
979
            self.kind_changed(tree1, tree2, 'tofile'),
980
            ]
981
        expected = sorted(expected)
982
        # we should get back just the changed links. We pass in 'unchanged' to
983
        # make sure that it is correctly not returned - and neither is the
984
        # unknown path 'unknown' which it points at.
985
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
986
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
987
            '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.
988
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
989
    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.
990
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
991
        tree1.lock_read()
992
        self.addCleanup(tree1.unlock)
993
        tree2.lock_read()
994
        self.addCleanup(tree2.unlock)
995
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
996
        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.
997
998
    def test_trees_with_special_names(self):
999
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1000
        tree1.lock_read()
1001
        self.addCleanup(tree1.unlock)
1002
        tree2.lock_read()
1003
        self.addCleanup(tree2.unlock)
1004
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1005
                          if f_id.endswith('_f-id'))
1006
        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
1007
2255.2.182 by Martin Pool
merge dirstate and trunk
1008
    def test_trees_with_subtrees(self):
1009
        tree1, tree2 = self.make_trees_with_subtrees()
1010
        self.do_iter_changes(tree1, tree2)
1011
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1012
    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.
1013
        tree1 = self.make_branch_and_tree('tree1')
1014
        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
1015
        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.
1016
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1017
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1018
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1019
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1020
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1021
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1022
1023
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1024
        tree1.lock_read()
1025
        self.addCleanup(tree1.unlock)
1026
        tree2.lock_read()
1027
        self.addCleanup(tree2.unlock)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1028
        # 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.
1029
        expected = sorted([
1030
            self.content_changed(tree2, 'a-id'),
1031
            self.content_changed(tree2, 'g-id'),
1032
            self.deleted(tree1, 'b-id'),
1033
            self.deleted(tree1, 'c-id'),
1034
            self.deleted(tree1, 'd-id'),
1035
            self.deleted(tree1, 'e-id'),
1036
            ])
1037
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))