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