/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
3619.4.4 by Robert Collins
Review feedback.
24
from bzrlib.tests import TestNotApplicable
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
25
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
26
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
27
# TODO: test the include_root option.
28
# TODO: test that renaming a directory x->y does not emit a rename for the
29
#       child x/a->y/a.
30
# TODO: test that renaming a directory x-> does not emit a rename for the child
31
#        x/a -> y/a when a supplied_files argument gives either 'x/' or 'y/a'
32
#        -> that is, when the renamed parent is not processed by the function.
33
# TODO: test items are only emitted once when a specific_files list names a dir
34
#       whose parent is now a child.
2255.2.151 by Robert Collins
Handle specific_files natively for WorkingTreeFormat4._iter_changes.
35
# TODO: test specific_files when the target tree has a file and the source a
36
#       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
37
# 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.
38
#
39
# TODO: More comparisons between trees with subtrees in different states.
2255.2.236 by Martin Pool
Review cleanups: mostly updating or removing todo comments.
40
#
41
# TODO: Many tests start out by setting the tree roots ids the same, maybe
42
#       that should just be the default for these tests, by changing
43
#       make_branch_and_tree.  mbp 20070307
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
44
45
class TestCompare(TestCaseWithTwoTrees):
46
47
    def test_compare_empty_trees(self):
48
        tree1 = self.make_branch_and_tree('1')
49
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
50
        tree2.set_root_id(tree1.get_root_id())
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
51
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
52
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
53
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
54
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
55
        self.assertEqual([], d.added)
56
        self.assertEqual([], d.modified)
57
        self.assertEqual([], d.removed)
58
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
59
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
60
61
    def test_empty_to_abc_content(self):
62
        tree1 = self.make_branch_and_tree('1')
63
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
64
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
65
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
66
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
67
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
68
        d = self.intertree_class(tree1, tree2).compare()
69
        self.assertEqual([('a', 'a-id', 'file'),
70
                          ('b', 'b-id', 'directory'),
71
                          ('b/c', 'c-id', 'file'),
72
                         ], d.added)
73
        self.assertEqual([], d.modified)
74
        self.assertEqual([], d.removed)
75
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
76
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
77
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
78
    def test_dangling(self):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
79
        # This test depends on the ability for some trees to have a difference
80
        # between a 'versioned present' and 'versioned not present' (aka
81
        # dangling) file. In this test there are two trees each with a separate
82
        # dangling file, and the dangling files should be considered absent for
83
        # the test.
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
84
        tree1 = self.make_branch_and_tree('1')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
85
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
86
        tree2.set_root_id(tree1.get_root_id())
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
87
        self.build_tree(['2/a'])
88
        tree2.add('a')
89
        os.unlink('2/a')
90
        self.build_tree(['1/b'])
91
        tree1.add('b')
92
        os.unlink('1/b')
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
93
        # the conversion to test trees here will leave the trees intact for the
94
        # default intertree, but may perform a commit for other tree types,
95
        # which may reduce the validity of the test. XXX: Think about how to
96
        # address this.
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
97
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
98
        d = self.intertree_class(tree1, tree2).compare()
99
        self.assertEqual([], d.added)
100
        self.assertEqual([], d.modified)
101
        self.assertEqual([], d.removed)
102
        self.assertEqual([], d.renamed)
103
        self.assertEqual([], d.unchanged)
104
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
105
    def test_abc_content_to_empty(self):
106
        tree1 = self.make_branch_and_tree('1')
107
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
108
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
109
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
110
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
111
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
112
        d = self.intertree_class(tree1, tree2).compare()
113
        self.assertEqual([], d.added)
114
        self.assertEqual([], d.modified)
115
        self.assertEqual([('a', 'a-id', 'file'),
116
                          ('b', 'b-id', 'directory'),
117
                          ('b/c', 'c-id', 'file'),
118
                         ], d.removed)
119
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
120
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
121
122
    def test_content_modification(self):
123
        tree1 = self.make_branch_and_tree('1')
124
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
125
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
126
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
127
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
128
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
129
        d = self.intertree_class(tree1, tree2).compare()
130
        self.assertEqual([], d.added)
131
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
132
        self.assertEqual([], d.removed)
133
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
134
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
135
        
136
    def test_meta_modification(self):
137
        tree1 = self.make_branch_and_tree('1')
138
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
139
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
140
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
141
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
142
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
143
        d = self.intertree_class(tree1, tree2).compare()
144
        self.assertEqual([], d.added)
145
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
146
        self.assertEqual([], d.removed)
147
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
148
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
149
150
    def test_file_rename(self):
151
        tree1 = self.make_branch_and_tree('1')
152
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
153
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
154
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
155
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
156
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
157
        d = self.intertree_class(tree1, tree2).compare()
158
        self.assertEqual([], d.added)
159
        self.assertEqual([], d.modified)
160
        self.assertEqual([], d.removed)
