/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):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
347
        """Helper to run iter_changes from tree1 to tree2.
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
348
        
349
        :param tree1, tree2:  The source and target trees. These will be locked
350
            automatically.
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
351
        :param **extra_args: Extra args to pass to iter_changes. This is not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
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)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
359
                .iter_changes(**extra_args))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
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)
3254.1.2 by Aaron Bentley
Fix doiter_changes
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
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
516
    def test_empty_specific_files(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)
520
        tree2 = self.get_tree_no_parents_abc_content(tree2)
521
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
522
        self.assertEqual([],
523
            self.do_iter_changes(tree1, tree2, specific_files=[]))
524
525
    def test_no_specific_files(self):
526
        tree1 = self.make_branch_and_tree('1')
527
        tree2 = self.make_to_branch_and_tree('2')
528
        tree1 = self.get_tree_no_parents_no_content(tree1)
529
        tree2 = self.get_tree_no_parents_abc_content(tree2)
530
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2796.1.2 by Aaron Bentley
Harmonize test_no_specific_files with test_empty_to_abc_content
531
        expected_results = sorted([
532
            self.added(tree2, 'root-id'),
533
            self.added(tree2, 'a-id'),
534
            self.added(tree2, 'b-id'),
535
            self.added(tree2, 'c-id'),
536
            self.deleted(tree1, 'empty-root-id')])
537
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
538
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
539
    def test_empty_to_abc_content_a_only(self):
540
        tree1 = self.make_branch_and_tree('1')
541
        tree2 = self.make_to_branch_and_tree('2')
542
        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.
543
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
544
        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.
545
        self.assertEqual(
546
            [self.added(tree2, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
547
            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.
548
549
    def test_abc_content_to_empty_to_abc_content_a_only(self):
550
        tree1 = self.make_branch_and_tree('1')
551
        tree2 = self.make_to_branch_and_tree('2')
552
        tree1 = self.get_tree_no_parents_abc_content(tree1)
553
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
554
        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.
555
        self.assertEqual(
556
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
557
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
558
559
    def test_empty_to_abc_content_a_and_c_only(self):
560
        tree1 = self.make_branch_and_tree('1')
561
        tree2 = self.make_to_branch_and_tree('2')
562
        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.
563
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
564
        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.
565
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
566
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
567
            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
568
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
569
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
570
        tree1 = self.make_branch_and_tree('1')
571
        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.
572
        tree1 = self.get_tree_no_parents_abc_content(tree1)
573
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
574
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
575
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
576
            entry = tree1.inventory[file_id]
577
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
578
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
579
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
580
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
581
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
582
        expected_results = sorted([
583
            self.added(tree2, 'empty-root-id'),
584
            deleted('root-id'), deleted('a-id'),
585
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
586
        self.assertEqual(
587
            expected_results,
588
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
589
590
    def test_content_modification(self):
591
        tree1 = self.make_branch_and_tree('1')
592
        tree2 = self.make_to_branch_and_tree('2')
593
        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.
594
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
595
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
596
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
597
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
598
                           (root_id, root_id), ('a', 'a'),
599
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
600
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
601
602
    def test_meta_modification(self):
603
        tree1 = self.make_branch_and_tree('1')
604
        tree2 = self.make_to_branch_and_tree('2')
605
        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.
606
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
607
        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.
608
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
609
                           ('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.
610
                          (False, True))],
611
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
612
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
613
    def test_empty_dir(self):
614
        """an empty dir should not cause glitches to surrounding files."""
615
        tree1 = self.make_branch_and_tree('1')
616
        tree2 = self.make_to_branch_and_tree('2')
617
        tree1 = self.get_tree_no_parents_abc_content(tree1)
618
        tree2 = self.get_tree_no_parents_abc_content(tree2)
619
        # the pathname is chosen to fall between 'a' and 'b'.
620
        self.build_tree(['1/a-empty/', '2/a-empty/'])
621
        tree1.add(['a-empty'], ['a-empty'])
622
        tree2.add(['a-empty'], ['a-empty'])
623
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
624
        expected = []
625
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
626
2012.1.1 by Aaron Bentley
Implement change iterator
627
    def test_file_rename(self):
628
        tree1 = self.make_branch_and_tree('1')
629
        tree2 = self.make_to_branch_and_tree('2')
630
        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.
631
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
632
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
633
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
634
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
635
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
636
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
637
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
638
639
    def test_file_rename_and_modification(self):
640
        tree1 = self.make_branch_and_tree('1')
641
        tree2 = self.make_to_branch_and_tree('2')
642
        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.
643
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
644
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
645
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
646
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
647
                           (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.
648
                           (False, False))],
649
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
650
651
    def test_file_rename_and_meta_modification(self):
652
        tree1 = self.make_branch_and_tree('1')
653
        tree2 = self.make_to_branch_and_tree('2')
654
        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.
655
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
656
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
657
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
658
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
659
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
660
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
661
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
662
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
663
    def test_missing_in_target(self):
664
        """Test with the target files versioned but absent from disk."""
665
        tree1 = self.make_branch_and_tree('1')
666
        tree2 = self.make_to_branch_and_tree('2')
667
        tree1 = self.get_tree_no_parents_abc_content(tree1)
668
        tree2 = self.get_tree_no_parents_abc_content(tree2)
669
        os.unlink('2/a')
670
        shutil.rmtree('2/b')
671
        # TODO ? have a symlink here?
672
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
673
        root_id = tree1.path2id('')
674
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
675
            self.missing('a-id', 'a', 'a', root_id, 'file'),
676
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
677
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
678
            ])
679
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
680
681
    def test_missing_and_renamed(self):
682
        tree1 = self.make_branch_and_tree('tree1')
683
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
684
        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.
685
        self.build_tree(['tree1/file'])
686
        tree1.add(['file'], ['file-id'])
687
        self.build_tree(['tree2/directory/'])
688
        tree2.add(['directory'], ['file-id'])
689
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
690
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
691
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
692
        root_id = tree1.path2id('')
693
        expected = sorted([
694
            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.
695
            ])
696
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
697
3619.4.1 by Robert Collins
Improve tests for the behaviour of Tree.iter_changes for missing paths that are only present in one tree, and fix found bugs. (Robert Collins)
698
    def test_only_in_source_and_missing(self):
699
        tree1 = self.make_branch_and_tree('tree1')
700
        tree2 = self.make_to_branch_and_tree('tree2')
701
        tree2.set_root_id(tree1.get_root_id())
702
        self.build_tree(['tree1/file'])
703
        tree1.add(['file'], ['file-id'])
704
        os.unlink('tree1/file')
705
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
706
        root_id = tree1.path2id('')
707
        if not tree1.path2id('file'):
708
            # The locked test trees conversion could not preserve the missing
709
            # file status. This is normal (e.g. InterDirstateTree falls back
710
            # to InterTree if the basis is not a DirstateRevisionTree, and
711
            # revision trees cannot have missing files. 
712
            return
713
        expected = [('file-id', ('file', None), False, (True, False),
714
            (root_id, None), ('file', None), (None, None), (False, None))]
715
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
716
717
    def test_only_in_target_and_missing(self):
718
        tree1 = self.make_branch_and_tree('tree1')
719
        tree2 = self.make_to_branch_and_tree('tree2')
720
        tree2.set_root_id(tree1.get_root_id())
721
        self.build_tree(['tree2/file'])
722
        tree2.add(['file'], ['file-id'])
723
        os.unlink('tree2/file')
724
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
725
        root_id = tree1.path2id('')
726
        expected = [('file-id', (None, 'file'), False, (False, True),
727
            (None, root_id), (None, 'file'), (None, None), (None, False))]
728
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
729
2012.1.1 by Aaron Bentley
Implement change iterator
730
    def test_unchanged_with_renames_and_modifications(self):
731
        """want_unchanged should generate a list of unchanged entries."""
732
        tree1 = self.make_branch_and_tree('1')
733
        tree2 = self.make_to_branch_and_tree('2')
734
        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.
735
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
736
        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.
737
        root_id = tree1.path2id('')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
738
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.
739
        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.
740
            self.unchanged(tree1, 'b-id'),
741
            ('a-id', ('a', 'd'), True, (True, True),
742
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
743
            (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.
744
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
745
746
    def test_compare_subtrees(self):
747
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
748
        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.
749
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
750
        tree1.set_root_id('root-id')
751
        subtree1 = self.make_branch_and_tree('1/sub')
752
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
753
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
754
755
        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
756
        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.
757
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
758
        tree2.set_root_id('root-id')
759
        subtree2 = self.make_to_branch_and_tree('2/sub')
760
        subtree2.set_root_id('subtree-id')
761
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
762
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
763
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
764
        self.assertEqual([], list(tree2.iter_changes(tree1)))
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
765
        subtree1.commit('commit', rev_id='commit-a')
766
        self.assertEqual([
767
            ('root-id',
768
             (u'', u''),
769
             False,
770
             (True, True),
771
             (None, None),
772
             (u'', u''),
773
             ('directory', 'directory'),
774
             (False, False)),
775
            ('subtree-id',
776
             ('sub', 'sub',),
777
             False,
778
             (True, True),
779
             ('root-id', 'root-id'),
780
             ('sub', 'sub'),
781
             ('tree-reference', 'tree-reference'),
782
             (False, False))],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
783
                         list(tree2.iter_changes(tree1,
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
784
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
785
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
786
    def test_disk_in_subtrees_skipped(self):
787
        """subtrees are considered not-in-the-current-tree.
