/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 the include_root option.
27
# TODO: test that renaming a directory x->y does not emit a rename for the
28
#       child x/a->y/a.
29
# TODO: test that renaming a directory x-> does not emit a rename for the child
30
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
31
#        -> that is, when the renamed parent is not processed by the function.
32
# TODO: test items are only emitted once when a specific_files list names a dir
33
#       whose parent is now a child.
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
34
# TODO: test specific_files when the target tree has a file and the source a
35
#       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
36
# 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.
37
#
38
# TODO: More comparisons between trees with subtrees in different states.
2255.2.236 by Martin Pool
Review cleanups: mostly updating or removing todo comments.
39
#
40
# TODO: Many tests start out by setting the tree roots ids the same, maybe
41
#       that should just be the default for these tests, by changing
42
#       make_branch_and_tree.  mbp 20070307
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
43
44
class TestCompare(TestCaseWithTwoTrees):
45
46
    def test_compare_empty_trees(self):
47
        tree1 = self.make_branch_and_tree('1')
48
        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
49
        tree2.set_root_id(tree1.get_root_id())
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
50
        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.
51
        tree2 = self.get_tree_no_parents_no_content(tree2)
52
        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.
53
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
54
        self.assertEqual([], d.added)
55
        self.assertEqual([], d.modified)
56
        self.assertEqual([], d.removed)
57
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
58
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
59
60
    def test_empty_to_abc_content(self):
61
        tree1 = self.make_branch_and_tree('1')
62
        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
63
        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.
64
        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.
65
        tree2 = self.get_tree_no_parents_abc_content(tree2)
66
        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.
67
        d = self.intertree_class(tree1, tree2).compare()
68
        self.assertEqual([('a', 'a-id', 'file'),
69
                          ('b', 'b-id', 'directory'),
70
                          ('b/c', 'c-id', 'file'),
71
                         ], d.added)
72
        self.assertEqual([], d.modified)
73
        self.assertEqual([], d.removed)
74
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
75
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
76
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
77
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
78
        # This test depends on the ability for some trees to have a difference
79
        # between a 'versioned present' and 'versioned not present' (aka
80
        # dangling) file. In this test there are two trees each with a separate
81
        # dangling file, and the dangling files should be considered absent for
82
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
83
        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.
84
        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
85
        tree2.set_root_id(tree1.get_root_id())
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
86
        self.build_tree(['2/a'])
87
        tree2.add('a')
88
        os.unlink('2/a')
89
        self.build_tree(['1/b'])
90
        tree1.add('b')
91
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
92
        # the conversion to test trees here will leave the trees intact for the
93
        # default intertree, but may perform a commit for other tree types,
94
        # which may reduce the validity of the test. XXX: Think about how to
95
        # address this.
96
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
97
        d = self.intertree_class(tree1, tree2).compare()
98
        self.assertEqual([], d.added)
99
        self.assertEqual([], d.modified)
100
        self.assertEqual([], d.removed)
101
        self.assertEqual([], d.renamed)
102
        self.assertEqual([], d.unchanged)
103
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
104
    def test_abc_content_to_empty(self):
105
        tree1 = self.make_branch_and_tree('1')
106
        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
107
        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.
108
        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.
109
        tree2 = self.get_tree_no_parents_no_content(tree2)
110
        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.
111
        d = self.intertree_class(tree1, tree2).compare()
112
        self.assertEqual([], d.added)
113
        self.assertEqual([], d.modified)
114
        self.assertEqual([('a', 'a-id', 'file'),
115
                          ('b', 'b-id', 'directory'),
116
                          ('b/c', 'c-id', 'file'),
117
                         ], d.removed)
118
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
119
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
120
121
    def test_content_modification(self):
122
        tree1 = self.make_branch_and_tree('1')
123
        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
124
        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.
125
        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.
126
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
127
        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.
128
        d = self.intertree_class(tree1, tree2).compare()
129
        self.assertEqual([], d.added)
130
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
131
        self.assertEqual([], d.removed)
132
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
133
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
134
        
135
    def test_meta_modification(self):
136
        tree1 = self.make_branch_and_tree('1')
137
        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
138
        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.
139
        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.
140
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
141
        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.
142
        d = self.intertree_class(tree1, tree2).compare()
143
        self.assertEqual([], d.added)
144
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
145
        self.assertEqual([], d.removed)
146
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
147
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
148
149
    def test_file_rename(self):