161
        self.assertEqual([('a', 'd', 'a-id', 'file', False, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
162
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
163
164
    def test_file_rename_and_modification(self):
165
        tree1 = self.make_branch_and_tree('1')
166
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
167
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
168
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
169
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
170
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
171
        d = self.intertree_class(tree1, tree2).compare()
172
        self.assertEqual([], d.added)
173
        self.assertEqual([], d.modified)
174
        self.assertEqual([], d.removed)
175
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
176
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
177
178
    def test_file_rename_and_meta_modification(self):
179
        tree1 = self.make_branch_and_tree('1')
180
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
181
        tree2.set_root_id(tree1.get_root_id())
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
182
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
183
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
184
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
185
        d = self.intertree_class(tree1, tree2).compare()
186
        self.assertEqual([], d.added)
187
        self.assertEqual([], d.modified)
188
        self.assertEqual([], d.removed)
189
        self.assertEqual([('b/c', 'e', 'c-id', 'file', False, True)], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
190
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
191
192
    def test_empty_to_abc_content_a_only(self):
193
        tree1 = self.make_branch_and_tree('1')
194
        tree2 = self.make_to_branch_and_tree('2')
2255.2.161 by Martin Pool
merge some of dirstate, update comparison tests to keep tree roots the same unless they're meant to differ
195
        tree2.set_root_id(tree1.get_root_id())
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
196
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
197
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
198
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
199
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
200
        self.assertEqual([('a', 'a-id', 'file')], d.added)
201
        self.assertEqual([], d.modified)
202
        self.assertEqual([], d.removed)
203
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
204
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
205
206
    def test_empty_to_abc_content_a_and_c_only(self):
207
        tree1 = self.make_branch_and_tree('1')
208
        tree2 = self.make_to_branch_and_tree('2')
209
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
210
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
211
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
212
        d = self.intertree_class(tree1, tree2).compare(
213
            specific_files=['a', 'b/c'])
214
        self.assertEqual(
215
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
216
            d.added)
217
        self.assertEqual([], d.modified)
218
        self.assertEqual([], d.removed)
219
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
220
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
221
222
    def test_empty_to_abc_content_b_only(self):
223
        """Restricting to a dir matches the children of the dir."""
224
        tree1 = self.make_branch_and_tree('1')
225
        tree2 = self.make_to_branch_and_tree('2')
226
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
227
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
228
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
229
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
230
        self.assertEqual(
231
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
232
            d.added)
233
        self.assertEqual([], d.modified)
234
        self.assertEqual([], d.removed)
235
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
236
        self.assertEqual([], d.unchanged)
237
238
    def test_unchanged_with_renames_and_modifications(self):
239
        """want_unchanged should generate a list of unchanged entries."""
240
        tree1 = self.make_branch_and_tree('1')
241
        tree2 = self.make_to_branch_and_tree('2')
242
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
243
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
244
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
245
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
246
        self.assertEqual([], d.added)
247
        self.assertEqual([], d.modified)
248
        self.assertEqual([], d.removed)
249
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
250
        self.assertEqual(
251
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
252
            d.unchanged)
253
254
    def test_extra_trees_finds_ids(self):
255
        """Ask for a delta between two trees with a path present in a third."""
256
        tree1 = self.make_branch_and_tree('1')
257
        tree2 = self.make_to_branch_and_tree('2')
258
        tree1 = self.get_tree_no_parents_abc_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
259
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
260
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
261
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
262
        # the type of tree-3 does not matter - it is used as a lookup, not
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
263
        # a dispatch. XXX: For dirstate it does speak to the optimisability of
264
        # the lookup, in merged trees it can be fast-pathed. We probably want
265
        # two tests: one as is, and one with it as a pending merge.
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
266
        tree3 = self.make_branch_and_tree('3')
267
        tree3 = self.get_tree_no_parents_abc_content_6(tree3)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
268
        tree3.lock_read()
269
        self.addCleanup(tree3.unlock)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
270
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
271
        # has c-id at b/c with its exec flag toggled.
272
        # without extra_trees, we should get no modifications from this
273
        # so do one, to be sure the test is valid.
274
        d = self.intertree_class(tree1, tree2).compare(
275
            specific_files=['e'])
276
        self.assertEqual([], d.modified)
277
        # now give it an additional lookup:
278
        d = self.intertree_class(tree1, tree2).compare(
279
            specific_files=['e'], extra_trees=[tree3])
280
        self.assertEqual([], d.added)
281
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
282
        self.assertEqual([], d.removed)
283
        self.assertEqual([], d.renamed)
284
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
285
286
    def test_require_versioned(self):
287
        # this does not quite robustly test, as it is passing in missing paths
288
        # rather than present-but-not-versioned paths. At the moment there is
289
        # no mechanism for managing the test trees (which are readonly) to 
290
        # get present-but-not-versioned files for trees that can do that.
291
        tree1 = self.make_branch_and_tree('1')
292
        tree2 = self.make_to_branch_and_tree('2')
293
        tree1 = self.get_tree_no_parents_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
294
        tree2 = self.get_tree_no_parents_abc_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
295
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
296
        self.assertRaises(errors.PathsNotVersionedError, 
297
            self.intertree_class(tree1, tree2).compare,
298
            specific_files=['d'],
299
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
300
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
301
    def test_default_ignores_unversioned_files(self):
302
        tree1 = self.make_branch_and_tree('tree1')
303
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
304
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
305
        self.build_tree(['tree1/a', 'tree1/c',
306
                         'tree2/a', 'tree2/b', 'tree2/c'])
307
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
308
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
309
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
310
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.91 by Robert Collins
Move unknown detection in long status into the delta creation, saving a tree-scan.
311
        d = self.intertree_class(tree1, tree2).compare()
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
312
        self.assertEqual([], d.added)
313
        self.assertEqual([(u'a', 'a-id', 'file', True, False),
314
            (u'c', 'c-id', 'file', True, False)], d.modified)
315
        self.assertEqual([], d.removed)
316
        self.assertEqual([], d.renamed)
317
        self.assertEqual([], d.unchanged)
318
        self.assertEqual([], d.unversioned)
319
320
    def test_unversioned_paths_in_tree(self):
321
        tree1 = self.make_branch_and_tree('tree1')
322
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
323
        tree2.set_root_id(tree1.get_root_id())
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
324
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
325
        if has_symlinks():
326
            os.symlink('target', 'tree2/link')
327
            links_supported = True
328
        else:
329
            links_supported = False
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
330
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
331
        d = self.intertree_class(tree1, tree2).compare(want_unversioned=True)
332
        self.assertEqual([], d.added)
333
        self.assertEqual([], d.modified)
334
        self.assertEqual([], d.removed)
335
        self.assertEqual([], d.renamed)
336
        self.assertEqual([], d.unchanged)
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
337
        expected_unversioned = [(u'dir', None, 'directory'),
338
                                (u'file', None, 'file')]
339
        if links_supported:
340
            expected_unversioned.append((u'link', None, 'symlink'))
341
        self.assertEqual(expected_unversioned, d.unversioned)
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
342
2012.1.1 by Aaron Bentley
Implement change iterator
343
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
344
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
345
    """Test the comparison iterator"""
346
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
347
    def do_iter_changes(self, tree1, tree2, **extra_args):
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
348
        """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.
349
        
350
        :param tree1, tree2:  The source and target trees. These will be locked
351
            automatically.
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
352
        :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.
353
            inspected by this test helper.
354
        """
355
        tree1.lock_read()
356
        tree2.lock_read()
357
        try:
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
358
            # sort order of output is not strictly defined
359
            return sorted(self.intertree_class(tree1, tree2)
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
360
                .iter_changes(**extra_args))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
361
        finally:
362
            tree1.unlock()
363
            tree2.unlock()
364
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
365
    def mutable_trees_to_locked_test_trees(self, tree1, tree2):
366
        """Convert the working trees into test trees.
367
368
        Read lock them, and add the unlock to the cleanup.
369
        """
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
370
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
371
        tree1.lock_read()
372
        self.addCleanup(tree1.unlock)
373
        tree2.lock_read()
374
        self.addCleanup(tree2.unlock)
375
        return tree1, tree2
376
2255.7.15 by John Arbash Meinel
Try to create an intertree test that exposes the walkdir vs dirstate mismatch. No luck yet.
377
    def make_tree_with_special_names(self):
378
        """Create a tree with filenames chosen to exercise the walk order."""
379
        tree1 = self.make_branch_and_tree('tree1')
380
        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
381
        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.
382
        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.
383
        tree2.commit('initial', rev_id='rev-1')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
384
        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.
385
        return (tree1, tree2, paths, path_ids)
386
387
    def make_trees_with_special_names(self):
388
        """Both trees will use the special names.
389
390
        But the contents will differ for each file.
391
        """
392
        tree1 = self.make_branch_and_tree('tree1')
393
        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
394
        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.
395
        paths, path_ids = self._create_special_names(tree1, 'tree1')
396
        paths, path_ids = self._create_special_names(tree2, 'tree2')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
397
        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.
398
        return (tree1, tree2, paths, path_ids)
399
400
    def _create_special_names(self, tree, base_path):
401
        """Create a tree with paths that expose differences in sort orders."""
402
        # Each directory will have a single file named 'f' inside
403
        dirs = ['a',
404
                'a-a',
405
                'a/a',
406
                'a/a-a',
407
                'a/a/a',
408
                'a/a/a-a',
409
                'a/a/a/a',
410
                'a/a/a/a-a',
411
                'a/a/a/a/a',
412
               ]
413
        with_slashes = []
414
        paths = []
415
        path_ids = []
416
        for d in dirs:
417
            with_slashes.append(base_path + '/' + d + '/')
418
            with_slashes.append(base_path + '/' + d + '/f')
419
            paths.append(d)
420
            paths.append(d+'/f')
421
            path_ids.append(d.replace('/', '_') + '-id')
422
            path_ids.append(d.replace('/', '_') + '_f-id')
423
        self.build_tree(with_slashes)
424
        tree.add(paths, path_ids)
425
        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.
426
2012.1.1 by Aaron Bentley
Implement change iterator
427
    def test_compare_empty_trees(self):
428
        tree1 = self.make_branch_and_tree('1')
429
        tree2 = self.make_to_branch_and_tree('2')
430
        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.
431
        tree2 = self.get_tree_no_parents_no_content(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
432
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
3254.1.2 by Aaron Bentley
Fix doiter_changes
433
        self.assertEqual([], self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
434
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
435
    def added(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
436
        path, entry = self.get_path_entry(tree, 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
3363.14.7 by Aaron Bentley
Get more tests passing
441
    @staticmethod
442
    def get_path_entry(tree, file_id):
443
        iterator = tree.iter_entries_by_dir(specific_file_ids=[file_id])
444
        return iterator.next()
445
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.
446
    def content_changed(self, tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
447
        path, entry = self.get_path_entry(tree, file_id)
448
        return (file_id, (path, path), True, (True, True),
449
                (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.
450
                (entry.name, entry.name), (entry.kind, entry.kind),
451
                (entry.executable, entry.executable))
452
453
    def kind_changed(self, from_tree, to_tree, file_id):
3363.14.7 by Aaron Bentley
Get more tests passing
454
        from_path, old_entry = self.get_path_entry(from_tree, file_id)
455
        path, new_entry = self.get_path_entry(to_tree, file_id)
456
        return (file_id, (from_path, path), True, (True, True),
457
                (old_entry.parent_id, new_entry.parent_id),
458
                (old_entry.name, new_entry.name),
459
                (old_entry.kind, new_entry.kind),
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.
460
                (old_entry.executable, new_entry.executable))
461
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
462
    def missing(self, file_id, from_path, to_path, parent_id, kind):
463
        _, from_basename = os.path.split(from_path)
464
        _, to_basename = os.path.split(to_path)
465
        # missing files have both paths, but no kind.
466
        return (file_id, (from_path, to_path), True, (True, True),
467
            (parent_id, parent_id),
468
            (from_basename, to_basename), (kind, None), (False, False))
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
469
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
470
    def deleted(self, tree, file_id):
471
        entry = tree.inventory[file_id]
472
        path = tree.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
473
        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.
474
                (entry.name, None), (entry.kind, None),
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
475
                (entry.executable, None))
476
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
477
    def renamed(self, from_tree, to_tree, file_id, content_changed):
3363.14.8 by Aaron Bentley
Fix more tests
478
        from_path, from_entry = self.get_path_entry(from_tree, file_id)
479
        to_path, to_entry = self.get_path_entry(to_tree, file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
480
        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.
481
            (from_entry.parent_id, to_entry.parent_id),
482
            (from_entry.name, to_entry.name),
483
            (from_entry.kind, to_entry.kind),
484
            (from_entry.executable, to_entry.executable))
485
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.
486
    def unchanged(self, tree, file_id):
3363.14.8 by Aaron Bentley
Fix more tests
487
        path, entry = self.get_path_entry(tree, file_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.
488
        parent = entry.parent_id
489
        name = entry.name
490
        kind = entry.kind
491
        executable = entry.executable
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
492
        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.
493
               (parent, parent), (name, name), (kind, kind),
494
               (executable, executable))
495
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
496
    def unversioned(self, tree, path):
497
        """Create an unversioned result."""
498
        _, basename = os.path.split(path)
3363.14.7 by Aaron Bentley
Get more tests passing
499
        kind = tree._comparison_data(None, path)[0]
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
500
        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.
501
                (None, basename), (None, kind),
502
                (None, False))
503
3735.7.8 by Vincent Ladeuil
Get rid of failures related to not applicable tests.
504
    def not_applicable_if_missing_in(self, relpath, tree):
505
        if not tree.path2id(relpath):
506
            # The locked test trees conversion could not preserve the missing
507
            # file status. This is normal (e.g. InterDirstateTree falls back
508
            # to InterTree if the basis is not a DirstateRevisionTree, and
509
            # revision trees cannot have missing files. 
510
            raise TestNotApplicable()
511
2012.1.1 by Aaron Bentley
Implement change iterator
512
    def test_empty_to_abc_content(self):
513
        tree1 = self.make_branch_and_tree('1')
514
        tree2 = self.make_to_branch_and_tree('2')
515
        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.
516
        tree2 = self.get_tree_no_parents_abc_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
517
        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.
518
        expected_results = sorted([
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
519
            self.added(tree2, 'root-id'),
520
            self.added(tree2, 'a-id'),
521
            self.added(tree2, 'b-id'),
522
            self.added(tree2, 'c-id'),
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
523
            self.deleted(tree1, 'empty-root-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
524
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
525
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
526
    def test_empty_specific_files(self):
527
        tree1 = self.make_branch_and_tree('1')
528
        tree2 = self.make_to_branch_and_tree('2')
529
        tree1 = self.get_tree_no_parents_no_content(tree1)
530
        tree2 = self.get_tree_no_parents_abc_content(tree2)
531
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
532
        self.assertEqual([],
533
            self.do_iter_changes(tree1, tree2, specific_files=[]))
534
535
    def test_no_specific_files(self):
536
        tree1 = self.make_branch_and_tree('1')
537
        tree2 = self.make_to_branch_and_tree('2')
538
        tree1 = self.get_tree_no_parents_no_content(tree1)
539
        tree2 = self.get_tree_no_parents_abc_content(tree2)
540
        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
541
        expected_results = sorted([
542
            self.added(tree2, 'root-id'),
543
            self.added(tree2, 'a-id'),
544
            self.added(tree2, 'b-id'),
545
            self.added(tree2, 'c-id'),
546
            self.deleted(tree1, 'empty-root-id')])
547
        self.assertEqual(expected_results, self.do_iter_changes(tree1, tree2))
2748.3.1 by Aaron Bentley
Start supporting [] for empty list
548
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
549
    def test_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_no_content(tree1)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
553
        tree2 = self.get_tree_no_parents_abc_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.added(tree2, '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']))
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
558
559
    def test_abc_content_to_empty_to_abc_content_a_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_abc_content(tree1)
563
        tree2 = self.get_tree_no_parents_no_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
        self.assertEqual(
566
            [self.deleted(tree1, 'a-id')],
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
567
            self.do_iter_changes(tree1, tree2, specific_files=['a']))
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
568
569
    def test_empty_to_abc_content_a_and_c_only(self):
570
        tree1 = self.make_branch_and_tree('1')
571
        tree2 = self.make_to_branch_and_tree('2')
572
        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.
573
        tree2 = self.get_tree_no_parents_abc_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)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
575
        expected_result = [self.added(tree2, 'a-id'), self.added(tree2, 'c-id')]
576
        self.assertEqual(expected_result,
2255.2.149 by Robert Collins
Crufty but existing _iter_changes implementation for WorkingTreeFormat4.
577
            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
578
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
579
    def test_abc_content_to_empty(self):
2012.1.1 by Aaron Bentley
Implement change iterator
580
        tree1 = self.make_branch_and_tree('1')
581
        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.
582
        tree1 = self.get_tree_no_parents_abc_content(tree1)
583
        tree2 = self.get_tree_no_parents_no_content(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
584
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
2012.1.1 by Aaron Bentley
Implement change iterator
585
        def deleted(file_id):
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
586
            entry = tree1.inventory[file_id]
587
            path = tree1.id2path(file_id)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
588
            return (file_id, (path, None), True, (True, False),
2012.1.1 by Aaron Bentley
Implement change iterator
589
                    (entry.parent_id, None),
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
590
                    (entry.name, None), (entry.kind, None),
2012.1.1 by Aaron Bentley
Implement change iterator
591
                    (entry.executable, None))
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
592
        expected_results = sorted([
593
            self.added(tree2, 'empty-root-id'),
594
            deleted('root-id'), deleted('a-id'),
595
            deleted('b-id'), deleted('c-id')])
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
596
        self.assertEqual(
597
            expected_results,
598
            self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
599
600
    def test_content_modification(self):
601
        tree1 = self.make_branch_and_tree('1')
602
        tree2 = self.make_to_branch_and_tree('2')
603
        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.
604
        tree2 = self.get_tree_no_parents_abc_content_2(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
605
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
606
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
607
        self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
608
                           (root_id, root_id), ('a', 'a'),
609
                           ('file', 'file'), (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
610
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
611
612
    def test_meta_modification(self):
613
        tree1 = self.make_branch_and_tree('1')
614
        tree2 = self.make_to_branch_and_tree('2')
615
        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.
616
        tree2 = self.get_tree_no_parents_abc_content_3(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
617
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
618
        self.assertEqual([('c-id', ('b/c', 'b/c'), False, (True, True),
619
                           ('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.
620
                          (False, True))],
621
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
622
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
623
    def test_empty_dir(self):
624
        """an empty dir should not cause glitches to surrounding files."""
625
        tree1 = self.make_branch_and_tree('1')
626
        tree2 = self.make_to_branch_and_tree('2')
627
        tree1 = self.get_tree_no_parents_abc_content(tree1)
628
        tree2 = self.get_tree_no_parents_abc_content(tree2)
629
        # the pathname is chosen to fall between 'a' and 'b'.
630
        self.build_tree(['1/a-empty/', '2/a-empty/'])
631
        tree1.add(['a-empty'], ['a-empty'])
632
        tree2.add(['a-empty'], ['a-empty'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
633
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.6 by Robert Collins
Test for iterating changes past empty directories.
634
        expected = []
635
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
636
2012.1.1 by Aaron Bentley
Implement change iterator
637
    def test_file_rename(self):
638
        tree1 = self.make_branch_and_tree('1')
639
        tree2 = self.make_to_branch_and_tree('2')
640
        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.
641
        tree2 = self.get_tree_no_parents_abc_content_4(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
642
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
643
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
644
        self.assertEqual([('a-id', ('a', 'd'), False, (True, True),
645
                           (root_id, root_id), ('a', 'd'), ('file', 'file'),
646
                           (False, False))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
647
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
648
649
    def test_file_rename_and_modification(self):
650
        tree1 = self.make_branch_and_tree('1')
651
        tree2 = self.make_to_branch_and_tree('2')
652
        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.
653
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
654
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
655
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
656
        self.assertEqual([('a-id', ('a', 'd'), True, (True, True),
657
                           (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.
658
                           (False, False))],
659
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
660
661
    def test_file_rename_and_meta_modification(self):
662
        tree1 = self.make_branch_and_tree('1')
663
        tree2 = self.make_to_branch_and_tree('2')
664
        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.
665
        tree2 = self.get_tree_no_parents_abc_content_6(tree2)
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
666
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
667
        root_id = tree1.path2id('')
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
668
        self.assertEqual([('c-id', ('b/c', 'e'), False, (True, True),
669
                           ('b-id', root_id), ('c', 'e'), ('file', 'file'),
670
                           (False, True))],
2255.2.122 by Robert Collins
Alter intertree implementation tests to let dirstate inter-trees be correctly parameterised.
671
                         self.do_iter_changes(tree1, tree2))
2012.1.1 by Aaron Bentley
Implement change iterator
672
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
673
    def test_missing_in_target(self):
674
        """Test with the target files versioned but absent from disk."""
675
        tree1 = self.make_branch_and_tree('1')
676
        tree2 = self.make_to_branch_and_tree('2')
677
        tree1 = self.get_tree_no_parents_abc_content(tree1)
678
        tree2 = self.get_tree_no_parents_abc_content(tree2)
679
        os.unlink('2/a')
680
        shutil.rmtree('2/b')
681
        # TODO ? have a symlink here?
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
682
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
683
        root_id = tree1.path2id('')
684
        expected = sorted([
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
685
            self.missing('a-id', 'a', 'a', root_id, 'file'),
686
            self.missing('b-id', 'b', 'b', root_id, 'directory'),
687
            self.missing('c-id', 'b/c', 'b/c', 'b-id', 'file'),
688
            ])
689
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
690
691
    def test_missing_and_renamed(self):
692
        tree1 = self.make_branch_and_tree('tree1')
693
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
694
        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.
695
        self.build_tree(['tree1/file'])
696
        tree1.add(['file'], ['file-id'])
697
        self.build_tree(['tree2/directory/'])
698
        tree2.add(['directory'], ['file-id'])
699
        os.rmdir('tree2/directory')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
700
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
3735.7.8 by Vincent Ladeuil
Get rid of failures related to not applicable tests.
701
        self.not_applicable_if_missing_in('directory', tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
702
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
703
        root_id = tree1.path2id('')
704
        expected = sorted([
705
            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.
706
            ])
707
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
708
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)
709
    def test_only_in_source_and_missing(self):
710
        tree1 = self.make_branch_and_tree('tree1')
711
        tree2 = self.make_to_branch_and_tree('tree2')
712
        tree2.set_root_id(tree1.get_root_id())
713
        self.build_tree(['tree1/file'])
714
        tree1.add(['file'], ['file-id'])
715
        os.unlink('tree1/file')
716
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
3735.7.8 by Vincent Ladeuil
Get rid of failures related to not applicable tests.
717
        self.not_applicable_if_missing_in('file', tree1)
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)
718
        root_id = tree1.path2id('')
719
        expected = [('file-id', ('file', None), False, (True, False),
720
            (root_id, None), ('file', None), (None, None), (False, None))]
721
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
722
723
    def test_only_in_target_and_missing(self):
724
        tree1 = self.make_branch_and_tree('tree1')
725
        tree2 = self.make_to_branch_and_tree('tree2')
726
        tree2.set_root_id(tree1.get_root_id())
727
        self.build_tree(['tree2/file'])
728
        tree2.add(['file'], ['file-id'])
729
        os.unlink('tree2/file')
730
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
3735.7.8 by Vincent Ladeuil
Get rid of failures related to not applicable tests.
731
        self.not_applicable_if_missing_in('file', tree2)
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)
732
        root_id = tree1.path2id('')
733
        expected = [('file-id', (None, 'file'), False, (False, True),
734
            (None, root_id), (None, 'file'), (None, None), (None, False))]
735
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
736
2012.1.1 by Aaron Bentley
Implement change iterator
737
    def test_unchanged_with_renames_and_modifications(self):
738
        """want_unchanged should generate a list of unchanged entries."""
739
        tree1 = self.make_branch_and_tree('1')
740
        tree2 = self.make_to_branch_and_tree('2')
741
        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.
742
        tree2 = self.get_tree_no_parents_abc_content_5(tree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
743
        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.
744
        root_id = tree1.path2id('')
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
745
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.
746
        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.
747
            self.unchanged(tree1, 'b-id'),
748
            ('a-id', ('a', 'd'), True, (True, True),
749
             (root_id, root_id), ('a', 'd'), ('file', 'file'),
2255.7.4 by Robert Collins
Test InterTree._iter_changes with missing (absent but versioned) files.
750
            (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.
751
            self.do_iter_changes(tree1, tree2, include_unchanged=True))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
752
753
    def test_compare_subtrees(self):
754
        tree1 = self.make_branch_and_tree('1')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
755
        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.
756
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
757
        tree1.set_root_id('root-id')
758
        subtree1 = self.make_branch_and_tree('1/sub')
759
        subtree1.set_root_id('subtree-id')
2255.9.2 by Martin Pool
test_compare_subtrees runs against all trees that claim to support
760
        tree1.add_reference(subtree1)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
761
762
        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
763
        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.
764
            return
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
765
        tree2.set_root_id('root-id')
766
        subtree2 = self.make_to_branch_and_tree('2/sub')
767
        subtree2.set_root_id('subtree-id')
768
        tree2.add_reference(subtree2)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
769
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
770
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
771
        self.assertEqual([], list(tree2.iter_changes(tree1)))
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
772
        subtree1.commit('commit', rev_id='commit-a')
773
        self.assertEqual([
774
            ('root-id',
775
             (u'', u''),
776
             False,
777
             (True, True),
778
             (None, None),
779
             (u'', u''),
780
             ('directory', 'directory'),
781
             (False, False)),
782
            ('subtree-id',
783
             ('sub', 'sub',),
784
             False,
785
             (True, True),
786
             ('root-id', 'root-id'),
787
             ('sub', 'sub'),
788
             ('tree-reference', 'tree-reference'),
789
             (False, False))],
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
790
                         list(tree2.iter_changes(tree1,
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
791
                             include_unchanged=True)))
2255.2.160 by Martin Pool
(merge) updates from dirstate branch
792
2323.4.2 by Robert Collins
Fix the behaviour of dirstate optimised iter_changes recursing its disk iterator into subtrees inappropriately.
793
    def test_disk_in_subtrees_skipped(self):
794
        """subtrees are considered not-in-the-current-tree.
795
        
796
        This test tests the trivial case, where the basis has no paths in the
797
        current trees subtree.
798
        """
799
        tree1 = self.make_branch_and_tree('1')
800
        tree1.set_root_id('root-id')
801
        tree2 = self.make_to_branch_and_tree('2')
802
        if not tree2.supports_tree_reference():
803
            return
804
        tree2.set_root_id('root-id')
805
        subtree2 = self.make_to_branch_and_tree('2/sub')
806
        subtree2.set_root_id('subtree-id')
807
        tree2.add(['sub'], ['subtree-id'])
808
        self.build_tree(['2/sub/file'])
809
        subtree2.add(['file'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
810
811
        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.
812
        # this should filter correctly from above
813
        self.assertEqual([self.added(tree2, 'subtree-id')],
814
            self.do_iter_changes(tree1, tree2, want_unversioned=True))
815
        # and when the path is named
816
        self.assertEqual([self.added(tree2, 'subtree-id')],
817
            self.do_iter_changes(tree1, tree2, specific_files=['sub'],
818
                want_unversioned=True))
819
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
820
    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.
821
        tree1 = self.make_branch_and_tree('tree1')
822
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.186 by Martin Pool
Fix up root id for some more comparison tests
823
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
824
        self.build_tree(['tree1/a', 'tree1/c',
825
                         'tree2/a', 'tree2/b', 'tree2/c'])
826
        tree1.add(['a', 'c'], ['a-id', 'c-id'])
827
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
828
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
829
        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.
830
831
        # We should ignore the fact that 'b' exists in tree-2
832
        # because the want_unversioned parameter was not given.
833
        expected = sorted([
834
            self.content_changed(tree2, 'a-id'),
835
            self.content_changed(tree2, 'c-id'),
836
            ])
2255.7.2 by Robert Collins
Add a (currently) disabled test for unversioned paths in the target tree with _iter_changes.
837
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2))
838
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
839
    def test_unversioned_paths_in_tree(self):
840
        tree1 = self.make_branch_and_tree('tree1')
841
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.184 by Martin Pool
Fixes for some comparison tests; repr of DirStateRevisionTree
842
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
843
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
844
        if has_symlinks():
845
            os.symlink('target', 'tree2/link')
846
            links_supported = True
847
        else:
848
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
849
        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.
850
        expected = [
851
            self.unversioned(tree2, 'file'),
852
            self.unversioned(tree2, 'dir'),
853
            ]
854
        if links_supported:
855
            expected.append(self.unversioned(tree2, 'link'))
856
        expected = sorted(expected)
857
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
858
            want_unversioned=True))
859
860
    def test_unversioned_paths_in_tree_specific_files(self):
861
        tree1 = self.make_branch_and_tree('tree1')
862
        tree2 = self.make_to_branch_and_tree('tree2')
863
        self.build_tree(['tree2/file', 'tree2/dir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
864
        if has_symlinks():
865
            os.symlink('target', 'tree2/link')
866
            links_supported = True
867
        else:
868
            links_supported = False
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
869
        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.
870
        expected = [
871
            self.unversioned(tree2, 'file'),
872
            self.unversioned(tree2, 'dir'),
873
            ]
874
        specific_files=['file', 'dir']
875
        if links_supported:
876
            expected.append(self.unversioned(tree2, 'link'))
877
            specific_files.append('link')
878
        expected = sorted(expected)
879
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
880
            specific_files=specific_files, require_versioned=False,
881
            want_unversioned=True))
882
883
    def test_unversioned_paths_in_target_matching_source_old_names(self):
884
        # its likely that naive implementations of unversioned file support
885
        # will fail if the path was versioned, but is not any more, 
886
        # due to a rename, not due to unversioning it.
887
        # That is, if the old tree has a versioned file 'foo', and
888
        # the new tree has the same file but versioned as 'bar', and also
889
        # has an unknown file 'foo', we should get back output for
890
        # both foo and bar.
891
        tree1 = self.make_branch_and_tree('tree1')
892
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.187 by Martin Pool
set common root ids in more tests
893
        tree2.set_root_id(tree1.get_root_id())
2255.7.85 by Robert Collins
Teach _iter_changes to gather unversioned path details upon request.
894
        self.build_tree(['tree2/file', 'tree2/dir/',
895
            'tree1/file', 'tree2/movedfile',
896
            'tree1/dir/', 'tree2/moveddir/'])
2408.1.2 by Alexander Belchenko
intertree_implementations: make usage of symlinks optional
897
        if has_symlinks():
898
            os.symlink('target', 'tree1/link')
899
            os.symlink('target', 'tree2/link')
900
            os.symlink('target', 'tree2/movedlink')
901
            links_supported = True
902
        else:
903
            links_supported = False
904
        tree1.add(['file', 'dir'], ['file-id', 'dir-id'])
905
        tree2.add(['movedfile', 'moveddir'], ['file-id', 'dir-id'])
906
        if links_supported:
907
            tree1.add(['link'], ['link-id'])
908
            tree2.add(['movedlink'], ['link-id'])
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
909
        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.
910
        root_id = tree1.path2id('')
911
        expected = [
912
            self.renamed(tree1, tree2, 'dir-id', False),
913
            self.renamed(tree1, tree2, 'file-id', True),
914
            self.unversioned(tree2, 'file'),
915
            self.unversioned(tree2, 'dir'),
916
            ]
917
        specific_files=['file', 'dir']
918
        if links_supported:
919
            expected.append(self.renamed(tree1, tree2, 'link-id', False))
920
            expected.append(self.unversioned(tree2, 'link'))
921
            specific_files.append('link')
922
        expected = sorted(expected)
923
        # run once with, and once without specific files, to catch
924
        # potentially different code paths.
925
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
926
            require_versioned=False,
927
            want_unversioned=True))
928
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
929
            specific_files=specific_files, require_versioned=False,
930
            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.
931
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
932
    def test_similar_filenames(self):
933
        """Test when we have a few files with similar names."""
934
        tree1 = self.make_branch_and_tree('tree1')
935
        tree2 = self.make_branch_and_tree('tree2')
936
        tree2.set_root_id(tree1.get_root_id())
937
938
        # The trees are actually identical, but they happen to contain
939
        # similarly named files.
940
        self.build_tree(['tree1/a/',
941
                         'tree1/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
942
                         'tree1/a/b/c/',
943
                         'tree1/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
944
                         'tree1/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
945
                         'tree1/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
946
                         'tree2/a/',
947
                         'tree2/a/b/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
948
                         'tree2/a/b/c/',
949
                         'tree2/a/b/c/d/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
950
                         'tree2/a-c/',
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
951
                         'tree2/a-c/e/',
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
952
                        ])
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
953
        tree1.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
954
                  ['a-id', 'b-id', 'c-id', 'd-id', 'a-c-id', 'e-id'])
955
        tree2.add(['a', 'a/b', 'a/b/c', 'a/b/c/d', 'a-c', 'a-c/e'],
956
                  ['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
957
958
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
959
960
        self.assertEqual([], self.do_iter_changes(tree1, tree2,
961
                                                  want_unversioned=True))
2466.5.2 by John Arbash Meinel
Extend the test a bit to make sure the include_unchanged value is correct.
962
        expected = sorted([
963
            self.unchanged(tree2, tree2.get_root_id()),
964
            self.unchanged(tree2, 'a-id'),
965
            self.unchanged(tree2, 'b-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
966
            self.unchanged(tree2, 'c-id'),
967
            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.
968
            self.unchanged(tree2, 'a-c-id'),
2466.5.4 by John Arbash Meinel
Fix bug #11127 by splitting paths on '/'.
969
            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.
970
            ])
971
        self.assertEqual(expected,
972
                         self.do_iter_changes(tree1, tree2,
973
                                              want_unversioned=True,
974
                                              include_unchanged=True))
2466.5.1 by John Arbash Meinel
Add a (failing) test for bug 111127
975
976
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
977
    def test_unversioned_subtree_only_emits_root(self):
978
        tree1 = self.make_branch_and_tree('tree1')
979
        tree2 = self.make_to_branch_and_tree('tree2')
2255.2.188 by Martin Pool
Set common root id in comparison tests
980
        tree2.set_root_id(tree1.get_root_id())
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
981
        self.build_tree(['tree2/dir/', 'tree2/dir/file'])
3363.14.9 by Aaron Bentley
Ensure TransformPreview is finalized
982
        tree1, tree2 = self.mutable_trees_to_test_trees(self, tree1, tree2)
2255.7.87 by Robert Collins
Dont walk unversioned directories in _iter_changes.
983
        expected = [
984
            self.unversioned(tree2, 'dir'),
985
            ]
986
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
987
            want_unversioned=True))
988
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.
989
    def make_trees_with_symlinks(self):
990
        tree1 = self.make_branch_and_tree('tree1')
991
        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
992
        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.
993
        self.build_tree(['tree1/fromfile', 'tree1/fromdir/'])
994
        self.build_tree(['tree2/tofile', 'tree2/todir/', 'tree2/unknown'])
995
        os.symlink('original', 'tree1/changed')
996
        os.symlink('original', 'tree1/removed')
997
        os.symlink('original', 'tree1/tofile')
998
        os.symlink('original', 'tree1/todir')
999
        # we make the unchanged link point at unknown to catch incorrect
1000
        # symlink-following code in the specified_files test.
1001
        os.symlink('unknown', 'tree1/unchanged')
1002
        os.symlink('new',      'tree2/added')
1003
        os.symlink('new',      'tree2/changed')
1004
        os.symlink('new',      'tree2/fromfile')
1005
        os.symlink('new',      'tree2/fromdir')
1006
        os.symlink('unknown', 'tree2/unchanged')
1007
        from_paths_and_ids = [
1008
            'fromdir',
1009
            'fromfile',
1010
            'changed',
1011
            'removed',
1012
            'todir',
1013
            'tofile',
1014
            'unchanged',
1015
            ]
1016
        to_paths_and_ids = [
1017
            'added',
1018
            'fromdir',
1019
            'fromfile',
1020
            'changed',
1021
            'todir',
1022
            'tofile',
1023
            'unchanged',
1024
            ]
1025
        tree1.add(from_paths_and_ids, from_paths_and_ids)
1026
        tree2.add(to_paths_and_ids, to_paths_and_ids)
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1027
        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.
1028
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1029
    def test_versioned_symlinks(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1030
        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.
1031
        tree1, tree2 = self.make_trees_with_symlinks()
1032
        root_id = tree1.path2id('')
1033
        expected = [
1034
            self.unchanged(tree1, tree1.path2id('')),
1035
            self.added(tree2, 'added'),
1036
            self.content_changed(tree2, 'changed'),
1037
            self.kind_changed(tree1, tree2, 'fromdir'),
1038
            self.kind_changed(tree1, tree2, 'fromfile'),
1039
            self.deleted(tree1, 'removed'),
1040
            self.unchanged(tree2, 'unchanged'),
1041
            self.unversioned(tree2, 'unknown'),
1042
            self.kind_changed(tree1, tree2, 'todir'),
1043
            self.kind_changed(tree1, tree2, 'tofile'),
1044
            ]
1045
        expected = sorted(expected)
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1046
        self.assertEqual(expected,
1047
            self.do_iter_changes(tree1, tree2, include_unchanged=True,
1048
                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.
1049
2255.7.88 by Robert Collins
Enable InterTree._iter_changes symlink tests.
1050
    def test_versioned_symlinks_specific_files(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
1051
        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.
1052
        tree1, tree2 = self.make_trees_with_symlinks()
1053
        root_id = tree1.path2id('')
1054
        expected = [
1055
            self.added(tree2, 'added'),
1056
            self.content_changed(tree2, 'changed'),
1057
            self.kind_changed(tree1, tree2, 'fromdir'),
1058
            self.kind_changed(tree1, tree2, 'fromfile'),
1059
            self.deleted(tree1, 'removed'),
1060
            self.kind_changed(tree1, tree2, 'todir'),
1061
            self.kind_changed(tree1, tree2, 'tofile'),
1062
            ]
1063
        expected = sorted(expected)
1064
        # we should get back just the changed links. We pass in 'unchanged' to
1065
        # make sure that it is correctly not returned - and neither is the
1066
        # unknown path 'unknown' which it points at.
1067
        self.assertEqual(expected, self.do_iter_changes(tree1, tree2,
1068
            specific_files=['added', 'changed', 'fromdir', 'fromfile',
1069
            '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.
1070
2255.7.21 by John Arbash Meinel
Get iter_changes working again, by fixing set_parent_trees to
1071
    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.
1072
        tree1, tree2, paths, path_ids = self.make_tree_with_special_names()
1073
        expected = sorted(self.added(tree2, f_id) for f_id in path_ids)
1074
        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.
1075
1076
    def test_trees_with_special_names(self):
1077
        tree1, tree2, paths, path_ids = self.make_trees_with_special_names()
1078
        expected = sorted(self.content_changed(tree2, f_id) for f_id in path_ids
1079
                          if f_id.endswith('_f-id'))
1080
        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
1081
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
1082
    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.
1083
        tree1 = self.make_branch_and_tree('tree1')
1084
        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
1085
        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.
1086
        self.build_tree(['tree1/a', 'tree1/b/', 'tree1/b/c',
1087
                         'tree1/b/d/', 'tree1/b/d/e', 'tree1/f/', 'tree1/f/g',
1088
                         'tree2/a', 'tree2/f/', 'tree2/f/g'])
1089
        tree1.add(['a', 'b', 'b/c', 'b/d/', 'b/d/e', 'f', 'f/g'],
1090
                  ['a-id', 'b-id', 'c-id', 'd-id', 'e-id', 'f-id', 'g-id'])
1091
        tree2.add(['a', 'f', 'f/g'], ['a-id', 'f-id', 'g-id'])
1092
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1093
        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.
1094
        # 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.
1095
        expected = sorted([
1096
            self.content_changed(tree2, 'a-id'),
1097
            self.content_changed(tree2, 'g-id'),
1098
            self.deleted(tree1, 'b-id'),
1099
            self.deleted(tree1, 'c-id'),
1100
            self.deleted(tree1, 'd-id'),
1101
            self.deleted(tree1, 'e-id'),
1102
            ])
1103
        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.
1104
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1105
    def test_added_unicode(self):
1106
        tree1 = self.make_branch_and_tree('tree1')
1107
        tree2 = self.make_to_branch_and_tree('tree2')
1108
        root_id = tree1.get_root_id()
1109
        tree2.set_root_id(root_id)
1110
1111
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1112
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1113
        a_id = u'\u03b1-id'.encode('utf8')
1114
        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.
1115
        try:
1116
            self.build_tree([u'tree1/\u03b1/',
1117
                             u'tree2/\u03b1/',
1118
                             u'tree2/\u03b1/\u03c9-added',
1119
                            ])
1120
        except UnicodeError:
1121
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1122
        tree1.add([u'\u03b1'], [a_id])
1123
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-added'], [a_id, added_id])
1124
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1125
        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.
1126
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1127
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1128
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1129
        self.assertEqual([self.added(tree2, added_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1130
                         self.do_iter_changes(tree1, tree2,
1131
                                              specific_files=[u'\u03b1']))
1132
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1133
    def test_deleted_unicode(self):
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1134
        tree1 = self.make_branch_and_tree('tree1')
1135
        tree2 = self.make_to_branch_and_tree('tree2')
1136
        root_id = tree1.get_root_id()
1137
        tree2.set_root_id(root_id)
1138
1139
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1140
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1141
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1142
        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.
1143
        try:
1144
            self.build_tree([u'tree1/\u03b1/',
1145
                             u'tree1/\u03b1/\u03c9-deleted',
1146
                             u'tree2/\u03b1/',
1147
                            ])
1148
        except UnicodeError:
1149
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1150
        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.
1151
        tree2.add([u'\u03b1'], [a_id])
1152
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1153
        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.
1154
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1155
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1156
                         self.do_iter_changes(tree1, tree2))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1157
        self.assertEqual([self.deleted(tree1, deleted_id)],
2360.1.3 by John Arbash Meinel
Start splitting up the overzealous test into focused tests.
1158
                         self.do_iter_changes(tree1, tree2,
1159
                                              specific_files=[u'\u03b1']))
1160
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1161
    def test_modified_unicode(self):
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1162
        tree1 = self.make_branch_and_tree('tree1')
1163
        tree2 = self.make_to_branch_and_tree('tree2')
1164
        root_id = tree1.get_root_id()
1165
        tree2.set_root_id(root_id)
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1166
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1167
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1168
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1169
        a_id = u'\u03b1-id'.encode('utf8')
1170
        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.
1171
        try:
1172
            self.build_tree([u'tree1/\u03b1/',
1173
                             u'tree1/\u03b1/\u03c9-modified',
1174
                             u'tree2/\u03b1/',
1175
                             u'tree2/\u03b1/\u03c9-modified',
1176
                            ])
1177
        except UnicodeError:
1178
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1179
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1180
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-modified'], [a_id, mod_id])
1181
1182
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1183
1184
        self.assertEqual([self.content_changed(tree1, mod_id)],
1185
                         self.do_iter_changes(tree1, tree2))
1186
        self.assertEqual([self.content_changed(tree1, mod_id)],
1187
                         self.do_iter_changes(tree1, tree2,
1188
                                              specific_files=[u'\u03b1']))
1189
1190
    def test_renamed_unicode(self):
1191
        tree1 = self.make_branch_and_tree('tree1')
1192
        tree2 = self.make_to_branch_and_tree('tree2')
1193
        root_id = tree1.get_root_id()
1194
        tree2.set_root_id(root_id)
1195
1196
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1197
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1198
        a_id = u'\u03b1-id'.encode('utf8')
1199
        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.
1200
        try:
1201
            self.build_tree([u'tree1/\u03b1/',
1202
                             u'tree2/\u03b1/',
1203
                            ])
1204
        except UnicodeError:
1205
            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.
1206
        self.build_tree_contents([(u'tree1/\u03c9-source', 'contents\n'),
1207
                                  (u'tree2/\u03b1/\u03c9-target', 'contents\n'),
1208
                                 ])
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1209
        tree1.add([u'\u03b1', u'\u03c9-source'], [a_id, rename_id])
1210
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-target'], [a_id, rename_id])
1211
1212
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1213
1214
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1215
                         self.do_iter_changes(tree1, tree2))
1216
        self.assertEqual([self.renamed(tree1, tree2, rename_id, False)],
1217
                         self.do_iter_changes(tree1, tree2,
1218
                                              specific_files=[u'\u03b1']))
1219
1220
    def test_unchanged_unicode(self):
1221
        tree1 = self.make_branch_and_tree('tree1')
1222
        tree2 = self.make_to_branch_and_tree('tree2')
1223
        root_id = tree1.get_root_id()
1224
        tree2.set_root_id(root_id)
1225
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1226
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1227
        a_id = u'\u03b1-id'.encode('utf8')
1228
        subfile_id = u'\u03c9-subfile-id'.encode('utf8')
1229
        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.
1230
        try:
1231
            self.build_tree([u'tree1/\u03b1/',
1232
                             u'tree2/\u03b1/',
1233
                            ])
1234
        except UnicodeError:
1235
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1236
        self.build_tree_contents([
1237
            (u'tree1/\u03b1/\u03c9-subfile', 'sub contents\n'),
1238
            (u'tree2/\u03b1/\u03c9-subfile', 'sub contents\n'),
1239
            (u'tree1/\u03c9-rootfile', 'root contents\n'),
1240
            (u'tree2/\u03c9-rootfile', 'root contents\n'),
1241
            ])
1242
        tree1.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1243
                  [a_id, subfile_id, rootfile_id])
1244
        tree2.add([u'\u03b1', u'\u03b1/\u03c9-subfile', u'\u03c9-rootfile'],
1245
                  [a_id, subfile_id, rootfile_id])
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1246
2360.1.4 by John Arbash Meinel
Clean up of test_compare code.
1247
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1248
2360.1.1 by John Arbash Meinel
Basic implementation test that makes sure _iter_changes handles unknown files.
1249
        expected = sorted([
1250
            self.unchanged(tree1, root_id),
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1251
            self.unchanged(tree1, a_id),
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1252
            self.unchanged(tree1, subfile_id),
1253
            self.unchanged(tree1, rootfile_id),
1254
            ])
1255
        self.assertEqual(expected,
1256
                         self.do_iter_changes(tree1, tree2,
1257
                                              include_unchanged=True))
1258
1259
        # We should also be able to select just a subset
1260
        expected = sorted([
1261
            self.unchanged(tree1, a_id),
1262
            self.unchanged(tree1, subfile_id),
1263
            ])
1264
        self.assertEqual(expected,
1265
                         self.do_iter_changes(tree1, tree2,
1266
                                              specific_files=[u'\u03b1'],
1267
                                              include_unchanged=True))
1268
1269
    def test_unknown_unicode(self):
1270
        tree1 = self.make_branch_and_tree('tree1')
1271
        tree2 = self.make_to_branch_and_tree('tree2')
1272
        root_id = tree1.get_root_id()
1273
        tree2.set_root_id(root_id)
1274
        # u'\u03b1' == GREEK SMALL LETTER ALPHA
1275
        # u'\u03c9' == GREEK SMALL LETTER OMEGA
1276
        a_id = u'\u03b1-id'.encode('utf8')
2360.1.8 by John Arbash Meinel
Update the tests to handle when fs is non-unicode.
1277
        try:
1278
            self.build_tree([u'tree1/\u03b1/',
1279
                             u'tree2/\u03b1/',
1280
                             u'tree2/\u03b1/unknown_dir/',
1281
                             u'tree2/\u03b1/unknown_file',
1282
                             u'tree2/\u03b1/unknown_dir/file',
1283
                             u'tree2/\u03c9-unknown_root_file',
1284
                            ])
1285
        except UnicodeError:
1286
            raise tests.TestSkipped("Could not create Unicode files.")
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1287
        tree1.add([u'\u03b1'], [a_id])
1288
        tree2.add([u'\u03b1'], [a_id])
1289
1290
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1291
1292
        expected = sorted([
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1293
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1294
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1295
            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.
1296
            # a/unknown_dir/file should not be included because we should not
1297
            # recurse into unknown_dir
1298
            # self.unversioned(tree2, 'a/unknown_dir/file'),
1299
            ])
1300
        self.assertEqual(expected,
1301
                         self.do_iter_changes(tree1, tree2,
1302
                                              require_versioned=False,
1303
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1304
        self.assertEqual([], # Without want_unversioned we should get nothing
1305
                         self.do_iter_changes(tree1, tree2))
2360.1.2 by John Arbash Meinel
Add an overzealous test, for Unicode support of _iter_changes.
1306
1307
        # We should also be able to select just a subset
1308
        expected = sorted([
1309
            self.unversioned(tree2, u'\u03b1/unknown_dir'),
1310
            self.unversioned(tree2, u'\u03b1/unknown_file'),
1311
            ])
1312
        self.assertEqual(expected,
1313
                         self.do_iter_changes(tree1, tree2,
1314
                                              specific_files=[u'\u03b1'],
1315
                                              require_versioned=False,
1316
                                              want_unversioned=True))
2360.1.5 by John Arbash Meinel
Split out the unicode tests properly.
1317
        self.assertEqual([], # Without want_unversioned we should get nothing
1318
                         self.do_iter_changes(tree1, tree2,
1319
                                              specific_files=[u'\u03b1']))
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1320
1321
    def test_unknown_empty_dir(self):
1322
        tree1 = self.make_branch_and_tree('tree1')
1323
        tree2 = self.make_to_branch_and_tree('tree2')
1324
        root_id = tree1.get_root_id()
1325
        tree2.set_root_id(root_id)
1326
2402.2.4 by John Arbash Meinel
Clean up the setup for clarity (suggested by Robert)
1327
        # Start with 2 identical trees
1328
        self.build_tree(['tree1/a/', 'tree1/b/',
1329
                         'tree2/a/', 'tree2/b/'])
1330
        self.build_tree_contents([('tree1/b/file', 'contents\n'),
1331
                                  ('tree2/b/file', 'contents\n')])
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1332
        tree1.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1333
        tree2.add(['a', 'b', 'b/file'], ['a-id', 'b-id', 'b-file-id'])
1334
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1335
        # Now create some unknowns in tree2
1336
        # We should find both a/file and a/dir as unknown, but we shouldn't
1337
        # recurse into a/dir to find that a/dir/subfile is also unknown.
1338
        self.build_tree(['tree2/a/file', 'tree2/a/dir/', 'tree2/a/dir/subfile'])
1339
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1340
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1341
1342
        expected = sorted([
1343
            self.unversioned(tree2, u'a/file'),
2402.2.2 by John Arbash Meinel
Fix _iter_changes to properly handle versioned (but empty) directories
1344
            self.unversioned(tree2, u'a/dir'),
2402.2.1 by John Arbash Meinel
Add a test which exposes the bug in WT4._iter_changes()
1345
            ])
1346
        self.assertEqual(expected,
1347
                         self.do_iter_changes(tree1, tree2,
1348
                                              require_versioned=False,
1349
                                              want_unversioned=True))
2456.2.1 by John Arbash Meinel
(broken) Add a (failing) test that _iter_changes works correctly
1350
1351
    def test_rename_over_deleted(self):
1352
        tree1 = self.make_branch_and_tree('tree1')
1353
        tree2 = self.make_to_branch_and_tree('tree2')
1354
        root_id = tree1.get_root_id()
1355
        tree2.set_root_id(root_id)
1356
1357
        # The final changes should be:
1358
        #   touch a b c d
1359
        #   add a b c d
1360
        #   commit
1361
        #   rm a d
1362
        #   mv b a
1363
        #   mv c d
1364
        self.build_tree_contents([
1365
            ('tree1/a', 'a contents\n'),
1366
            ('tree1/b', 'b contents\n'),
1367
            ('tree1/c', 'c contents\n'),
1368
            ('tree1/d', 'd contents\n'),
1369
            ('tree2/a', 'b contents\n'),
1370
            ('tree2/d', 'c contents\n'),
1371
            ])
1372
        tree1.add(['a', 'b', 'c', 'd'], ['a-id', 'b-id', 'c-id', 'd-id'])
1373
        tree2.add(['a', 'd'], ['b-id', 'c-id'])
1374
1375
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1376
1377
        expected = sorted([
1378
            self.deleted(tree1, 'a-id'),
1379
            self.deleted(tree1, 'd-id'),
1380
            self.renamed(tree1, tree2, 'b-id', False),
1381
            self.renamed(tree1, tree2, 'c-id', False),
1382
            ])
1383
        self.assertEqual(expected,
1384
                         self.do_iter_changes(tree1, tree2))
2456.2.2 by John Arbash Meinel
Add another (failing) test case.
1385
1386
    def test_deleted_and_unknown(self):
1387
        """Test a file marked removed, but still present on disk."""
1388
        tree1 = self.make_branch_and_tree('tree1')
1389
        tree2 = self.make_to_branch_and_tree('tree2')
1390
        root_id = tree1.get_root_id()
1391
        tree2.set_root_id(root_id)
1392
1393
        # The final changes should be:
1394
        # bzr add a b c
1395
        # bzr rm --keep b
1396
        self.build_tree_contents([
1397
            ('tree1/a', 'a contents\n'),
1398
            ('tree1/b', 'b contents\n'),
1399
            ('tree1/c', 'c contents\n'),
1400
            ('tree2/a', 'a contents\n'),
1401
            ('tree2/b', 'b contents\n'),
1402
            ('tree2/c', 'c contents\n'),
1403
            ])
1404
        tree1.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
1405
        tree2.add(['a', 'c'], ['a-id', 'c-id'])
1406
1407
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1408
1409
        expected = sorted([
1410
            self.deleted(tree1, 'b-id'),
1411
            self.unversioned(tree2, 'b'),
1412
            ])
1413
        self.assertEqual(expected,
1414
                         self.do_iter_changes(tree1, tree2,
1415
                                              want_unversioned=True))
2456.2.5 by John Arbash Meinel
Make sure the output with want_unversioned=False is reasonable.
1416
        expected = sorted([
1417
            self.deleted(tree1, 'b-id'),
1418
            ])
1419
        self.assertEqual(expected,
1420
                         self.do_iter_changes(tree1, tree2,
1421
                                              want_unversioned=False))
2465.1.1 by John Arbash Meinel
Add a (failing) test exposing the bug in _iter_changes
1422
1423
    def test_renamed_and_added(self):
1424
        """Test when we have renamed a file, and put another in its place."""
1425
        tree1 = self.make_branch_and_tree('tree1')
1426
        tree2 = self.make_to_branch_and_tree('tree2')
1427
        root_id = tree1.get_root_id()
1428
        tree2.set_root_id(root_id)
1429
1430
        # The final changes are:
1431
        # bzr add b c
1432
        # bzr mv b a
1433
        # bzr mv c d
1434
        # bzr add b c
1435
1436
        self.build_tree_contents([
1437
            ('tree1/b', 'b contents\n'),
1438
            ('tree1/c', 'c contents\n'),
1439
            ('tree2/a', 'b contents\n'),
1440
            ('tree2/b', 'new b contents\n'),
1441
            ('tree2/c', 'new c contents\n'),
1442
            ('tree2/d', 'c contents\n'),
1443
            ])
1444
        tree1.add(['b', 'c'], ['b1-id', 'c1-id'])
1445
        tree2.add(['a', 'b', 'c', 'd'], ['b1-id', 'b2-id', 'c2-id', 'c1-id'])
1446
1447
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1448
1449
        expected = sorted([
1450
            self.renamed(tree1, tree2, 'b1-id', False),
1451
            self.renamed(tree1, tree2, 'c1-id', False),
1452
            self.added(tree2, 'b2-id'),
1453
            self.added(tree2, 'c2-id'),
1454
            ])
1455
        self.assertEqual(expected,
1456
                         self.do_iter_changes(tree1, tree2,
1457
                                              want_unversioned=True))
2472.3.1 by John Arbash Meinel
Fix bug #111288. When we don't have a match
1458
1459
    def test_renamed_and_unknown(self):
1460
        """A file was moved on the filesystem, but not in bzr."""
1461
        tree1 = self.make_branch_and_tree('tree1')
1462
        tree2 = self.make_to_branch_and_tree('tree2')
1463
        root_id = tree1.get_root_id()
1464
        tree2.set_root_id(root_id)
1465
1466
        # The final changes are:
1467
        # bzr add a b
1468
        # mv a a2
1469
1470
        self.build_tree_contents([
1471
            ('tree1/a', 'a contents\n'),
1472
            ('tree1/b', 'b contents\n'),
1473
            ('tree2/a', 'a contents\n'),
1474
            ('tree2/b', 'b contents\n'),
1475
            ])
1476
        tree1.add(['a', 'b'], ['a-id', 'b-id'])
1477
        tree2.add(['a', 'b'], ['a-id', 'b-id'])
1478
        os.rename('tree2/a', 'tree2/a2')
1479
1480
        tree1, tree2 = self.mutable_trees_to_locked_test_trees(tree1, tree2)
1481
1482
        expected = sorted([
1483
            self.missing('a-id', 'a', 'a', tree2.get_root_id(), 'file'),
1484
            self.unversioned(tree2, 'a2'),
1485
            ])
1486
        self.assertEqual(expected,
1487
                         self.do_iter_changes(tree1, tree2,
1488
                                              want_unversioned=True))