/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
1
# Copyright (C) 2006 by Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for the InterTree.compare() function."""
18
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
19
import os
20
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
21
from bzrlib import errors
1852.8.3 by Robert Collins
Implement an InterTreeTestProvider and a trivial test_compare test case.
22
from bzrlib.tests.intertree_implementations import TestCaseWithTwoTrees
23
24
25
class TestCompare(TestCaseWithTwoTrees):
26
27
    def test_compare_empty_trees(self):
28
        tree1 = self.make_branch_and_tree('1')
29
        tree2 = self.make_to_branch_and_tree('2')
30
        tree1 = self.get_tree_no_parents_no_content(tree1)
31
        tree2 = self.get_to_tree_no_parents_no_content(tree2)
32
        d = self.intertree_class(tree1, tree2).compare()
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
33
        self.assertEqual([], d.added)
34
        self.assertEqual([], d.modified)
35
        self.assertEqual([], d.removed)
36
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
37
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
38
39
    def test_empty_to_abc_content(self):
40
        tree1 = self.make_branch_and_tree('1')
41
        tree2 = self.make_to_branch_and_tree('2')
42
        tree1 = self.get_tree_no_parents_no_content(tree1)
43
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
44
        d = self.intertree_class(tree1, tree2).compare()
45
        self.assertEqual([('a', 'a-id', 'file'),
46
                          ('b', 'b-id', 'directory'),
47
                          ('b/c', 'c-id', 'file'),
48
                         ], d.added)
49
        self.assertEqual([], d.modified)
50
        self.assertEqual([], d.removed)
51
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
52
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
53
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
54
    def test_dangling(self):
55
        tree1 = self.make_branch_and_tree('1')
56
        tree2 = self.make_branch_and_tree('2')
57
        self.build_tree(['2/a'])
58
        tree2.add('a')
59
        os.unlink('2/a')
60
        self.build_tree(['1/b'])
61
        tree1.add('b')
62
        os.unlink('1/b')
63
        d = self.intertree_class(tree1, tree2).compare()
64
        self.assertEqual([], d.added)
65
        self.assertEqual([], d.modified)
66
        self.assertEqual([], d.removed)
67
        self.assertEqual([], d.renamed)
68
        self.assertEqual([], d.unchanged)
69
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
70
    def test_abc_content_to_empty(self):
71
        tree1 = self.make_branch_and_tree('1')
72
        tree2 = self.make_to_branch_and_tree('2')
73
        tree1 = self.get_tree_no_parents_abc_content(tree1)
74
        tree2 = self.get_to_tree_no_parents_no_content(tree2)
75
        d = self.intertree_class(tree1, tree2).compare()
76
        self.assertEqual([], d.added)
77
        self.assertEqual([], d.modified)
78
        self.assertEqual([('a', 'a-id', 'file'),
79
                          ('b', 'b-id', 'directory'),
80
                          ('b/c', 'c-id', 'file'),
81
                         ], d.removed)
82
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
83
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
84
85
    def test_content_modification(self):
86
        tree1 = self.make_branch_and_tree('1')
87
        tree2 = self.make_to_branch_and_tree('2')
88
        tree1 = self.get_tree_no_parents_abc_content(tree1)
89
        tree2 = self.get_to_tree_no_parents_abc_content_2(tree2)
90
        d = self.intertree_class(tree1, tree2).compare()
91
        self.assertEqual([], d.added)
92
        self.assertEqual([('a', 'a-id', 'file', True, False)], d.modified)
93
        self.assertEqual([], d.removed)
94
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
95
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
96
        
97
    def test_meta_modification(self):
98
        tree1 = self.make_branch_and_tree('1')
99
        tree2 = self.make_to_branch_and_tree('2')
100
        tree1 = self.get_tree_no_parents_abc_content(tree1)
101
        tree2 = self.get_to_tree_no_parents_abc_content_3(tree2)
102
        d = self.intertree_class(tree1, tree2).compare()
103
        self.assertEqual([], d.added)
