/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2255.2.152 by Martin Pool
(broken) merge aaron's workingtree format changes
1
# Copyright (C) 2006, 2007 Canonical Ltd
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for the InterTree.compare() function."""
18
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
19
import os
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
20
import shutil
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
21
2255.6.4 by Aaron Bentley
merge from dirstate
22
from bzrlib import errors, tests, workingtree_4
2321.3.4 by Alexander Belchenko
test intertree_implementations: skip tests with symlinks on platforms that don't have symlinks support
23
from bzrlib.osutils import file_kind, has_symlinks
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
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
361
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
362
        """Convert the working trees into test trees.
363
364
        Read lock them, and add the unlock to the cleanup.
365
        """
366
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
367
        tree1.lock_read()
368
        self.addCleanup(tree1.unlock)
369
        tree2.lock_read()
370
        self.addCleanup(tree2.unlock)
371
        return tree1, tree2
372
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
373
    def make_tree_with_special_names(self):
374
        """Create a tree with filenames chosen to exercise the walk order."""
375
        tree1 = self.make_branch_and_tree('tree1')
376
        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
377
        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.
378
        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.
379
        tree2.commit('initial', rev_id='rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
380
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
381
        return (tree1, tree2, paths, path_ids)
382
383
    def make_trees_with_special_names(self):
384
        """Both trees will use the special names.
385
386
        But the contents will differ for each file.