150
        tree1 = self.make_branch_and_tree('1')
151
        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
152
        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.
153
        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.
154
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
155
        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.
156
        d = self.intertree_class(tree1, tree2).compare()
157
        self.assertEqual([], d.added)
158
        self.assertEqual([], d.modified)
159
        self.assertEqual([], d.removed)
160
        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=...).
161
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
162
163
    def test_file_rename_and_modification(self):
164
        tree1 = self.make_branch_and_tree('1')
165
        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
166
        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.
167
        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.
168
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
169
        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.
170
        d = self.intertree_class(tree1, tree2).compare()
171
        self.assertEqual([], d.added)
172
        self.assertEqual([], d.modified)
173
        self.assertEqual([], d.removed)
174
        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=...).
175
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
176
177
    def test_file_rename_and_meta_modification(self):
178
        tree1 = self.make_branch_and_tree('1')
179
        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
180
        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.
181
        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.
182
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
183
        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.
184
        d = self.intertree_class(tree1, tree2).compare()
185
        self.assertEqual([], d.added)
186
        self.assertEqual([], d.modified)
187
        self.assertEqual([], d.removed)
188
        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=...).
189
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
190
191
    def test_empty_to_abc_content_a_only(self):
192
        tree1 = self.make_branch_and_tree('1')
193
        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
194
        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.
195
        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.
196
        tree2 = self.get_tree_no_parents_abc_content(tree2)
197
        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.
198
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
199
        self.assertEqual([('a', 'a-id', 'file')], d.added)
200
        self.assertEqual([], d.modified)
201
        self.assertEqual([], d.removed)
202
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
203
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
204
205
    def test_empty_to_abc_content_a_and_c_only(self):
206
        tree1 = self.make_branch_and_tree('1')
207
        tree2 = self.make_to_branch_and_tree('2')
208
        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.
209
        tree2 = self.get_tree_no_parents_abc_content(tree2)
210
        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.
211
        d = self.intertree_class(tree1, tree2).compare(
212
            specific_files=['a', 'b/c'])
213
        self.assertEqual(
214
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
215
            d.added)
216
        self.assertEqual([], d.modified)
217
        self.assertEqual([], d.removed)
218
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
219
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
220
221
    def test_empty_to_abc_content_b_only(self):
222
        """Restricting to a dir matches the children of the dir."""
223
        tree1 = self.make_branch_and_tree('1')
224
        tree2 = self.make_to_branch_and_tree('2')
225
        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.
226
        tree2 = self.get_tree_no_parents_abc_content(tree2)
227
        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.
228
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
229
        self.assertEqual(
230
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
231
            d.added)
232
        self.assertEqual([], d.modified)
233
        self.assertEqual([], d.removed)
234
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
235
        self.assertEqual([], d.unchanged)
236
237
    def test_unchanged_with_renames_and_modifications(self):
238
        """want_unchanged should generate a list of unchanged entries."""
239
        tree1 = self.make_branch_and_tree('1')
240
        tree2 = self.make_to_branch_and_tree('2')
241
        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.
242
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
243
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
244
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
245
        self.assertEqual([], d.added)
246
        self.assertEqual([], d.modified)
247
        self.assertEqual([], d.removed)
248
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
249
        self.assertEqual(
250
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
251
            d.unchanged)
252
253
    def test_extra_trees_finds_ids(self):
254
        """Ask for a delta between two trees with a path present in a third."""
255
        tree1 = self.make_branch_and_tree('1')
256
        tree2 = self.make_to_branch_and_tree('2')
257
        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.
258
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
259
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
260
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
261
        # 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.
262
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
263
        # the lookup, in merged trees it can be fast-pathed. We probably want
264
        # 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=...).
265
        tree3 = self.make_branch_and_tree('3')
266
        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.
267
        tree3.lock_read()
268
        self.addCleanup(tree3.unlock)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
269
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
270
        # has c-id at b/c with its exec flag toggled.
271
        # without extra_trees, we should get no modifications from this
272
        # so do one, to be sure the test is valid.
273
        d = self.intertree_class(tree1, tree2).compare(
274
            specific_files=['e'])
275
        self.assertEqual([], d.modified)
276
        # now give it an additional lookup:
277
        d = self.intertree_class(tree1, tree2).compare(
278
            specific_files=['e'], extra_trees=[tree3])
279
        self.assertEqual([], d.added)
280
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
281
        self.assertEqual([], d.removed)