104
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
105
        self.assertEqual([], d.removed)
106
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
107
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
108
109
    def test_file_rename(self):
110
        tree1 = self.make_branch_and_tree('1')
111
        tree2 = self.make_to_branch_and_tree('2')
112
        tree1 = self.get_tree_no_parents_abc_content(tree1)
113
        tree2 = self.get_to_tree_no_parents_abc_content_4(tree2)
114
        d = self.intertree_class(tree1, tree2).compare()
115
        self.assertEqual([], d.added)
116
        self.assertEqual([], d.modified)
117
        self.assertEqual([], d.removed)
118
        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=...).
119
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
120
121
    def test_file_rename_and_modification(self):
122
        tree1 = self.make_branch_and_tree('1')
123
        tree2 = self.make_to_branch_and_tree('2')
124
        tree1 = self.get_tree_no_parents_abc_content(tree1)
125
        tree2 = self.get_to_tree_no_parents_abc_content_5(tree2)
126
        d = self.intertree_class(tree1, tree2).compare()
127
        self.assertEqual([], d.added)
128
        self.assertEqual([], d.modified)
129
        self.assertEqual([], d.removed)
130
        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=...).
131
        self.assertEqual([], d.unchanged)
1852.9.2 by Robert Collins
Convert stock delta tests to intertree_implementation tests of InterTree.compare.
132
133
    def test_file_rename_and_meta_modification(self):
134
        tree1 = self.make_branch_and_tree('1')
135
        tree2 = self.make_to_branch_and_tree('2')
136
        tree1 = self.get_tree_no_parents_abc_content(tree1)
137
        tree2 = self.get_to_tree_no_parents_abc_content_6(tree2)
138
        d = self.intertree_class(tree1, tree2).compare()
139
        self.assertEqual([], d.added)
140
        self.assertEqual([], d.modified)
141
        self.assertEqual([], d.removed)
142
        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=...).
143
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
144
145
    def test_empty_to_abc_content_a_only(self):
146
        tree1 = self.make_branch_and_tree('1')
147
        tree2 = self.make_to_branch_and_tree('2')
148
        tree1 = self.get_tree_no_parents_no_content(tree1)
149
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
150
        d = self.intertree_class(tree1, tree2).compare(specific_files=['a'])
151
        self.assertEqual([('a', 'a-id', 'file')], d.added)
152
        self.assertEqual([], d.modified)
153
        self.assertEqual([], d.removed)
154
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
155
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
156
157
    def test_empty_to_abc_content_a_and_c_only(self):
158
        tree1 = self.make_branch_and_tree('1')
159
        tree2 = self.make_to_branch_and_tree('2')
160
        tree1 = self.get_tree_no_parents_no_content(tree1)
161
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
162
        d = self.intertree_class(tree1, tree2).compare(
163
            specific_files=['a', 'b/c'])
164
        self.assertEqual(
165
            [('a', 'a-id', 'file'), ('b/c', 'c-id', 'file')],
166
            d.added)
167
        self.assertEqual([], d.modified)
168
        self.assertEqual([], d.removed)
169
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
170
        self.assertEqual([], d.unchanged)
1852.9.3 by Robert Collins
Convert the test_delta tests to intertree_implementation and workingtree_implementation tests as appropriate.
171
172
    def test_empty_to_abc_content_b_only(self):
173
        """Restricting to a dir matches the children of the dir."""
174
        tree1 = self.make_branch_and_tree('1')
175
        tree2 = self.make_to_branch_and_tree('2')
176
        tree1 = self.get_tree_no_parents_no_content(tree1)
177
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
178
        d = self.intertree_class(tree1, tree2).compare(specific_files=['b'])
179
        self.assertEqual(
180
            [('b', 'b-id', 'directory'),('b/c', 'c-id', 'file')],
181
            d.added)
182
        self.assertEqual([], d.modified)
183
        self.assertEqual([], d.removed)
184
        self.assertEqual([], d.renamed)