387
        """
388
        tree1 = self.make_branch_and_tree('tree1')
389
        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
390
        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.
391
        paths, path_ids = self._create_special_names(tree1, 'tree1')
392
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
393
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.22 by John Arbash Meinel
add a test that shows _iter_changes works when only contents have changed, and nothing is considered newly added.
394
        return (tree1, tree2, paths, path_ids)
395
396
    def _create_special_names(self, tree, base_path):
397
        """Create a tree with paths that expose differences in sort orders."""
398
        # Each directory will have a single file named 'f' inside
399
        dirs = ['a',
400
                'a-a',
401
                'a/a',
402
                'a/a-a',
403
                'a/a/a',
404
                'a/a/a-a',
405
                'a/a/a/a',
406
                'a/a/a/a-a',
407
                'a/a/a/a/a',
408
               ]
409
        with_slashes = []
410
        paths = []
411
        path_ids = []
412
        for d in dirs:
413
            with_slashes.append(base_path + '/' + d + '/')
414
            with_slashes.append(base_path + '/' + d + '/f')
415
            paths.append(d)
416
            paths.append(d+'/f')
417
            path_ids.append(d.replace('/', '_') + '-id')
418
            path_ids.append(d.replace('/', '_') + '_f-id')
419
        self.build_tree(with_slashes)
420
        tree.add(paths, path_ids)
421
        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.
422
2012.1.1 by Aaron Bentley
Implement change iterator
423
    def test_compare_empty_trees(self):
424
        tree1 = self.make_branch_and_tree('1')
425
        tree2 = self.make_to_branch_and_tree('2')
426
        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.
427
        tree2 = self.get_tree_no_parents_no_content(tree2)
428
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
429
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
430
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
431
    def added(self, tree, file_id):
432
        entry = tree.inventory[file_id]
433
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
434
        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.
435
                (None, entry.name), (None, entry.kind),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
436
                (None, entry.executable))
437
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.
438
    def content_changed(self, tree, file_id):
439
        entry = tree.inventory[file_id]
440
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
441
        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.
442
                (entry.name, entry.name), (entry.kind, entry.kind),
443
                (entry.executable, entry.executable))
444
445
    def kind_changed(self, from_tree, to_tree, file_id):
446
        old_entry = from_tree.inventory[file_id]
447
        new_entry = to_tree.inventory[file_id]
448
        path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
449
        from_path = from_tree.id2path(file_id)
450
        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.
451
                (old_entry.name, new_entry.name), (old_entry.kind, new_entry.kind),
452
                (old_entry.executable, new_entry.executable))
453
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
454
    def missing(self, file_id, from_path, to_path, parent_id, kind):
455
        _, from_basename = os.path.split(from_path)
456
        _, to_basename = os.path.split(to_path)
457
        # missing files have both paths, but no kind.
458
        return (file_id, (from_path, to_path), True, (True, True),
459
            (parent_id, parent_id),
460
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
461
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
462
    def deleted(self, tree, file_id):
463
        entry = tree.inventory[file_id]
464
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
465
        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.
466
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
467
                (entry.executable, None))
468
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
469
    def renamed(self, from_tree, to_tree, file_id, content_changed):
470
        from_entry = from_tree.inventory[file_id]
471
        to_entry = to_tree.inventory[file_id]
472
        from_path = from_tree.id2path(file_id)
473
        to_path = to_tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
474
        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.
475
            (from_entry.parent_id, to_entry.parent_id),
476
            (from_entry.name, to_entry.name),
477
            (from_entry.kind, to_entry.kind),
478
            (from_entry.executable, to_entry.executable))
479
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.
480
    def unchanged(self, tree, file_id):
481
        entry = tree.inventory[file_id]
482
        parent = entry.parent_id
483
        name = entry.name
484
        kind = entry.kind
485
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
486
        path = tree.id2path(file_id)
487
        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.
488
               (parent, parent), (name, name), (kind, kind),
489
               (executable, executable))
490
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
491
    def unversioned(self, tree, path):
492
        """Create an unversioned result."""
493
        _, basename = os.path.split(path)
494
        kind = file_kind(tree.abspath(path))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
495
        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.
496
                (None, basename), (None, kind),
497
                (None, False))
498
2012.1.1 by Aaron Bentley
Implement change iterator
499
    def test_empty_to_abc_content(self):
500
        tree1 = self.make_branch_and_tree('1')
501
        tree2 = self.make_to_branch_and_tree('2')
502
        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.
503
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
504
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
505
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
506
            self.added(tree2, 'root-id'),
507
            self.added(tree2, 'a-id'),
508
            self.added(tree2, 'b-id'),
509
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
510
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
511
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
512
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
513
    def test_empty_to_abc_content_a_only(self):
514
        tree1 = self.make_branch_and_tree('1')
515
        tree2 = self.make_to_branch_and_tree('2')
516
        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.
517
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
518
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
519
        self.assertEqual(
520
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
521
            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.
522
523
    def test_abc_content_to_empty_to_abc_content_a_only(self):
524
        tree1 = self.make_branch_and_tree('1')
525
        tree2 = self.make_to_branch_and_tree('2')
526
        tree1 = self.get_tree_no_parents_abc_content(tree1)
527
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
528
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
529
        self.assertEqual(
530
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
531
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
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)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
538
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
539
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
540
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
541
            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
542
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
543
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
544
        tree1 = self.make_branch_and_tree('1')
545
        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.
546
        tree1 = self.get_tree_no_parents_abc_content(tree1)
547
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
548
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
549
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
550
            entry = tree1.inventory[file_id]
551
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
552
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
553
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
554
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
555
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
556
        expected_results = sorted([
557
            self.added(tree2, 'empty-root-id'),
558
            deleted('root-id'), deleted('a-id'),
559
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
560
        self.assertEqual(
561
            expected_results,
562
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
563
564
    def test_content_modification(self):
565
        tree1 = self.make_branch_and_tree('1')
566
        tree2 = self.make_to_branch_and_tree('2')
567
        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.
568
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
569
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
570
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
571
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
572
                           (root_id, root_id), ('a', 'a'),
573
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
574
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
575
576
    def test_meta_modification(self):
577
        tree1 = self.make_branch_and_tree('1')
578
        tree2 = self.make_to_branch_and_tree('2')
579
        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.
580
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
581
        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.
582
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
583
                           ('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.
584
                          (False, True))],
585
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
586
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
587
    def test_empty_dir(self):
588
        """an empty dir should not cause glitches to surrounding files."""
589
        tree1 = self.make_branch_and_tree('1')
590
        tree2 = self.make_to_branch_and_tree('2')
591
        tree1 = self.get_tree_no_parents_abc_content(tree1)
592
        tree2 = self.get_tree_no_parents_abc_content(tree2)
593
        # the pathname is chosen to fall between 'a' and 'b'.
594
        self.build_tree(['1/a-empty/', '2/a-empty/'])
595
        tree1.add(['a-empty'], ['a-empty'])
596
        tree2.add(['a-empty'], ['a-empty'])
597
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
598
        expected = []
599
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
600
2012.1.1 by Aaron Bentley
Implement change iterator
601
    def test_file_rename(self):
602
        tree1 = self.make_branch_and_tree('1')
603
        tree2 = self.make_to_branch_and_tree('2')
604
        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.
605
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
606
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
607
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
608
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
609
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
610
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
611
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
612
613
    def test_file_rename_and_modification(self):
614
        tree1 = self.make_branch_and_tree('1')
615
        tree2 = self.make_to_branch_and_tree('2')
616
        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.
617
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
618
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
619
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
620
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
621
                           (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.
622
                           (False, False))],
623
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
624
625
    def test_file_rename_and_meta_modification(self):
626
        tree1 = self.make_branch_and_tree('1')
627
        tree2 = self.make_to_branch_and_tree('2')
628
        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.
629
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
630
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
631
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
632
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
633
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
634
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
635
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
636
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
637
    def test_missing_in_target(self):
638
        """Test with the target files versioned but absent from disk."""
639
        tree1 = self.make_branch_and_tree('1')
640
        tree2 = self.make_to_branch_and_tree('2')
641
        tree1 = self.get_tree_no_parents_abc_content(tree1)
642
        tree2 = self.get_tree_no_parents_abc_content(tree2)
643
        os.unlink('2/a')
644
        shutil.rmtree('2/b')
645
        # TODO ? have a symlink here?
646
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
647
        root_id = tree1.path2id('')
648
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
649
            self.missing('a-id', 'a', 'a', root_id, 'file'),
650
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
651
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
652
            ])
653
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
654
655
    def test_missing_and_renamed(self):
656
        tree1 = self.make_branch_and_tree('tree1')
657
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
658
        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.
659
        self.build_tree(['tree1/file'])
660
        tree1.add(['file'], ['file-id'])
661
        self.build_tree(['tree2/directory/'])
662
        tree2.add(['directory'], ['file-id'])
663
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
664
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
665
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
666
        root_id = tree1.path2id('')
667
        expected = sorted([
668
            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.
669
            ])
670
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
671
2012.1.1 by Aaron Bentley
Implement change iterator
672
    def test_unchanged_with_renames_and_modifications(self):
673
        """want_unchanged should generate a list of unchanged entries."""
674
        tree1 = self.make_branch_and_tree('1')
675
        tree2 = self.make_to_branch_and_tree('2')
676
        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.
677
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
678
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
679
        root_id = tree1.path2id('')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
680
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.
681
        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.
682
            self.unchanged(tree1, 'b-id'),
683
            ('a-id', ('a', 'd'), True, (True, True),
684
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
685
            (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.
686
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
687
688
    def test_compare_subtrees(self):
689
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
690
        if not tree1.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
691
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
692
        tree1.set_root_id('root-id')
693
        subtree1 = self.make_branch_and_tree('1/sub')
694
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
695
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
696
697
        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
698
        if not tree2.supports_tree_reference():
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
699
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
700
        tree2.set_root_id('root-id')
701
        subtree2 = self.make_to_branch_and_tree('2/sub')
702
        subtree2.set_root_id('subtree-id')
703
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
704
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
705
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
706
        self.assertEqual([], list(tree2._iter_changes(tree1)))
707
        subtree1.commit('commit', rev_id='commit-a')
708
        self.assertEqual([
709
            ('root-id',
710
             (u'', u''),
711
             False,
712
             (True, True),
713
             (None, None),
714
             (u'', u''),
715
             ('directory', 'directory'),
716
             (False, False)),
717
            ('subtree-id',
718
             ('sub', 'sub',),
719
             False,
720
             (True, True),
721
             ('root-id', 'root-id'),
722
             ('sub', 'sub'),
723
             ('tree-reference', 'tree-reference'),
724
             (False, False))],
725
                         list(tree2._iter_changes(tree1,
726
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
727
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
728
    def test_disk_in_subtrees_skipped(self):
729
        """subtrees are considered not-in-the-current-tree.
