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