1852.9.4 by Robert Collins
Add minimal test for Tree.compare(extra_trees=...).
185
        self.assertEqual([], d.unchanged)
186
187
    def test_unchanged_with_renames_and_modifications(self):
188
        """want_unchanged should generate a list of unchanged entries."""
189
        tree1 = self.make_branch_and_tree('1')
190
        tree2 = self.make_to_branch_and_tree('2')
191
        tree1 = self.get_tree_no_parents_abc_content(tree1)
192
        tree2 = self.get_to_tree_no_parents_abc_content_5(tree2)
193
        d = self.intertree_class(tree1, tree2).compare(want_unchanged=True)
194
        self.assertEqual([], d.added)
195
        self.assertEqual([], d.modified)
196
        self.assertEqual([], d.removed)
197
        self.assertEqual([('a', 'd', 'a-id', 'file', True, False)], d.renamed)
198
        self.assertEqual(
199
            [(u'b', 'b-id', 'directory'), (u'b/c', 'c-id', 'file')],
200
            d.unchanged)
201
202
    def test_extra_trees_finds_ids(self):
203
        """Ask for a delta between two trees with a path present in a third."""
204
        tree1 = self.make_branch_and_tree('1')
205
        tree2 = self.make_to_branch_and_tree('2')
206
        tree1 = self.get_tree_no_parents_abc_content(tree1)
207
        tree2 = self.get_to_tree_no_parents_abc_content_3(tree2)
208
        # the type of tree-3 does not matter - it is used as a lookup, not
209
        # a dispatch
210
        tree3 = self.make_branch_and_tree('3')
211
        tree3 = self.get_tree_no_parents_abc_content_6(tree3)
212
        # tree 3 has 'e' which is 'c-id'. Tree 1 has c-id at b/c, and Tree 2
213
        # has c-id at b/c with its exec flag toggled.
214
        # without extra_trees, we should get no modifications from this
215
        # so do one, to be sure the test is valid.
216
        d = self.intertree_class(tree1, tree2).compare(
217
            specific_files=['e'])
218
        self.assertEqual([], d.modified)
219
        # now give it an additional lookup:
220
        d = self.intertree_class(tree1, tree2).compare(
221
            specific_files=['e'], extra_trees=[tree3])
222
        self.assertEqual([], d.added)
223
        self.assertEqual([('b/c', 'c-id', 'file', False, True)], d.modified)
224
        self.assertEqual([], d.removed)
225
        self.assertEqual([], d.renamed)
226
        self.assertEqual([], d.unchanged)
1852.9.5 by Robert Collins
Add tests for require_versioned to the InterTree.compare() test suite.
227
228
    def test_require_versioned(self):
229
        # this does not quite robustly test, as it is passing in missing paths
230
        # rather than present-but-not-versioned paths. At the moment there is
231
        # no mechanism for managing the test trees (which are readonly) to 
232
        # get present-but-not-versioned files for trees that can do that.
233
        tree1 = self.make_branch_and_tree('1')
234
        tree2 = self.make_to_branch_and_tree('2')
235
        tree1 = self.get_tree_no_parents_no_content(tree1)
236
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
237
        self.assertRaises(errors.PathsNotVersionedError, 
238
            self.intertree_class(tree1, tree2).compare,
239
            specific_files=['d'],
240
            require_versioned=True)
2012.1.1 by Aaron Bentley
Implement change iterator
241
242
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
243
class TestIterChanges(TestCaseWithTwoTrees):
2012.1.1 by Aaron Bentley
Implement change iterator
244
    """Test the comparison iterator"""
245
246
    def test_compare_empty_trees(self):
247
        tree1 = self.make_branch_and_tree('1')
248
        tree2 = self.make_to_branch_and_tree('2')
249
        tree1 = self.get_tree_no_parents_no_content(tree1)
250
        tree2 = self.get_to_tree_no_parents_no_content(tree2)
251
        self.assertEqual([], list(tree2.iter_changes(tree1)))
252
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
253
    def added(self, tree, file_id):