730
        
731
        This test tests the trivial case, where the basis has no paths in the
732
        current trees subtree.
733
        """
734
        tree1 = self.make_branch_and_tree('1')
735
        tree1.set_root_id('root-id')
736
        tree2 = self.make_to_branch_and_tree('2')
737
        if not tree2.supports_tree_reference():
738
            return
739
        tree2.set_root_id('root-id')
740
        subtree2 = self.make_to_branch_and_tree('2/sub')
741
        subtree2.set_root_id('subtree-id')
742
        tree2.add(['sub'], ['subtree-id'])
743
        self.build_tree(['2/sub/file'])
744
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
745
746
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
747
        # this should filter correctly from above
748
        self.assertEqual([self.added(tree2, 'subtree-id')],
749
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
750
        # and when the path is named
751
        self.assertEqual([self.added(tree2, 'subtree-id')],
752
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
753
                want_unversioned=True))
754
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
755
    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.
756
        tree1 = self.make_branch_and_tree('tree1')
757
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
758
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
759
        self.build_tree(['tree1/a', 'tree1/c',
760
                         'tree2/a', 'tree2/b', 'tree2/c'])
761
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
762
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
763
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
764
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
765
766
        # We should ignore the fact that 'b' exists in tree-2
767
        # because the want_unversioned parameter was not given.
768
        expected = sorted([
769
            self.content_changed(tree2, 'a-id'),
770
            self.content_changed(tree2, 'c-id'),
771
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
772
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
773
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
774
    def test_unversioned_paths_in_tree(self):
775
        tree1 = self.make_branch_and_tree('tree1')
776
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
777
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
778
        self.build_tree(['tree2/file', 'tree2/dir/'])
779
        # try:
780
        os.symlink('target', 'tree2/link')
781
        links_supported = True
782
        # except ???:
783
        #   links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
784
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
785
        expected = [
786
            self.unversioned(tree2, 'file'),
787
            self.unversioned(tree2, 'dir'),
788
            ]
789
        if links_supported:
790
            expected.append(self.unversioned(tree2, 'link'))
791
        expected = sorted(expected)
792
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
793
            want_unversioned=True))
794
795
    def test_unversioned_paths_in_tree_specific_files(self):
796
        tree1 = self.make_branch_and_tree('tree1')
797
        tree2 = self.make_to_branch_and_tree('tree2')
798
        self.build_tree(['tree2/file', 'tree2/dir/'])
799
        # try:
800
        os.symlink('target', 'tree2/link')
801
        links_supported = True
802
        # except ???:
803
        #   links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
804
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
805
        expected = [
806
            self.unversioned(tree2, 'file'),
807
            self.unversioned(tree2, 'dir'),
808
            ]
809
        specific_files=['file', 'dir']
810
        if links_supported:
811
            expected.append(self.unversioned(tree2, 'link'))
812
            specific_files.append('link')
813
        expected = sorted(expected)
814
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
815
            specific_files=specific_files, require_versioned=False,
816
            want_unversioned=True))
817
818
    def test_unversioned_paths_in_target_matching_source_old_names(self):
819
        # its likely that naive implementations of unversioned file support
820
        # will fail if the path was versioned, but is not any more, 
821
        # due to a rename, not due to unversioning it.
822
        # That is, if the old tree has a versioned file 'foo', and
823
        # the new tree has the same file but versioned as 'bar', and also
824
        # has an unknown file 'foo', we should get back output for
825
        # both foo and bar.
826
        tree1 = self.make_branch_and_tree('tree1')
827
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
828
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
829
        self.build_tree(['tree2/file', 'tree2/dir/',
830
            'tree1/file', 'tree2/movedfile',
831
            'tree1/dir/', 'tree2/moveddir/'])
832
        # try:
833
        os.symlink('target', 'tree1/link')
834
        os.symlink('target', 'tree2/link')
835
        os.symlink('target', 'tree2/movedlink')
836
        links_supported = True
837
        # except ???:
838
        #   links_supported = False
839
        tree1.add(['file', 'dir', 'link'], ['file-id', 'dir-id', 'link-id'])
840
        tree2.add(['movedfile', 'moveddir', 'movedlink'],
841
            ['file-id', 'dir-id', 'link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
842
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
843
        root_id = tree1.path2id('')
844
        expected = [
845
            self.renamed(tree1, tree2, 'dir-id', False),
846
            self.renamed(tree1, tree2, 'file-id', True),
847
            self.unversioned(tree2, 'file'),
848
            self.unversioned(tree2, 'dir'),
849
            ]
850
        specific_files=['file', 'dir']
851
        if links_supported:
852
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
853
            expected.append(self.unversioned(tree2, 'link'))
854
            specific_files.append('link')
855
        expected = sorted(expected)
856
        # run once with, and once without specific files, to catch
857
        # potentially different code paths.
858
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
859
            require_versioned=False,
860
            want_unversioned=True))
861
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
862
            specific_files=specific_files, require_versioned=False,
863
            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.
864
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
865
    def test_unversioned_subtree_only_emits_root(self):
866
        tree1 = self.make_branch_and_tree('tree1')
867
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
868
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
869
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
870
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
871
        expected = [
872
            self.unversioned(tree2, 'dir'),
873
            ]
874
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
875
            want_unversioned=True))
876
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.
877
    def make_trees_with_symlinks(self):
878
        tree1 = self.make_branch_and_tree('tree1')
879
        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
880
        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.
881
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
882
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
883
        # try:
884
        os.symlink('original', 'tree1/changed')
885
        os.symlink('original', 'tree1/removed')
886
        os.symlink('original', 'tree1/tofile')
887
        os.symlink('original', 'tree1/todir')
888
        # we make the unchanged link point at unknown to catch incorrect
889
        # symlink-following code in the specified_files test.
890
        os.symlink('unknown', 'tree1/unchanged')
891
        os.symlink('new',      'tree2/added')
892
        os.symlink('new',      'tree2/changed')
893
        os.symlink('new',      'tree2/fromfile')
894
        os.symlink('new',      'tree2/fromdir')
895
        os.symlink('unknown', 'tree2/unchanged')
896
        from_paths_and_ids = [
897
            'fromdir',
898
            'fromfile',
899
            'changed',
900
            'removed',
901
            'todir',
902
            'tofile',
903
            'unchanged',
904
            ]
905
        to_paths_and_ids = [
906
            'added',
907
            'fromdir',
908
            'fromfile',
909
            'changed',
910
            'todir',
911
            'tofile',
912
            'unchanged',
913
            ]
914
        tree1.add(from_paths_and_ids, from_paths_and_ids)
915
        tree2.add(to_paths_and_ids, to_paths_and_ids)
916
        # except ???:
917
        #   raise TestSkipped('OS does not support symlinks')
918
        #   links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
919
        return self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
920
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
921
    def test_versioned_symlinks(self):
2321.3.4 by Alexander Belchenko
test intertree_implementations: skip tests with symlinks on platforms that don't have symlinks support
922
        if not has_symlinks():
2321.3.8 by Alexander Belchenko
Cleanup patch after John's review
923
            raise tests.TestSkipped("No symlink support")
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.
924
        tree1, tree2 = self.make_trees_with_symlinks()
925
        root_id = tree1.path2id('')
926
        expected = [
927
            self.unchanged(tree1, tree1.path2id('')),
928
            self.added(tree2, 'added'),
929
            self.content_changed(tree2, 'changed'),
930
            self.kind_changed(tree1, tree2, 'fromdir'),
931
            self.kind_changed(tree1, tree2, 'fromfile'),
932
            self.deleted(tree1, 'removed'),
933
            self.unchanged(tree2, 'unchanged'),
934
            self.unversioned(tree2, 'unknown'),
935
            self.kind_changed(tree1, tree2, 'todir'),
936
            self.kind_changed(tree1, tree2, 'tofile'),
937
            ]
938
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
939
        self.assertEqual(expected,
940
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
941
                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.
942
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
943
    def test_versioned_symlinks_specific_files(self):
2321.3.4 by Alexander Belchenko
test intertree_implementations: skip tests with symlinks on platforms that don't have symlinks support
944
        if not has_symlinks():
2321.3.8 by Alexander Belchenko
Cleanup patch after John's review
945
            raise tests.TestSkipped("No symlink support")
2255.7.3 by Robert Collins
Add tests for _iter_changes with symlinks, disabled until unversioned file support is added, as that affects the test expected value.
946
        tree1, tree2 = self.make_trees_with_symlinks()
947
        root_id = tree1.path2id('')
948
        expected = [
949
            self.added(tree2, 'added'),
950
            self.content_changed(tree2, 'changed'),
951
            self.kind_changed(tree1, tree2, 'fromdir'),
952
            self.kind_changed(tree1, tree2, 'fromfile'),
953
            self.deleted(tree1, 'removed'),
954
            self.kind_changed(tree1, tree2, 'todir'),
955
            self.kind_changed(tree1, tree2, 'tofile'),
956
            ]
957
        expected = sorted(expected)
958
        # we should get back just the changed links. We pass in 'unchanged' to
959
        # make sure that it is correctly not returned - and neither is the
960
        # unknown path 'unknown' which it points at.
961
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
962
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
963
            '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.
964
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
965
    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.
966
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
967
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
968
        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.
969
970
    def test_trees_with_special_names(self):
971
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
972
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
973
                          if f_id.endswith('_f-id'))
974
        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
975
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
976
    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.
977
        tree1 = self.make_branch_and_tree('tree1')
978
        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
979
        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.
980
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
981
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
982
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
983
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
984
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
985
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
986
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
987
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
988
        # 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.
989
        expected = sorted([
990
            self.content_changed(tree2, 'a-id'),
991
            self.content_changed(tree2, 'g-id'),
992
            self.deleted(tree1, 'b-id'),
993
            self.deleted(tree1, 'c-id'),
994
            self.deleted(tree1, 'd-id'),
995
            self.deleted(tree1, 'e-id'),
996
            ])
997
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
998
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
999
    def test_added_unicode(self):
1000
        tree1 = self.make_branch_and_tree('tree1')
1001
        tree2 = self.make_to_branch_and_tree('tree2')
1002
        root_id = tree1.get_root_id()
1003
        tree2.set_root_id(root_id)
1004
1005
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1006
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1007
        a_id = u'\u03b1-id'.encode('utf8')
1008
        added_id = u'\u03c9_added_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1009
        try:
1010
            self.build_tree([u'tree1/\u03b1/',
1011
                             u'tree2/\u03b1/',
1012
                             u'tree2/\u03b1/\u03c9-added',
1013
                            ])
1014
        except UnicodeError:
1015
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1016
        tree1.add([u'\u03b1'], [a_id])
1017
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1018
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1019
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1020
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1021
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1022
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1023
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1024
                         self.do_iter_changes(tree1, tree2,
1025
                                              specific_files=[u'\u03b1']))
1026
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1027
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1028
        tree1 = self.make_branch_and_tree('tree1')
1029
        tree2 = self.make_to_branch_and_tree('tree2')
1030
        root_id = tree1.get_root_id()
1031
        tree2.set_root_id(root_id)
1032
1033
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1034
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1035
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1036
        deleted_id = u'\u03c9_deleted_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1037
        try:
1038
            self.build_tree([u'tree1/\u03b1/',
1039
                             u'tree1/\u03b1/\u03c9-deleted',
1040
                             u'tree2/\u03b1/',
1041
                            ])
1042
        except UnicodeError:
1043
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1044
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-deleted'], [a_id, deleted_id])
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1045
        tree2.add([u'\u03b1'], [a_id])
1046
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1047
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1048
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1049
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1050
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1051
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1052
                         self.do_iter_changes(tree1, tree2,
1053
                                              specific_files=[u'\u03b1']))
1054
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1055
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1056
        tree1 = self.make_branch_and_tree('tree1')
1057
        tree2 = self.make_to_branch_and_tree('tree2')
1058
        root_id = tree1.get_root_id()
1059
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1060
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1061
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1062
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1063
        a_id = u'\u03b1-id'.encode('utf8')
1064
        mod_id = u'\u03c9_mod_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1065
        try:
1066
            self.build_tree([u'tree1/\u03b1/',
1067
                             u'tree1/\u03b1/\u03c9-modified',
1068
                             u'tree2/\u03b1/',
1069
                             u'tree2/\u03b1/\u03c9-modified',
1070
                            ])
1071
        except UnicodeError:
1072
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1073
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1074
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1075
1076
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1077
1078
        self.assertEqual([self.content_changed(tree1, mod_id)],
1079
                         self.do_iter_changes(tree1, tree2))
1080
        self.assertEqual([self.content_changed(tree1, mod_id)],
1081
                         self.do_iter_changes(tree1, tree2,
1082
                                              specific_files=[u'\u03b1']))
1083
1084
    def test_renamed_unicode(self):
1085
        tree1 = self.make_branch_and_tree('tree1')
1086
        tree2 = self.make_to_branch_and_tree('tree2')
1087
        root_id = tree1.get_root_id()
1088
        tree2.set_root_id(root_id)
1089
1090
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1091
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1092
        a_id = u'\u03b1-id'.encode('utf8')
1093
        rename_id = u'\u03c9_rename_id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1094
        try:
1095
            self.build_tree([u'tree1/\u03b1/',
1096
                             u'tree2/\u03b1/',
1097
                            ])
1098
        except UnicodeError:
1099
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1100
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1101
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1102
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1103
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1104
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1105
1106
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1107
1108
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1109
                         self.do_iter_changes(tree1, tree2))
1110
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1111
                         self.do_iter_changes(tree1, tree2,
1112
                                              specific_files=[u'\u03b1']))
1113
1114
    def test_unchanged_unicode(self):
1115
        tree1 = self.make_branch_and_tree('tree1')
1116
        tree2 = self.make_to_branch_and_tree('tree2')
1117
        root_id = tree1.get_root_id()
1118
        tree2.set_root_id(root_id)
1119
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1120
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1121
        a_id = u'\u03b1-id'.encode('utf8')
1122
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1123
        rootfile_id = u'\u03c9-root-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1124
        try:
1125
            self.build_tree([u'tree1/\u03b1/',
1126
                             u'tree2/\u03b1/',
1127
                            ])
1128
        except UnicodeError:
1129
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1130
        self.build_tree_contents([
1131
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1132
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1133
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1134
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1135
            ])
1136
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1137
                  [a_id, subfile_id, rootfile_id])
1138
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1139
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1140
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1141
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1142
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1143
        expected = sorted([
1144
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1145
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1146
            self.unchanged(tree1, subfile_id),
1147
            self.unchanged(tree1, rootfile_id),
1148
            ])
1149
        self.assertEqual(expected,
1150
                         self.do_iter_changes(tree1, tree2,
1151
                                              include_unchanged=True))
1152
1153
        # We should also be able to select just a subset
1154
        expected = sorted([
1155
            self.unchanged(tree1, a_id),
1156
            self.unchanged(tree1, subfile_id),
1157
            ])
1158
        self.assertEqual(expected,
1159
                         self.do_iter_changes(tree1, tree2,
1160
                                              specific_files=[u'\u03b1'],
1161
                                              include_unchanged=True))
1162
1163
    def test_unknown_unicode(self):
1164
        tree1 = self.make_branch_and_tree('tree1')
1165
        tree2 = self.make_to_branch_and_tree('tree2')
1166
        root_id = tree1.get_root_id()
1167
        tree2.set_root_id(root_id)
1168
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1169
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1170
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1171
        try:
1172
            self.build_tree([u'tree1/\u03b1/',
1173
                             u'tree2/\u03b1/',
1174
                             u'tree2/\u03b1/unknown_dir/',
1175
                             u'tree2/\u03b1/unknown_file',
1176
                             u'tree2/\u03b1/unknown_dir/file',
1177
                             u'tree2/\u03c9-unknown_root_file',
1178
                            ])
1179
        except UnicodeError:
1180
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1181
        tree1.add([u'\u03b1'], [a_id])
1182
        tree2.add([u'\u03b1'], [a_id])
1183
1184
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1185
1186
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1187
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1188
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1189
            self.unversioned(tree2, u'\u03c9-unknown_root_file'),
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1190
            # a/unknown_dir/file should not be included because we should not
1191
            # recurse into unknown_dir
1192
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1193
            ])
1194
        self.assertEqual(expected,
1195
                         self.do_iter_changes(tree1, tree2,
1196
                                              require_versioned=False,
1197
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1198
        self.assertEqual([], # Without want_unversioned we should get nothing
1199
                         self.do_iter_changes(tree1, tree2))
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1200
1201
        # We should also be able to select just a subset
1202
        expected = sorted([
1203
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1204
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1205
            ])
1206
        self.assertEqual(expected,
1207
                         self.do_iter_changes(tree1, tree2,
1208
                                              specific_files=[u'\u03b1'],
1209
                                              require_versioned=False,
1210
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1211
        self.assertEqual([], # Without want_unversioned we should get nothing
1212
                         self.do_iter_changes(tree1, tree2,
1213
                                              specific_files=[u'\u03b1']))