282
        self.assertEqual([], d.renamed)
283
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
284
285
    def test_require_versioned(self):
286
        # this does not quite robustly test, as it is passing in missing paths
287
        # rather than present-but-not-versioned paths. At the moment there is
288
        # no mechanism for managing the test trees (which are readonly) to 
289
        # get present-but-not-versioned files for trees that can do that.
290
        tree1 = self.make_branch_and_tree('1')
291
        tree2 = self.make_to_branch_and_tree('2')
292
        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.
293
        tree2 = self.get_tree_no_parents_abc_content(tree2)
294
        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.
295
        self.assertRaises(errors.PathsNotVersionedError, 
296
            self.intertree_class(tree1, tree2).compare,
297
            specific_files=['d'],
298
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
299
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
300
    def test_default_ignores_unversioned_files(self):
301
        tree1 = self.make_branch_and_tree('tree1')
302
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
303
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
304
        self.build_tree(['tree1/a', 'tree1/c',
305
                         'tree2/a', 'tree2/b', 'tree2/c'])
306
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
307
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
308
309
        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.
310
        d = self.intertree_class(tree1, tree2).compare()
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
311
        self.assertEqual([], d.added)
312
        self.assertEqual([(u'a', 'a-id', 'file', True, False),
313
            (u'c', 'c-id', 'file', True, False)], d.modified)
314
        self.assertEqual([], d.removed)
315
        self.assertEqual([], d.renamed)
316
        self.assertEqual([], d.unchanged)
317
        self.assertEqual([], d.unversioned)
318
319
    def test_unversioned_paths_in_tree(self):
320
        tree1 = self.make_branch_and_tree('tree1')
321
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
322
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
323
        self.build_tree(['tree2/file', 'tree2/dir/'])
324
        # try:
325
        os.symlink('target', 'tree2/link')
326
        links_supported = True
327
        # except ???:
328
        #   links_supported = False
329
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
330
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
331
        self.assertEqual([], d.added)
332
        self.assertEqual([], d.modified)
333
        self.assertEqual([], d.removed)
334
        self.assertEqual([], d.renamed)
335
        self.assertEqual([], d.unchanged)
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
336
        self.assertEqual([(u'dir', None, 'directory'), (u'file', None, 'file'),
337
            (u'link', None, 'symlink')], d.unversioned)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
338
2012.1.1 by Aaron Bentley
Implement change iterator
339
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
340
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
341
    """Test the comparison iterator"""
342
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
343
    def do_iter_changes(self, tree1, tree2, **extra_args):
344
        """Helper to run _iter_changes from tree1 to tree2.
345
        
346
        :param tree1, tree2:  The source and target trees. These will be locked
347
            automatically.
348
        :param **extra_args: Extra args to pass to _iter_changes. This is not
349
            inspected by this test helper.
350
        """
351
        tree1.lock_read()
352
        tree2.lock_read()
353
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
354
            # sort order of output is not strictly defined
355
            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.
356
                ._iter_changes(**extra_args))
357
        finally:
358
            tree1.unlock()
359
            tree2.unlock()
360
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
361
    def make_tree_with_special_names(self):
362
        """Create a tree with filenames chosen to exercise the walk order."""
363
        tree1 = self.make_branch_and_tree('tree1')
364
        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
365
        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.
366
        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.
367
        tree2.commit('initial', rev_id='rev-1')
368
        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.
369
        return (tree1, tree2, paths, path_ids)
370
371
    def make_trees_with_special_names(self):
372
        """Both trees will use the special names.
373
374
        But the contents will differ for each file.
375
        """
376
        tree1 = self.make_branch_and_tree('tree1')
377
        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
378
        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.
379
        paths, path_ids = self._create_special_names(tree1, 'tree1')
380
        paths, path_ids = self._create_special_names(tree2, 'tree2')
381
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
382
        return (tree1, tree2, paths, path_ids)
383
384
    def _create_special_names(self, tree, base_path):
385
        """Create a tree with paths that expose differences in sort orders."""
386
        # Each directory will have a single file named 'f' inside
387
        dirs = ['a',
388
                'a-a',
389
                'a/a',
390
                'a/a-a',
391
                'a/a/a',
392
                'a/a/a-a',
393
                'a/a/a/a',
394
                'a/a/a/a-a',
395
                'a/a/a/a/a',
396
               ]
397
        with_slashes = []
398
        paths = []
399
        path_ids = []