254
        entry = tree.inventory[file_id]
255
        path = tree.id2path(file_id)
256
        return (file_id, path, True, (False, True), (None, entry.parent_id),
257
                (None, entry.name), (None, entry.kind), 
258
                (None, entry.executable))
259
260
    def deleted(self, tree, file_id):
261
        entry = tree.inventory[file_id]
262
        path = tree.id2path(file_id)
263
        return (file_id, path, True, (True, False), (entry.parent_id, None),
264
                (entry.name, None), (entry.kind, None), 
265
                (entry.executable, None))
266
2012.1.1 by Aaron Bentley
Implement change iterator
267
    def test_empty_to_abc_content(self):
268
        tree1 = self.make_branch_and_tree('1')
269
        tree2 = self.make_to_branch_and_tree('2')
270
        tree1 = self.get_tree_no_parents_no_content(tree1)
271
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
272
            
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
273
        self.assertEqual([self.added(tree2, 'a-id'), 
274
                          self.added(tree2, 'b-id'), 
275
                          self.added(tree2, 'c-id')],
2012.1.1 by Aaron Bentley
Implement change iterator
276
                         list(tree2.iter_changes(tree1)))
277
2012.1.5 by Aaron Bentley
Implement specific file id and dangling id handling
278
    def test_empty_to_abc_content_a_only(self):
279
        tree1 = self.make_branch_and_tree('1')
280
        tree2 = self.make_to_branch_and_tree('2')
281
        tree1 = self.get_tree_no_parents_no_content(tree1)
282
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
283
        self.assertEqual([self.added(tree2, 'a-id')],
284
                         list(tree2.iter_changes(tree1, 
285
                                                 specific_file_ids=['a-id'])))
286
        self.assertEqual([self.deleted(tree2, 'a-id')],
287
                         list(tree1.iter_changes(tree2, 
288
                                                 specific_file_ids=['a-id'])))
289
290
    def test_empty_to_abc_content_a_and_c_only(self):
291
        tree1 = self.make_branch_and_tree('1')
292
        tree2 = self.make_to_branch_and_tree('2')
293
        tree1 = self.get_tree_no_parents_no_content(tree1)
294
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
295
        self.assertEqual([self.added(tree2, 'a-id'),
296
                          self.added(tree2, 'c-id')],
297
                         list(tree2.iter_changes(tree1, 
298
                                                 specific_file_ids=['a-id', 
299
                                                                    'c-id'])))
300
        d = self.intertree_class(tree1, tree2).compare(
301
            specific_files=['a', 'b/c'])
302
2012.1.1 by Aaron Bentley
Implement change iterator
303
    def test_abc_content(self):
304
        tree1 = self.make_branch_and_tree('1')
305
        tree2 = self.make_to_branch_and_tree('2')
306
        tree1 = self.get_tree_no_parents_no_content(tree1)
307
        tree2 = self.get_to_tree_no_parents_abc_content(tree2)
308
        def deleted(file_id):
309
            entry = tree2.inventory[file_id]
310
            path = tree2.id2path(file_id)
311
            return (file_id, path, True, (True, False), 
312
                    (entry.parent_id, None),
313
                    (entry.name, None), (entry.kind, None), 
314
                    (entry.executable, None))
315
            
316
        self.assertEqual([deleted('a-id'), deleted('b-id'), deleted('c-id')],
317
                         list(tree1.iter_changes(tree2)))
318
319
    def test_content_modification(self):
320
        tree1 = self.make_branch_and_tree('1')
321
        tree2 = self.make_to_branch_and_tree('2')
322
        tree1 = self.get_tree_no_parents_abc_content(tree1)