788
        
789
        This test tests the trivial case, where the basis has no paths in the
790
        current trees subtree.
791
        """
792
        tree1 = self.make_branch_and_tree('1')
793
        tree1.set_root_id('root-id')
794
        tree2 = self.make_to_branch_and_tree('2')
795
        if not tree2.supports_tree_reference():
796
            return
797
        tree2.set_root_id('root-id')
798
        subtree2 = self.make_to_branch_and_tree('2/sub')
799
        subtree2.set_root_id('subtree-id')
800
        tree2.add(['sub'], ['subtree-id'])
801
        self.build_tree(['2/sub/file'])
802
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
803
804
        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.
805
        # this should filter correctly from above
806
        self.assertEqual([self.added(tree2, 'subtree-id')],
807
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
808
        # and when the path is named
809
        self.assertEqual([self.added(tree2, 'subtree-id')],
810
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
811
                want_unversioned=True))
812
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
813
    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.
814
        tree1 = self.make_branch_and_tree('tree1')
815
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
816
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
817
        self.build_tree(['tree1/a', 'tree1/c',
818
                         'tree2/a', 'tree2/b', 'tree2/c'])
819
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
820
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
821
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
822
        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.
823
824
        # We should ignore the fact that 'b' exists in tree-2
825
        # because the want_unversioned parameter was not given.
826
        expected = sorted([
827
            self.content_changed(tree2, 'a-id'),
828
            self.content_changed(tree2, 'c-id'),
829
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
830
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
831
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
832
    def test_unversioned_paths_in_tree(self):
833
        tree1 = self.make_branch_and_tree('tree1')
834
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
835
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
836
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
837
        if has_symlinks():
838
            os.symlink('target', 'tree2/link')
839
            links_supported = True
840
        else:
841
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
842
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
843
        expected = [
844
            self.unversioned(tree2, 'file'),
845
            self.unversioned(tree2, 'dir'),
846
            ]
847
        if links_supported:
848
            expected.append(self.unversioned(tree2, 'link'))
849
        expected = sorted(expected)
850
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
851
            want_unversioned=True))
852
853
    def test_unversioned_paths_in_tree_specific_files(self):
854
        tree1 = self.make_branch_and_tree('tree1')
855
        tree2 = self.make_to_branch_and_tree('tree2')
856
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
857
        if has_symlinks():
858
            os.symlink('target', 'tree2/link')
859
            links_supported = True
860
        else:
861
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
862
        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.
863
        expected = [
864
            self.unversioned(tree2, 'file'),
865
            self.unversioned(tree2, 'dir'),
866
            ]
867
        specific_files=['file', 'dir']
868
        if links_supported:
869
            expected.append(self.unversioned(tree2, 'link'))
870
            specific_files.append('link')
871
        expected = sorted(expected)
872
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
873
            specific_files=specific_files, require_versioned=False,
874
            want_unversioned=True))
875
876
    def test_unversioned_paths_in_target_matching_source_old_names(self):
877
        # its likely that naive implementations of unversioned file support
878
        # will fail if the path was versioned, but is not any more, 
879
        # due to a rename, not due to unversioning it.
880
        # That is, if the old tree has a versioned file 'foo', and
881
        # the new tree has the same file but versioned as 'bar', and also
882
        # has an unknown file 'foo', we should get back output for
883
        # both foo and bar.
884
        tree1 = self.make_branch_and_tree('tree1')
885
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
886
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
887
        self.build_tree(['tree2/file', 'tree2/dir/',
888
            'tree1/file', 'tree2/movedfile',
889
            'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
890
        if has_symlinks():
891
            os.symlink('target', 'tree1/link')
892
            os.symlink('target', 'tree2/link')
893
            os.symlink('target', 'tree2/movedlink')
894
            links_supported = True
895
        else:
896
            links_supported = False
897
        tree1.add(['file', 'dir'], ['file-id', 'dir-id'])
898
        tree2.add(['movedfile', 'moveddir'], ['file-id', 'dir-id'])
899
        if links_supported:
900
            tree1.add(['link'], ['link-id'])
901
            tree2.add(['movedlink'], ['link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
902
        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.
903
        root_id = tree1.path2id('')
904
        expected = [
905
            self.renamed(tree1, tree2, 'dir-id', False),
906
            self.renamed(tree1, tree2, 'file-id', True),
907
            self.unversioned(tree2, 'file'),
908
            self.unversioned(tree2, 'dir'),
909
            ]
910
        specific_files=['file', 'dir']
911
        if links_supported:
912
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
913
            expected.append(self.unversioned(tree2, 'link'))
914
            specific_files.append('link')
915
        expected = sorted(expected)
916
        # run once with, and once without specific files, to catch
917
        # potentially different code paths.
918
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
919
            require_versioned=False,
920
            want_unversioned=True))
921
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
922
            specific_files=specific_files, require_versioned=False,
923
            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.
924
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
925
    def test_similar_filenames(self):
926
        """Test when we have a few files with similar names."""
927
        tree1 = self.make_branch_and_tree('tree1')
928
        tree2 = self.make_branch_and_tree('tree2')
929
        tree2.set_root_id(tree1.get_root_id())
930
931
        # The trees are actually identical, but they happen to contain
932
        # similarly named files.
933
        self.build_tree(['tree1/a/',
934
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
935
                         'tree1/a/b/c/',
936
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
937
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
938
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
939
                         'tree2/a/',
940
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
941
                         'tree2/a/b/c/',
942
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
943
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
944
                         'tree2/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
945
                        ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
946
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
947
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
948
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
949
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
950
951
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
952
953
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
954
                                                  want_unversioned=True))
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
955
        expected = sorted([
956
            self.unchanged(tree2, tree2.get_root_id()),
957
            self.unchanged(tree2, 'a-id'),
958
            self.unchanged(tree2, 'b-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
959
            self.unchanged(tree2, 'c-id'),
960
            self.unchanged(tree2, 'd-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
961
            self.unchanged(tree2, 'a-c-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
962
            self.unchanged(tree2, 'e-id'),
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
963
            ])
964
        self.assertEqual(expected,
965
                         self.do_iter_changes(tree1, tree2,
966
                                              want_unversioned=True,
967
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
968
969
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
970
    def test_unversioned_subtree_only_emits_root(self):
971
        tree1 = self.make_branch_and_tree('tree1')
972
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
973
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
974
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
975
        tree1, tree2 = self.mutable_trees_to_test_trees(tree1, tree2)
976
        expected = [
977
            self.unversioned(tree2, 'dir'),
978
            ]
979
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
980
            want_unversioned=True))
981
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.
982
    def make_trees_with_symlinks(self):
983
        tree1 = self.make_branch_and_tree('tree1')
984
        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
985
        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.
986
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
987
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
988
        os.symlink('original', 'tree1/changed')
989
        os.symlink('original', 'tree1/removed')
990
        os.symlink('original', 'tree1/tofile')
991
        os.symlink('original', 'tree1/todir')
992
        # we make the unchanged link point at unknown to catch incorrect
993
        # symlink-following code in the specified_files test.
994
        os.symlink('unknown', 'tree1/unchanged')
995
        os.symlink('new',      'tree2/added')
996
        os.symlink('new',      'tree2/changed')
997
        os.symlink('new',      'tree2/fromfile')
998
        os.symlink('new',      'tree2/fromdir')
999
        os.symlink('unknown', 'tree2/unchanged')
1000
        from_paths_and_ids = [
1001
            'fromdir',
1002
            'fromfile',
1003
            'changed',
1004
            'removed',
1005
            'todir',
1006
            'tofile',
1007
            'unchanged',
1008
            ]
1009
        to_paths_and_ids = [
1010
            'added',
1011
            'fromdir',
1012
            'fromfile',
1013
            'changed',
1014
            'todir',
1015
            'tofile',
1016
            'unchanged',
1017
            ]
1018
        tree1.add(from_paths_and_ids, from_paths_and_ids)
1019
        tree2.add(to_paths_and_ids, to_paths_and_ids)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1020
        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.
1021
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1022
    def test_versioned_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1023
        self.requireFeature(tests.SymlinkFeature)
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.
1024
        tree1, tree2 = self.make_trees_with_symlinks()
1025
        root_id = tree1.path2id('')
1026
        expected = [
1027
            self.unchanged(tree1, tree1.path2id('')),
1028
            self.added(tree2, 'added'),
1029
            self.content_changed(tree2, 'changed'),
1030
            self.kind_changed(tree1, tree2, 'fromdir'),
1031
            self.kind_changed(tree1, tree2, 'fromfile'),
1032
            self.deleted(tree1, 'removed'),
1033
            self.unchanged(tree2, 'unchanged'),
1034
            self.unversioned(tree2, 'unknown'),
1035
            self.kind_changed(tree1, tree2, 'todir'),
1036
            self.kind_changed(tree1, tree2, 'tofile'),
1037
            ]
1038
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1039
        self.assertEqual(expected,
1040
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
1041
                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.
1042
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1043
    def test_versioned_symlinks_specific_files(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1044
        self.requireFeature(tests.SymlinkFeature)
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.
1045
        tree1, tree2 = self.make_trees_with_symlinks()
1046
        root_id = tree1.path2id('')
1047
        expected = [
1048
            self.added(tree2, 'added'),
1049
            self.content_changed(tree2, 'changed'),
1050
            self.kind_changed(tree1, tree2, 'fromdir'),
1051
            self.kind_changed(tree1, tree2, 'fromfile'),
1052
            self.deleted(tree1, 'removed'),
1053
            self.kind_changed(tree1, tree2, 'todir'),
1054
            self.kind_changed(tree1, tree2, 'tofile'),
1055
            ]
1056
        expected = sorted(expected)
1057
        # we should get back just the changed links. We pass in 'unchanged' to
1058
        # make sure that it is correctly not returned - and neither is the
1059
        # unknown path 'unknown' which it points at.
1060
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1061
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
1062
            '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.
1063
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1064
    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.
1065
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
1066
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1067
        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.
1068
1069
    def test_trees_with_special_names(self):
1070
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1071
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1072
                          if f_id.endswith('_f-id'))
1073
        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
1074
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1075
    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.
1076
        tree1 = self.make_branch_and_tree('tree1')
1077
        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
1078
        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.
1079
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1080
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1081
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1082
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1083
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1084
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1085
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1086
        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.
1087
        # 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.
1088
        expected = sorted([
1089
            self.content_changed(tree2, 'a-id'),
1090
            self.content_changed(tree2, 'g-id'),
1091
            self.deleted(tree1, 'b-id'),
1092
            self.deleted(tree1, 'c-id'),
1093
            self.deleted(tree1, 'd-id'),
1094
            self.deleted(tree1, 'e-id'),
1095
            ])
1096
        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.
1097
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1098
    def test_added_unicode(self):
1099
        tree1 = self.make_branch_and_tree('tree1')
1100
        tree2 = self.make_to_branch_and_tree('tree2')
1101
        root_id = tree1.get_root_id()
1102
        tree2.set_root_id(root_id)
1103
1104
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1105
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1106
        a_id = u'\u03b1-id'.encode('utf8')
1107
        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.
1108
        try:
1109
            self.build_tree([u'tree1/\u03b1/',
1110
                             u'tree2/\u03b1/',
1111
                             u'tree2/\u03b1/\u03c9-added',
1112
                            ])
1113
        except UnicodeError:
1114
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1115
        tree1.add([u'\u03b1'], [a_id])
1116
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1117
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1118
        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.
1119
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1120
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1121
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1122
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1123
                         self.do_iter_changes(tree1, tree2,
1124
                                              specific_files=[u'\u03b1']))
1125
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1126
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1127
        tree1 = self.make_branch_and_tree('tree1')
1128
        tree2 = self.make_to_branch_and_tree('tree2')
1129
        root_id = tree1.get_root_id()
1130
        tree2.set_root_id(root_id)
1131
1132
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1133
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1134
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1135
        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.
1136
        try:
1137
            self.build_tree([u'tree1/\u03b1/',
1138
                             u'tree1/\u03b1/\u03c9-deleted',
1139
                             u'tree2/\u03b1/',
1140
                            ])
1141
        except UnicodeError:
1142
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1143
        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.
1144
        tree2.add([u'\u03b1'], [a_id])
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)
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1147
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1148
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1149
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1150
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1151
                         self.do_iter_changes(tree1, tree2,
1152
                                              specific_files=[u'\u03b1']))
1153
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1154
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1155
        tree1 = self.make_branch_and_tree('tree1')
1156
        tree2 = self.make_to_branch_and_tree('tree2')
1157
        root_id = tree1.get_root_id()
1158
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1159
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1160
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1161
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1162
        a_id = u'\u03b1-id'.encode('utf8')
1163
        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.
1164
        try:
1165
            self.build_tree([u'tree1/\u03b1/',
1166
                             u'tree1/\u03b1/\u03c9-modified',
1167
                             u'tree2/\u03b1/',
1168
                             u'tree2/\u03b1/\u03c9-modified',
1169
                            ])
1170
        except UnicodeError:
1171
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1172
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1173
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1174
1175
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1176
1177
        self.assertEqual([self.content_changed(tree1, mod_id)],
1178
                         self.do_iter_changes(tree1, tree2))
1179
        self.assertEqual([self.content_changed(tree1, mod_id)],
1180
                         self.do_iter_changes(tree1, tree2,
1181
                                              specific_files=[u'\u03b1']))
1182
1183
    def test_renamed_unicode(self):
1184
        tree1 = self.make_branch_and_tree('tree1')
1185
        tree2 = self.make_to_branch_and_tree('tree2')
1186
        root_id = tree1.get_root_id()
1187
        tree2.set_root_id(root_id)
1188
1189
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1190
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1191
        a_id = u'\u03b1-id'.encode('utf8')
1192
        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.
1193
        try:
1194
            self.build_tree([u'tree1/\u03b1/',
1195
                             u'tree2/\u03b1/',
1196
                            ])
1197
        except UnicodeError:
1198
            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.
1199
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1200
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1201
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1202
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1203
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1204
1205
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1206
1207
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1208
                         self.do_iter_changes(tree1, tree2))
1209
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1210
                         self.do_iter_changes(tree1, tree2,
1211
                                              specific_files=[u'\u03b1']))
1212
1213
    def test_unchanged_unicode(self):
1214
        tree1 = self.make_branch_and_tree('tree1')
1215
        tree2 = self.make_to_branch_and_tree('tree2')
1216
        root_id = tree1.get_root_id()
1217
        tree2.set_root_id(root_id)
1218
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1219
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1220
        a_id = u'\u03b1-id'.encode('utf8')
1221
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1222
        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.
1223
        try:
1224
            self.build_tree([u'tree1/\u03b1/',
1225
                             u'tree2/\u03b1/',
1226
                            ])
1227
        except UnicodeError:
1228
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1229
        self.build_tree_contents([
1230
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1231
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1232
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1233
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1234
            ])
1235
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1236
                  [a_id, subfile_id, rootfile_id])
1237
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1238
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1239
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1240
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1241
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1242
        expected = sorted([
1243
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1244
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1245
            self.unchanged(tree1, subfile_id),
1246
            self.unchanged(tree1, rootfile_id),
1247
            ])
1248
        self.assertEqual(expected,
1249
                         self.do_iter_changes(tree1, tree2,
1250
                                              include_unchanged=True))
1251
1252
        # We should also be able to select just a subset
1253
        expected = sorted([
1254
            self.unchanged(tree1, a_id),
1255
            self.unchanged(tree1, subfile_id),
1256
            ])
1257
        self.assertEqual(expected,
1258
                         self.do_iter_changes(tree1, tree2,
1259
                                              specific_files=[u'\u03b1'],
1260
                                              include_unchanged=True))
1261
1262
    def test_unknown_unicode(self):
1263
        tree1 = self.make_branch_and_tree('tree1')
1264
        tree2 = self.make_to_branch_and_tree('tree2')
1265
        root_id = tree1.get_root_id()
1266
        tree2.set_root_id(root_id)
1267
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1268
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1269
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1270
        try:
1271
            self.build_tree([u'tree1/\u03b1/',
1272
                             u'tree2/\u03b1/',
1273
                             u'tree2/\u03b1/unknown_dir/',
1274
                             u'tree2/\u03b1/unknown_file',
1275
                             u'tree2/\u03b1/unknown_dir/file',
1276
                             u'tree2/\u03c9-unknown_root_file',
1277
                            ])
1278
        except UnicodeError:
1279
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1280
        tree1.add([u'\u03b1'], [a_id])
1281
        tree2.add([u'\u03b1'], [a_id])
1282
1283
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1284
1285
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1286
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1287
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1288
            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.
1289
            # a/unknown_dir/file should not be included because we should not
1290
            # recurse into unknown_dir
1291
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1292
            ])
1293
        self.assertEqual(expected,
1294
                         self.do_iter_changes(tree1, tree2,
1295
                                              require_versioned=False,
1296
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1297
        self.assertEqual([], # Without want_unversioned we should get nothing
1298
                         self.do_iter_changes(tree1, tree2))
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1299
1300
        # We should also be able to select just a subset
1301
        expected = sorted([
1302
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1303
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1304
            ])
1305
        self.assertEqual(expected,
1306
                         self.do_iter_changes(tree1, tree2,
1307
                                              specific_files=[u'\u03b1'],
1308
                                              require_versioned=False,
1309
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1310
        self.assertEqual([], # Without want_unversioned we should get nothing
1311
                         self.do_iter_changes(tree1, tree2,
1312
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1313
1314
    def test_unknown_empty_dir(self):
1315
        tree1 = self.make_branch_and_tree('tree1')
1316
        tree2 = self.make_to_branch_and_tree('tree2')
1317
        root_id = tree1.get_root_id()
1318
        tree2.set_root_id(root_id)
1319
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1320
        # Start with 2 identical trees
1321
        self.build_tree(['tree1/a/', 'tree1/b/',
1322
                         'tree2/a/', 'tree2/b/'])
1323
        self.build_tree_contents([('tree1/b/file', 'contents\n'),
1324
                                  ('tree2/b/file', 'contents\n')])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1325
        tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1326
        tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1327
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1328
        # Now create some unknowns in tree2
1329
        # We should find both a/file and a/dir as unknown, but we shouldn't
1330
        # recurse into a/dir to find that a/dir/subfile is also unknown.
1331
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1332
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1333
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1334
1335
        expected = sorted([
1336
            self.unversioned(tree2, u'a/file'),
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1337
            self.unversioned(tree2, u'a/dir'),
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1338
            ])
1339
        self.assertEqual(expected,
1340
                         self.do_iter_changes(tree1, tree2,
1341
                                              require_versioned=False,
1342
                                              want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1343
1344
    def test_rename_over_deleted(self):
1345
        tree1 = self.make_branch_and_tree('tree1')
1346
        tree2 = self.make_to_branch_and_tree('tree2')
1347
        root_id = tree1.get_root_id()
1348
        tree2.set_root_id(root_id)
1349
1350
        # The final changes should be:
1351
        #   touch a b c d
1352
        #   add a b c d
1353
        #   commit
1354
        #   rm a d
1355
        #   mv b a
1356
        #   mv c d
1357
        self.build_tree_contents([
1358
            ('tree1/a', 'a contents\n'),
1359
            ('tree1/b', 'b contents\n'),
1360
            ('tree1/c', 'c contents\n'),
1361
            ('tree1/d', 'd contents\n'),
1362
            ('tree2/a', 'b contents\n'),
1363
            ('tree2/d', 'c contents\n'),
1364
            ])
1365
        tree1.add(['a', 'b', 'c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
1366
        tree2.add(['a', 'd'], ['b-id', 'c-id'])
1367
1368
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1369
1370
        expected = sorted([
1371
            self.deleted(tree1, 'a-id'),
1372
            self.deleted(tree1, 'd-id'),
1373
            self.renamed(tree1, tree2, 'b-id', False),
1374
            self.renamed(tree1, tree2, 'c-id', False),
1375
            ])
1376
        self.assertEqual(expected,
1377
                         self.do_iter_changes(tree1, tree2))
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1378
1379
    def test_deleted_and_unknown(self):
1380
        """Test a file marked removed, but still present on disk."""
1381
        tree1 = self.make_branch_and_tree('tree1')
1382
        tree2 = self.make_to_branch_and_tree('tree2')
1383
        root_id = tree1.get_root_id()
1384
        tree2.set_root_id(root_id)
1385
1386
        # The final changes should be:
1387
        # bzr add a b c
1388
        # bzr rm --keep b
1389
        self.build_tree_contents([
1390
            ('tree1/a', 'a contents\n'),
1391
            ('tree1/b', 'b contents\n'),
1392
            ('tree1/c', 'c contents\n'),
1393
            ('tree2/a', 'a contents\n'),
1394
            ('tree2/b', 'b contents\n'),
1395
            ('tree2/c', 'c contents\n'),
1396
            ])
1397
        tree1.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
1398
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1399
1400
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1401
1402
        expected = sorted([
1403
            self.deleted(tree1, 'b-id'),
1404
            self.unversioned(tree2, 'b'),
1405
            ])
1406
        self.assertEqual(expected,
1407
                         self.do_iter_changes(tree1, tree2,
1408
                                              want_unversioned=True))
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1409
        expected = sorted([
1410
            self.deleted(tree1, 'b-id'),
1411
            ])
1412
        self.assertEqual(expected,
1413
                         self.do_iter_changes(tree1, tree2,
1414
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1415
1416
    def test_renamed_and_added(self):
1417
        """Test when we have renamed a file, and put another in its place."""
1418
        tree1 = self.make_branch_and_tree('tree1')
1419
        tree2 = self.make_to_branch_and_tree('tree2')
1420
        root_id = tree1.get_root_id()
1421
        tree2.set_root_id(root_id)
1422
1423
        # The final changes are:
1424
        # bzr add b c
1425
        # bzr mv b a
1426
        # bzr mv c d
1427
        # bzr add b c
1428
1429
        self.build_tree_contents([
1430
            ('tree1/b', 'b contents\n'),
1431
            ('tree1/c', 'c contents\n'),
1432
            ('tree2/a', 'b contents\n'),
1433
            ('tree2/b', 'new b contents\n'),
1434
            ('tree2/c', 'new c contents\n'),
1435
            ('tree2/d', 'c contents\n'),
1436
            ])
1437
        tree1.add(['b', 'c'], ['b1-id', 'c1-id'])
1438
        tree2.add(['a', 'b', 'c', 'd'], ['b1-id', 'b2-id', 'c2-id', 'c1-id'])
1439
1440
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1441
1442
        expected = sorted([
1443
            self.renamed(tree1, tree2, 'b1-id', False),
1444
            self.renamed(tree1, tree2, 'c1-id', False),
1445
            self.added(tree2, 'b2-id'),
1446
            self.added(tree2, 'c2-id'),
1447
            ])
1448
        self.assertEqual(expected,
1449
                         self.do_iter_changes(tree1, tree2,
1450
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1451
1452
    def test_renamed_and_unknown(self):
1453
        """A file was moved on the filesystem, but not in bzr."""
1454
        tree1 = self.make_branch_and_tree('tree1')
1455
        tree2 = self.make_to_branch_and_tree('tree2')
1456
        root_id = tree1.get_root_id()
1457
        tree2.set_root_id(root_id)
1458
1459
        # The final changes are:
1460
        # bzr add a b
1461
        # mv a a2
1462
1463
        self.build_tree_contents([
1464
            ('tree1/a', 'a contents\n'),
1465
            ('tree1/b', 'b contents\n'),
1466
            ('tree2/a', 'a contents\n'),
1467
            ('tree2/b', 'b contents\n'),
1468
            ])
1469
        tree1.add(['a', 'b'], ['a-id', 'b-id'])
1470
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1471
        os.rename('tree2/a', 'tree2/a2')
1472
1473
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1474
1475
        expected = sorted([
1476
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),
1477
            self.unversioned(tree2, 'a2'),
1478
            ])
1479
        self.assertEqual(expected,
1480
                         self.do_iter_changes(tree1, tree2,
1481
                                              want_unversioned=True))