400
        for d in dirs:
401
            with_slashes.append(base_path + '/' + d + '/')
402
            with_slashes.append(base_path + '/' + d + '/f')
403
            paths.append(d)
404
            paths.append(d+'/f')
405
            path_ids.append(d.replace('/', '_') + '-id')
406
            path_ids.append(d.replace('/', '_') + '_f-id')
407
        self.build_tree(with_slashes)
408
        tree.add(paths, path_ids)
409
        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.
410
2012.1.1 by Aaron Bentley
Implement change iterator
411
    def test_compare_empty_trees(self):
412
        tree1 = self.make_branch_and_tree('1')
413
        tree2 = self.make_to_branch_and_tree('2')
414
        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.
415
        tree2 = self.get_tree_no_parents_no_content(tree2)
416
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
417
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
418
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
419
    def added(self, tree, file_id):
420
        entry = tree.inventory[file_id]
421
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
422
        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.
423
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
424
                (None, entry.executable))
425
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.
426
    def content_changed(self, tree, file_id):
427
        entry = tree.inventory[file_id]
428
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
429
        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.
430
                (entry.name, entry.name), (entry.kind, entry.kind),
431
                (entry.executable, entry.executable))
432
433
    def kind_changed(self, from_tree, to_tree, file_id):
434
        old_entry = from_tree.inventory[file_id]
435
        new_entry = to_tree.inventory[file_id]
436
        path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
437
        from_path = from_tree.id2path(file_id)
438
        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.
439
                (old_entry.name, new_entry.name), (old_entry.kind, new_entry.kind),
440
                (old_entry.executable, new_entry.executable))
441
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
442
    def missing(self, file_id, from_path, to_path, parent_id, kind):
443
        _, from_basename = os.path.split(from_path)
444
        _, to_basename = os.path.split(to_path)
445
        # missing files have both paths, but no kind.
446
        return (file_id, (from_path, to_path), True, (True, True),
447
            (parent_id, parent_id),
448
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
449
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
450
    def deleted(self, tree, file_id):
451
        entry = tree.inventory[file_id]
452
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
453
        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.
454
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
455
                (entry.executable, None))
456
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
457
    def renamed(self, from_tree, to_tree, file_id, content_changed):
458
        from_entry = from_tree.inventory[file_id]
459
        to_entry = to_tree.inventory[file_id]
460
        from_path = from_tree.id2path(file_id)
461
        to_path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
462
        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.
463
            (from_entry.parent_id, to_entry.parent_id),
464
            (from_entry.name, to_entry.name),
465
            (from_entry.kind, to_entry.kind),
466
            (from_entry.executable, to_entry.executable))
467
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.
468
    def unchanged(self, tree, file_id):
469
        entry = tree.inventory[file_id]
470
        parent = entry.parent_id
471
        name = entry.name
472
        kind = entry.kind
473
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
474
        path = tree.id2path(file_id)
475
        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.
476
               (parent, parent), (name, name), (kind, kind),
477
               (executable, executable))
478
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
479
    def unversioned(self, tree, path):
480
        """Create an unversioned result."""
481
        _, basename = os.path.split(path)
482
        kind = file_kind(tree.abspath(path))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
483
        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.
484
                (None, basename), (None, kind),
485
                (None, False))
486
2012.1.1 by Aaron Bentley
Implement change iterator
487
    def test_empty_to_abc_content(self):
488
        tree1 = self.make_branch_and_tree('1')
489
        tree2 = self.make_to_branch_and_tree('2')
490
        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.
491
        tree2 = self.get_tree_no_parents_abc_content(tree2)
492
        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.
493
        tree1.lock_read()
494
        tree2.lock_read()
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
495
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
496
            self.added(tree2, 'root-id'),
497
            self.added(tree2, 'a-id'),
498
            self.added(tree2, 'b-id'),
499
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
500
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
501
        tree1.unlock()
502
        tree2.unlock()
503
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
504
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
505
    def test_empty_to_abc_content_a_only(self):
506
        tree1 = self.make_branch_and_tree('1')
507
        tree2 = self.make_to_branch_and_tree('2')
508
        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.
509
        tree2 = self.get_tree_no_parents_abc_content(tree2)
510
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
511
        tree1.lock_read()
512
        tree2.lock_read()