323
        tree2 = self.get_to_tree_no_parents_abc_content_2(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
324
        root_id = tree1.inventory.root.file_id
325
        self.assertEqual([('a-id', 'a', True, (True, True), 
326
                          (root_id, root_id), ('a', 'a'), 
327
                          ('file', 'file'), (False, False))], 
2012.1.1 by Aaron Bentley
Implement change iterator
328
                         list(tree2.iter_changes(tree1)))
329
330
    def test_meta_modification(self):
331
        tree1 = self.make_branch_and_tree('1')
332
        tree2 = self.make_to_branch_and_tree('2')
333
        tree1 = self.get_tree_no_parents_abc_content(tree1)
334
        tree2 = self.get_to_tree_no_parents_abc_content_3(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
335
        self.assertEqual([('c-id', 'b/c', False, (True, True), 
336
                          ('b-id', 'b-id'), ('c', 'c'), ('file', 'file'), 
2012.1.1 by Aaron Bentley
Implement change iterator
337
                          (False, True))], list(tree2.iter_changes(tree1)))
338
339
    def test_file_rename(self):
340
        tree1 = self.make_branch_and_tree('1')
341
        tree2 = self.make_to_branch_and_tree('2')
342
        tree1 = self.get_tree_no_parents_abc_content(tree1)
343
        tree2 = self.get_to_tree_no_parents_abc_content_4(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
344
        root_id = tree1.inventory.root.file_id
345
        self.assertEqual([('a-id', 'd', False, (True, True), 
346
                          (root_id, root_id), ('a', 'd'), ('file', 'file'),
347
                          (False, False))], list(tree2.iter_changes(tree1)))
2012.1.1 by Aaron Bentley
Implement change iterator
348
349
    def test_file_rename_and_modification(self):
350
        tree1 = self.make_branch_and_tree('1')
351
        tree2 = self.make_to_branch_and_tree('2')
352
        tree1 = self.get_tree_no_parents_abc_content(tree1)
353
        tree2 = self.get_to_tree_no_parents_abc_content_5(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
354
        root_id = tree1.inventory.root.file_id
355
        self.assertEqual([('a-id', 'd', True, (True, True), 
356
                          (root_id, root_id), ('a', 'd'), ('file', 'file'),
357
                           (False, False))], list(tree2.iter_changes(tree1)))
2012.1.1 by Aaron Bentley
Implement change iterator
358
359
    def test_file_rename_and_meta_modification(self):
360
        tree1 = self.make_branch_and_tree('1')
361
        tree2 = self.make_to_branch_and_tree('2')
362
        tree1 = self.get_tree_no_parents_abc_content(tree1)
363
        tree2 = self.get_to_tree_no_parents_abc_content_6(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
364
        root_id = tree1.inventory.root.file_id
365
        self.assertEqual([('c-id', 'e', False, (True, True), 
366
                          ('b-id', root_id), ('c', 'e'), ('file', 'file'), 
2012.1.1 by Aaron Bentley
Implement change iterator
367
                          (False, True))], list(tree2.iter_changes(tree1)))
368
369
    def test_unchanged_with_renames_and_modifications(self):
370
        """want_unchanged should generate a list of unchanged entries."""
371
        tree1 = self.make_branch_and_tree('1')
372
        tree2 = self.make_to_branch_and_tree('2')
373
        tree1 = self.get_tree_no_parents_abc_content(tree1)
374
        tree2 = self.get_to_tree_no_parents_abc_content_5(tree2)
2012.1.3 by Aaron Bentley
Always generate tuples (because kind is always used, even when not different)
375
        root_id = tree1.inventory.root.file_id
376
        def unchanged(file_id):
377
            entry = tree1.inventory[file_id]
378
            parent = entry.parent_id
379
            name = entry.name
380
            kind = entry.kind
381
            executable = entry.executable
382
            return (file_id, tree1.id2path(file_id), False, (True, True), 
383
                   (parent, parent), (name, name), (kind, kind), 
384
                   (executable, executable))
385
        self.assertEqual([unchanged(root_id), unchanged('b-id'),
386
                          ('a-id', 'd', True, (True, True), 
387
                          (root_id, root_id), ('a', 'd'), ('file', 'file'),
388
                          (False, False)), unchanged('c-id')],
389
                         list(tree2.iter_changes(tree1, 
390
                                                 include_unchanged=True)))