513
        self.assertEqual(
514
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
515
            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.
516
        tree1.unlock()
517
        tree2.unlock()
518
519
    def test_abc_content_to_empty_to_abc_content_a_only(self):
520
        tree1 = self.make_branch_and_tree('1')
521
        tree2 = self.make_to_branch_and_tree('2')
522
        tree1 = self.get_tree_no_parents_abc_content(tree1)
523
        tree2 = self.get_tree_no_parents_no_content(tree2)
524
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
525
        tree1.lock_read()
526
        tree2.lock_read()
527
        self.assertEqual(
528
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
529
            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.
530
        tree1.unlock()
531
        tree2.unlock()
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
532
533
    def test_empty_to_abc_content_a_and_c_only(self):
534
        tree1 = self.make_branch_and_tree('1')
535
        tree2 = self.make_to_branch_and_tree('2')
536
        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.
537
        tree2 = self.get_tree_no_parents_abc_content(tree2)
538
        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.
539
        tree1.lock_read()
540
        tree2.lock_read()
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
541
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
542
        tree1.unlock()
543
        tree2.unlock()
544
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
545
            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
546
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
547
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
548
        tree1 = self.make_branch_and_tree('1')
549
        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.
550
        tree1 = self.get_tree_no_parents_abc_content(tree1)
551
        tree2 = self.get_tree_no_parents_no_content(tree2)
552
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
553
        tree1.lock_read()
554
        tree2.lock_read()
2012.1.1 by Aaron Bentley
Implement change iterator
555
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
556
            entry = tree1.inventory[file_id]
557
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
558
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
559
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
560
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
561
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
562
        expected_results = sorted([
563
            self.added(tree2, 'empty-root-id'),
564
            deleted('root-id'), deleted('a-id'),
565
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
566
        tree1.unlock()
567
        tree2.unlock()
568
        self.assertEqual(
569
            expected_results,
570
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
571
572
    def test_content_modification(self):
573
        tree1 = self.make_branch_and_tree('1')
574
        tree2 = self.make_to_branch_and_tree('2')
575
        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.
576
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
577
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
578
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
579
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
580
                           (root_id, root_id), ('a', 'a'),
581
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
582
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
583
584
    def test_meta_modification(self):
585
        tree1 = self.make_branch_and_tree('1')
586
        tree2 = self.make_to_branch_and_tree('2')
587
        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.
588
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
589
        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.
590
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
591
                           ('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.
592
                          (False, True))],
593
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
594
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
595
    def test_empty_dir(self):
596
        """an empty dir should not cause glitches to surrounding files."""
597
        tree1 = self.make_branch_and_tree('1')
598
        tree2 = self.make_to_branch_and_tree('2')
599
        tree1 = self.get_tree_no_parents_abc_content(tree1)
600
        tree2 = self.get_tree_no_parents_abc_content(tree2)
601
        # the pathname is chosen to fall between 'a' and 'b'.
602
        self.build_tree(['1/a-empty/', '2/a-empty/'])
603
        tree1.add(['a-empty'], ['a-empty'])
604
        tree2.add(['a-empty'], ['a-empty'])
605
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
606
        expected = []
607
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
608
2012.1.1 by Aaron Bentley
Implement change iterator
609
    def test_file_rename(self):
610
        tree1 = self.make_branch_and_tree('1')
611
        tree2 = self.make_to_branch_and_tree('2')
612
        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.
613
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
614
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
615
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
616
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
617
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
618
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
619
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
620
621
    def test_file_rename_and_modification(self):
622
        tree1 = self.make_branch_and_tree('1')
623
        tree2 = self.make_to_branch_and_tree('2')
624
        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.
625
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
626
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
627
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
628
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
629
                           (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.
630
                           (False, False))],
631
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
632
633
    def test_file_rename_and_meta_modification(self):
634
        tree1 = self.make_branch_and_tree('1')
635
        tree2 = self.make_to_branch_and_tree('2')
636
        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.
637
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
638
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
639
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
640
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
641
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
642
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
643
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
644
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
645
    def test_missing_in_target(self):
646
        """Test with the target files versioned but absent from disk."""
647
        tree1 = self.make_branch_and_tree('1')
648
        tree2 = self.make_to_branch_and_tree('2')
649
        tree1 = self.get_tree_no_parents_abc_content(tree1)
650
        tree2 = self.get_tree_no_parents_abc_content(tree2)
651
        os.unlink('2/a')
652
        shutil.rmtree('2/b')
653
        # TODO ? have a symlink here?
654
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
655
        root_id = tree1.path2id('')
656
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
657
            self.missing('a-id', 'a', 'a', root_id, 'file'),
658
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
659
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
660
            ])
661
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
662
663
    def test_missing_and_renamed(self):
664
        tree1 = self.make_branch_and_tree('tree1')
665
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
666
        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.
667
        self.build_tree(['tree1/file'])
668
        tree1.add(['file'], ['file-id'])
669
        self.build_tree(['tree2/directory/'])
670
        tree2.add(['directory'], ['file-id'])
671
        os.rmdir('tree2/directory')
672
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
673
        tree1.lock_read()
674
        self.addCleanup(tree1.unlock)
675
        tree2.lock_read()
676
        self.addCleanup(tree2.unlock)
677
        root_id = tree1.path2id('')
678
        expected = sorted([
679
            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.
680
            ])
681
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
682
2012.1.1 by Aaron Bentley
Implement change iterator
683
    def test_unchanged_with_renames_and_modifications(self):
684
        """want_unchanged should generate a list of unchanged entries."""
685
        tree1 = self.make_branch_and_tree('1')
686
        tree2 = self.make_to_branch_and_tree('2')
687
        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.
688
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
689
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
690
        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.
691
        tree1.lock_read()
692
        self.addCleanup(tree1.unlock)
693
        tree2.lock_read()
694
        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.
695
        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.
696
            self.unchanged(tree1, 'b-id'),
697
            ('a-id', ('a', 'd'), True, (True, True),
698
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
699
            (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.
700
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
701
702
    def test_compare_subtrees(self):
703
        """want_unchanged should generate a list of unchanged entries."""
704
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
705
        if not tree1.supports_tree_reference():
706
            raise tests.TestSkipped('Tree %s does not support references'
707
                % (tree1,))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
708
        tree1.set_root_id('root-id')
709
        subtree1 = self.make_branch_and_tree('1/sub')
710
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
711
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
712
713
        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
714
        if not tree2.supports_tree_reference():
715
            raise tests.TestSkipped('Tree %s does not support references'
716
                % (tree2,))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
717
        tree2.set_root_id('root-id')
718
        subtree2 = self.make_to_branch_and_tree('2/sub')
719
        subtree2.set_root_id('subtree-id')
720
        tree2.add_reference(subtree2)
2255.13.1 by Martin Pool
review fixes from robert
721
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
722
        tree1.lock_read()
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
723
        self.addCleanup(tree1.unlock)
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
724
        tree2.lock_read()
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
725
        self.addCleanup(tree2.unlock)
726
        self.assertEqual([], list(tree2._iter_changes(tree1)))
727
        subtree1.commit('commit', rev_id='commit-a')
728
        self.assertEqual([
729
            ('root-id',
730
             (u'', u''),
731
             False,
732
             (True, True),
733
             (None, None),
734
             (u'', u''),
735
             ('directory', 'directory'),
736
             (False, False)),
737
            ('subtree-id',
738
             ('sub', 'sub',),
739
             False,
740
             (True, True),
741
             ('root-id', 'root-id'),
742
             ('sub', 'sub'),
743
             ('tree-reference', 'tree-reference'),
744
             (False, False))],
745
                         list(tree2._iter_changes(tree1,
746
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
747
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
748
    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.
749
        tree1 = self.make_branch_and_tree('tree1')
750
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
751
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
752
        self.build_tree(['tree1/a', 'tree1/c',
753
                         'tree2/a', 'tree2/b', 'tree2/c'])
754
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
755
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
756
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
757
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
758
        tree1.lock_read()
759
        self.addCleanup(tree1.unlock)
760
        tree2.lock_read()
761
        self.addCleanup(tree2.unlock)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
762
763
        # We should ignore the fact that 'b' exists in tree-2
764
        # because the want_unversioned parameter was not given.
765
        expected = sorted([
766
            self.content_changed(tree2, 'a-id'),
767
            self.content_changed(tree2, 'c-id'),
768
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
769
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
770
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
771
    def test_unversioned_paths_in_tree(self):
772
        tree1 = self.make_branch_and_tree('tree1')
773
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
774
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
775
        self.build_tree(['tree2/file', 'tree2/dir/'])
776
        # try:
777
        os.symlink('target', 'tree2/link')
778
        links_supported = True
779
        # except ???:
780
        #   links_supported = False
781
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
782
        tree1.lock_read()
783
        self.addCleanup(tree1.unlock)
784
        tree2.lock_read()
785
        self.addCleanup(tree2.unlock)
786
        expected = [
787
            self.unversioned(tree2, 'file'),
788
            self.unversioned(tree2, 'dir'),
789
            ]
790
        if links_supported:
791
            expected.append(self.unversioned(tree2, 'link'))
792
        expected = sorted(expected)
793
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
794
            want_unversioned=True))
795
796
    def test_unversioned_paths_in_tree_specific_files(self):
797
        tree1 = self.make_branch_and_tree('tree1')
798
        tree2 = self.make_to_branch_and_tree('tree2')
799
        self.build_tree(['tree2/file', 'tree2/dir/'])
800
        # try:
801
        os.symlink('target', 'tree2/link')
802
        links_supported = True
803
        # except ???:
804
        #   links_supported = False
805
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
806
        tree1.lock_read()
807
        self.addCleanup(tree1.unlock)
808
        tree2.lock_read()
809
        self.addCleanup(tree2.unlock)
810
        expected = [
811
            self.unversioned(tree2, 'file'),
812
            self.unversioned(tree2, 'dir'),
813
            ]
814
        specific_files=['file', 'dir']
815
        if links_supported:
816
            expected.append(self.unversioned(tree2, 'link'))
817
            specific_files.append('link')
818
        expected = sorted(expected)
819
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
820
            specific_files=specific_files, require_versioned=False,
821
            want_unversioned=True))
822
823
    def test_unversioned_paths_in_target_matching_source_old_names(self):
824
        # its likely that naive implementations of unversioned file support
825
        # will fail if the path was versioned, but is not any more, 
826
        # due to a rename, not due to unversioning it.
827
        # That is, if the old tree has a versioned file 'foo', and
828
        # the new tree has the same file but versioned as 'bar', and also
829
        # has an unknown file 'foo', we should get back output for
830
        # both foo and bar.
831
        tree1 = self.make_branch_and_tree('tree1')
832
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
833
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
834
        self.build_tree(['tree2/file', 'tree2/dir/',
835
            'tree1/file', 'tree2/movedfile',
836
            'tree1/dir/', 'tree2/moveddir/'])
837
        # try:
838
        os.symlink('target', 'tree1/link')
839
        os.symlink('target', 'tree2/link')
840
        os.symlink('target', 'tree2/movedlink')
841
        links_supported = True
842
        # except ???:
843
        #   links_supported = False
844
        tree1.add(['file', 'dir', 'link'], ['file-id', 'dir-id', 'link-id'])
845
        tree2.add(['movedfile', 'moveddir', 'movedlink'],
846
            ['file-id', 'dir-id', 'link-id'])
847
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
848
        root_id = tree1.path2id('')
849
        tree1.lock_read()
850
        self.addCleanup(tree1.unlock)
851
        tree2.lock_read()
852
        self.addCleanup(tree2.unlock)
853
        expected = [
854
            self.renamed(tree1, tree2, 'dir-id', False),
855
            self.renamed(tree1, tree2, 'file-id', True),
856
            self.unversioned(tree2, 'file'),
857
            self.unversioned(tree2, 'dir'),
858
            ]
859
        specific_files=['file', 'dir']
860
        if links_supported:
861
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
862
            expected.append(self.unversioned(tree2, 'link'))
863
            specific_files.append('link')
864
        expected = sorted(expected)
865
        # run once with, and once without specific files, to catch
866
        # potentially different code paths.
867
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
868
            require_versioned=False,
869
            want_unversioned=True))
870
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
871
            specific_files=specific_files, require_versioned=False,
872
            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.
873
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
874
    def test_unversioned_subtree_only_emits_root(self):
875
        tree1 = self.make_branch_and_tree('tree1')
876
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
877
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
878
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
879
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
880
        expected = [
881
            self.unversioned(tree2, 'dir'),
882
            ]
883
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
884
            want_unversioned=True))
885
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.
886
    def make_trees_with_symlinks(self):
887
        tree1 = self.make_branch_and_tree('tree1')
888
        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
889
        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.
890
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
891
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
892
        # try:
893
        os.symlink('original', 'tree1/changed')
894
        os.symlink('original', 'tree1/removed')
895
        os.symlink('original', 'tree1/tofile')
896
        os.symlink('original', 'tree1/todir')
897
        # we make the unchanged link point at unknown to catch incorrect
898
        # symlink-following code in the specified_files test.
899
        os.symlink('unknown', 'tree1/unchanged')
900
        os.symlink('new',      'tree2/added')
901
        os.symlink('new',      'tree2/changed')
902
        os.symlink('new',      'tree2/fromfile')
903
        os.symlink('new',      'tree2/fromdir')
904
        os.symlink('unknown', 'tree2/unchanged')
905
        from_paths_and_ids = [
906
            'fromdir',
907
            'fromfile',
908
            'changed',
909
            'removed',
910
            'todir',
911
            'tofile',
912
            'unchanged',
913
            ]
914
        to_paths_and_ids = [
915
            'added',
916
            'fromdir',
917
            'fromfile',
918
            'changed',
919
            'todir',
920
            'tofile',
921
            'unchanged',
922
            ]
923
        tree1.add(from_paths_and_ids, from_paths_and_ids)
924
        tree2.add(to_paths_and_ids, to_paths_and_ids)
925
        # except ???:
926
        #   raise TestSkipped('OS does not support symlinks')
927
        #   links_supported = False
928
        return self.mutable_trees_to_test_trees(tree1, tree2)
929
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
930
    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.
931
        tree1, tree2 = self.make_trees_with_symlinks()
932
        root_id = tree1.path2id('')
933
        tree1.lock_read()
934
        self.addCleanup(tree1.unlock)
935
        tree2.lock_read()
936
        self.addCleanup(tree2.unlock)
937
        expected = [
938
            self.unchanged(tree1, tree1.path2id('')),
939
            self.added(tree2, 'added'),
940
            self.content_changed(tree2, 'changed'),
941
            self.kind_changed(tree1, tree2, 'fromdir'),
942
            self.kind_changed(tree1, tree2, 'fromfile'),
943
            self.deleted(tree1, 'removed'),
944
            self.unchanged(tree2, 'unchanged'),
945
            self.unversioned(tree2, 'unknown'),
946
            self.kind_changed(tree1, tree2, 'todir'),
947
            self.kind_changed(tree1, tree2, 'tofile'),
948
            ]
949
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
950
        self.assertEqual(expected,
951
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
952
                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.
953
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
954
    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.
955
        tree1, tree2 = self.make_trees_with_symlinks()
956
        root_id = tree1.path2id('')
957
        tree1.lock_read()
958
        self.addCleanup(tree1.unlock)
959
        tree2.lock_read()
960
        self.addCleanup(tree2.unlock)
961
        expected = [
962
            self.added(tree2, 'added'),
963
            self.content_changed(tree2, 'changed'),
964
            self.kind_changed(tree1, tree2, 'fromdir'),
965
            self.kind_changed(tree1, tree2, 'fromfile'),
966
            self.deleted(tree1, 'removed'),
967
            self.kind_changed(tree1, tree2, 'todir'),
968
            self.kind_changed(tree1, tree2, 'tofile'),
969
            ]
970
        expected = sorted(expected)
971
        # we should get back just the changed links. We pass in 'unchanged' to
972
        # make sure that it is correctly not returned - and neither is the
973
        # unknown path 'unknown' which it points at.
974
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
975
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
976
            '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.
977
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
978
    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.
979
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
980
        tree1.lock_read()
981
        self.addCleanup(tree1.unlock)
982
        tree2.lock_read()
983
        self.addCleanup(tree2.unlock)
984
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
985
        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.
986
987
    def test_trees_with_special_names(self):
988
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
989
        tree1.lock_read()
990
        self.addCleanup(tree1.unlock)
991
        tree2.lock_read()
992
        self.addCleanup(tree2.unlock)
993
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
994
                          if f_id.endswith('_f-id'))
995
        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
996
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
997
    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.
998
        tree1 = self.make_branch_and_tree('tree1')
999
        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
1000
        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.
1001
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1002
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1003
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1004
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1005
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1006
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1007
1008
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
1009
        tree1.lock_read()
1010
        self.addCleanup(tree1.unlock)
1011
        tree2.lock_read()
1012
        self.addCleanup(tree2.unlock)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1013
        # 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.
1014
        expected = sorted([
1015
            self.content_changed(tree2, 'a-id'),
1016
            self.content_changed(tree2, 'g-id'),
1017
            self.deleted(tree1, 'b-id'),
1018
            self.deleted(tree1, 'c-id'),
1019
            self.deleted(tree1, 'd-id'),
1020
            self.deleted(tree1, 'e-id'),
1021
            ])
1022
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))