/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
17
"""Implementation tests for breezy.merge.Merger."""
4869.2.8 by Andrew Bennetts
Use _merge_type_registry for per_merger tests.
18
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
19
import os
20
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
21
from ..conflicts import TextConflict
22
from .. import (
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
23
    errors,
24
    merge as _mod_merge,
25
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
26
from . import (
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
27
    multiply_tests,
28
    TestCaseWithTransport,
29
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
30
from .test_merge_core import MergeBuilder
31
from ..transform import TreeTransform
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
32
33
34
6625.1.5 by Martin
Drop custom load_tests implementation and use unittest signature
35
def load_tests(loader, standard_tests, pattern):
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
36
    """Multiply tests for tranport implementations."""
37
    result = loader.suiteClass()
38
    scenarios = [
4869.2.8 by Andrew Bennetts
Use _merge_type_registry for per_merger tests.
39
        (name, {'merge_type': merger})
6259.3.5 by Martin Packman
Update bt.per_merger parametrisation to new registry location
40
        for name, merger in _mod_merge.merge_type_registry.items()]
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
41
    return multiply_tests(standard_tests, scenarios, result)
42
43
44
class TestMergeImplementation(TestCaseWithTransport):
45
46
    def do_merge(self, target_tree, source_tree, **kwargs):
6719.1.2 by Jelmer Vernooij
Fix some tests.
47
        merger = _mod_merge.Merger.from_revision_ids(
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
48
            target_tree, source_tree.last_revision(),
49
            other_branch=source_tree.branch)
50
        merger.merge_type=self.merge_type
51
        for name, value in kwargs.items():
52
            setattr(merger, name, value)
53
        merger.do_merge()
54
55
    def test_merge_specific_file(self):
56
        this_tree = self.make_branch_and_tree('this')
57
        this_tree.lock_write()
58
        self.addCleanup(this_tree.unlock)
59
        self.build_tree_contents([
60
            ('this/file1', 'a\nb\n'),
61
            ('this/file2', 'a\nb\n')
62
        ])
63
        this_tree.add(['file1', 'file2'])
64
        this_tree.commit('Added files')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
65
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
66
        self.build_tree_contents([
67
            ('other/file1', 'a\nb\nc\n'),
68
            ('other/file2', 'a\nb\nc\n')
69
        ])
70
        other_tree.commit('modified both')
71
        self.build_tree_contents([
72
            ('this/file1', 'd\na\nb\n'),
73
            ('this/file2', 'd\na\nb\n')
74
        ])
75
        this_tree.commit('modified both')
76
        self.do_merge(this_tree, other_tree, interesting_files=['file1'])
77
        self.assertFileEqual('d\na\nb\nc\n', 'this/file1')
78
        self.assertFileEqual('d\na\nb\n', 'this/file2')
79
80
    def test_merge_move_and_change(self):
81
        this_tree = self.make_branch_and_tree('this')
82
        this_tree.lock_write()
83
        self.addCleanup(this_tree.unlock)
84
        self.build_tree_contents([
85
            ('this/file1', 'line 1\nline 2\nline 3\nline 4\n'),
86
        ])
87
        this_tree.add('file1',)
88
        this_tree.commit('Added file')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
89
        other_tree = this_tree.controldir.sprout('other').open_workingtree()
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
90
        self.build_tree_contents([
91
            ('other/file1', 'line 1\nline 2 to 2.1\nline 3\nline 4\n'),
92
        ])
93
        other_tree.commit('Changed 2 to 2.1')
94
        self.build_tree_contents([
95
            ('this/file1', 'line 1\nline 3\nline 2\nline 4\n'),
96
        ])
97
        this_tree.commit('Swapped 2 & 3')
98
        self.do_merge(this_tree, other_tree)
99
        if self.merge_type is _mod_merge.LCAMerger:
4869.2.6 by Andrew Bennetts
test_merge_move_and_change should still be an expected fail for LCA merge.
100
            self.expectFailure(
101
                "lca merge doesn't conflict for move and change",
102
                self.assertFileEqual,
103
                'line 1\n'
104
                '<<<<<<< TREE\n'
105
                'line 3\n'
106
                'line 2\n'
107
                '=======\n'
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
108
                'line 2 to 2.1\n'
109
                'line 3\n'
4869.2.6 by Andrew Bennetts
test_merge_move_and_change should still be an expected fail for LCA merge.
110
                '>>>>>>> MERGE-SOURCE\n'
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
111
                'line 4\n', 'this/file1')
112
        else:
113
            self.assertFileEqual('line 1\n'
114
                '<<<<<<< TREE\n'
115
                'line 3\n'
116
                'line 2\n'
117
                '=======\n'
118
                'line 2 to 2.1\n'
119
                'line 3\n'
120
                '>>>>>>> MERGE-SOURCE\n'
121
                'line 4\n', 'this/file1')
122
123
    def test_modify_conflicts_with_delete(self):
124
        # If one side deletes a line, and the other modifies that line, then
125
        # the modification should be considered a conflict
126
        builder = self.make_branch_builder('test')
127
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
128
        builder.build_snapshot(None,
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
129
            [('add', ('', None, 'directory', None)),
130
             ('add', ('foo', 'foo-id', 'file', 'a\nb\nc\nd\ne\n')),
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
131
            ], revision_id='BASE-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
132
        # Delete 'b\n'
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
133
        builder.build_snapshot(['BASE-id'],
134
            [('modify', ('foo-id', 'a\nc\nd\ne\n'))],
135
            revision_id='OTHER-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
136
        # Modify 'b\n', add 'X\n'
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
137
        builder.build_snapshot(['BASE-id'],
138
            [('modify', ('foo-id', 'a\nb2\nc\nd\nX\ne\n'))],
139
            revision_id='THIS-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
140
        builder.finish_series()
141
        branch = builder.get_branch()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
142
        this_tree = branch.controldir.create_workingtree()
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
143
        this_tree.lock_write()
144
        self.addCleanup(this_tree.unlock)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
145
        other_tree = this_tree.controldir.sprout('other',
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
146
                                             'OTHER-id').open_workingtree()
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
147
        self.do_merge(this_tree, other_tree)
148
        if self.merge_type is _mod_merge.LCAMerger:
149
            self.expectFailure("lca merge doesn't track deleted lines",
150
                self.assertFileEqual,
151
                    'a\n'
152
                    '<<<<<<< TREE\n'
153
                    'b2\n'
154
                    '=======\n'
155
                    '>>>>>>> MERGE-SOURCE\n'
156
                    'c\n'
157
                    'd\n'
158
                    'X\n'
159
                    'e\n', 'test/foo')
160
        else:
161
            self.assertFileEqual(
162
                'a\n'
163
                '<<<<<<< TREE\n'
164
                'b2\n'
165
                '=======\n'
166
                '>>>>>>> MERGE-SOURCE\n'
167
                'c\n'
168
                'd\n'
169
                'X\n'
170
                'e\n', 'test/foo')
171
172
    def get_limbodir_deletiondir(self, wt):
173
        transform = TreeTransform(wt)
174
        limbodir = transform._limbodir
175
        deletiondir = transform._deletiondir
176
        transform.finalize()
177
        return (limbodir, deletiondir)
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
178
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
179
    def test_merge_with_existing_limbo_empty(self):
180
        """Empty limbo dir is just cleaned up - see bug 427773"""
181
        wt = self.make_branch_and_tree('this')
182
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
183
        os.mkdir(limbodir)
184
        self.do_merge(wt, wt)
185
186
    def test_merge_with_existing_limbo_non_empty(self):
187
        wt = self.make_branch_and_tree('this')
188
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
189
        os.mkdir(limbodir)
190
        os.mkdir(os.path.join(limbodir, 'something'))
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
191
        self.assertRaises(errors.ExistingLimbo, self.do_merge, wt, wt)
192
        self.assertRaises(errors.LockError, wt.unlock)
193
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
194
    def test_merge_with_pending_deletion_empty(self):
6015.51.2 by Martin Pool
Get the test names right
195
        wt = self.make_branch_and_tree('this')
196
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
197
        os.mkdir(deletiondir)
6015.51.3 by Martin Pool
test_merge_with_pending_deletion_empty: correct the assertions
198
        self.do_merge(wt, wt)
6015.51.2 by Martin Pool
Get the test names right
199
200
    def test_merge_with_pending_deletion_non_empty(self):
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
201
        """Also see bug 427773"""
202
        wt = self.make_branch_and_tree('this')
203
        (limbodir, deletiondir) =  self.get_limbodir_deletiondir(wt)
204
        os.mkdir(deletiondir)
205
        os.mkdir(os.path.join(deletiondir, 'something'))
206
        self.assertRaises(errors.ExistingPendingDeletion, self.do_merge, wt, wt)
207
        self.assertRaises(errors.LockError, wt.unlock)
208
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
209
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
210
class TestHookMergeFileContent(TestCaseWithTransport):
211
    """Tests that the 'merge_file_content' hook is invoked."""
212
4869.3.10 by Andrew Bennetts
Add more tests.
213
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
214
        super(TestHookMergeFileContent, self).setUp()
4869.3.10 by Andrew Bennetts
Add more tests.
215
        self.hook_log = []
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
216
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
217
    def install_hook_inactive(self):
218
        def inactive_factory(merger):
219
            # This hook is never active
220
            self.hook_log.append(('inactive',))
221
            return None
222
        _mod_merge.Merger.hooks.install_named_hook(
223
            'merge_file_content', inactive_factory, 'test hook (inactive)')
224
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
225
    def install_hook_noop(self):
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
226
        test = self
227
        class HookNA(_mod_merge.AbstractPerFileMerger):
228
            def merge_contents(self, merge_params):
229
                # This hook unconditionally does nothing.
230
                test.hook_log.append(('no-op',))
231
                return 'not_applicable', None
232
        def hook_na_factory(merger):
233
            return HookNA(merger)
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
234
        _mod_merge.Merger.hooks.install_named_hook(
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
235
            'merge_file_content', hook_na_factory, 'test hook (no-op)')
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
236
237
    def install_hook_success(self):
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
238
        test = self
239
        class HookSuccess(_mod_merge.AbstractPerFileMerger):
240
            def merge_contents(self, merge_params):
241
                test.hook_log.append(('success',))
242
                if merge_params.file_id == '1':
243
                    return 'success', ['text-merged-by-hook']
244
                return 'not_applicable', None
245
        def hook_success_factory(merger):
246
            return HookSuccess(merger)
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
247
        _mod_merge.Merger.hooks.install_named_hook(
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
248
            'merge_file_content', hook_success_factory, 'test hook (success)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
249
4869.3.6 by Andrew Bennetts
Add more tests.
250
    def install_hook_conflict(self):
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
251
        test = self
252
        class HookConflict(_mod_merge.AbstractPerFileMerger):
253
            def merge_contents(self, merge_params):
254
                test.hook_log.append(('conflict',))
255
                if merge_params.file_id == '1':
256
                    return ('conflicted',
257
                        ['text-with-conflict-markers-from-hook'])
258
                return 'not_applicable', None
259
        def hook_conflict_factory(merger):
260
            return HookConflict(merger)
4869.3.6 by Andrew Bennetts
Add more tests.
261
        _mod_merge.Merger.hooks.install_named_hook(
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
262
            'merge_file_content', hook_conflict_factory, 'test hook (delete)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
263
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
264
    def install_hook_delete(self):
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
265
        test = self
266
        class HookDelete(_mod_merge.AbstractPerFileMerger):
267
            def merge_contents(self, merge_params):
268
                test.hook_log.append(('delete',))
269
                if merge_params.file_id == '1':
270
                    return 'delete', None
271
                return 'not_applicable', None
272
        def hook_delete_factory(merger):
273
            return HookDelete(merger)
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
274
        _mod_merge.Merger.hooks.install_named_hook(
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
275
            'merge_file_content', hook_delete_factory, 'test hook (delete)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
276
4869.3.6 by Andrew Bennetts
Add more tests.
277
    def install_hook_log_lines(self):
278
        """Install a hook that saves the get_lines for the this, base and other
279
        versions of the file.
280
        """
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
281
        test = self
282
        class HookLogLines(_mod_merge.AbstractPerFileMerger):
283
            def merge_contents(self, merge_params):
284
                test.hook_log.append((
285
                    'log_lines',
286
                    merge_params.this_lines,
287
                    merge_params.other_lines,
288
                    merge_params.base_lines,
289
                    ))
290
                return 'not_applicable', None
291
        def hook_log_lines_factory(merger):
292
            return HookLogLines(merger)
4869.3.6 by Andrew Bennetts
Add more tests.
293
        _mod_merge.Merger.hooks.install_named_hook(
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
294
            'merge_file_content', hook_log_lines_factory,
295
            'test hook (log_lines)')
4869.3.6 by Andrew Bennetts
Add more tests.
296
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
297
    def make_merge_builder(self):
298
        builder = MergeBuilder(self.test_base_dir)
299
        self.addCleanup(builder.cleanup)
300
        return builder
301
4869.3.10 by Andrew Bennetts
Add more tests.
302
    def create_file_needing_contents_merge(self, builder, file_id):
303
        builder.add_file(file_id, builder.tree_root, "name1", "text1", True)
304
        builder.change_contents(file_id, other="text4", this="text3")
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
305
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
306
    def test_change_vs_change(self):
307
        """Hook is used for (changed, changed)"""
308
        self.install_hook_success()
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
309
        builder = self.make_merge_builder()
310
        builder.add_file("1", builder.tree_root, "name1", "text1", True)
311
        builder.change_contents("1", other="text4", this="text3")
312
        conflicts = builder.merge(self.merge_type)
313
        self.assertEqual(conflicts, [])
314
        self.assertEqual(
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
315
            builder.this.get_file('name1').read(), 'text-merged-by-hook')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
316
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
317
    def test_change_vs_deleted(self):
318
        """Hook is used for (changed, deleted)"""
319
        self.install_hook_success()
320
        builder = self.make_merge_builder()
321
        builder.add_file("1", builder.tree_root, "name1", "text1", True)
322
        builder.change_contents("1", this="text2")
323
        builder.remove_file("1", other=True)
324
        conflicts = builder.merge(self.merge_type)
325
        self.assertEqual(conflicts, [])
326
        self.assertEqual(
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
327
            builder.this.get_file('name1').read(), 'text-merged-by-hook')
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
328
329
    def test_result_can_be_delete(self):
330
        """A hook's result can be the deletion of a file."""
331
        self.install_hook_delete()
332
        builder = self.make_merge_builder()
4869.3.10 by Andrew Bennetts
Add more tests.
333
        self.create_file_needing_contents_merge(builder, "1")
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
334
        conflicts = builder.merge(self.merge_type)
335
        self.assertEqual(conflicts, [])
336
        self.assertRaises(errors.NoSuchId, builder.this.id2path, '1')
4869.3.14 by Andrew Bennetts
Fix bug that would leave an unversioned file behind when a hook asks for a deletion.
337
        self.assertEqual([], list(builder.this.list_files()))
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
338
4869.3.6 by Andrew Bennetts
Add more tests.
339
    def test_result_can_be_conflict(self):
340
        """A hook's result can be a conflict."""
341
        self.install_hook_conflict()
342
        builder = self.make_merge_builder()
4869.3.10 by Andrew Bennetts
Add more tests.
343
        self.create_file_needing_contents_merge(builder, "1")
4869.3.6 by Andrew Bennetts
Add more tests.
344
        conflicts = builder.merge(self.merge_type)
345
        self.assertEqual(conflicts, [TextConflict('name1', file_id='1')])
346
        # The hook still gets to set the file contents in this case, so that it
347
        # can insert custom conflict markers.
348
        self.assertEqual(
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
349
            builder.this.get_file('name1').read(),
4869.3.6 by Andrew Bennetts
Add more tests.
350
            'text-with-conflict-markers-from-hook')
351
352
    def test_can_access_this_other_and_base_versions(self):
353
        """The hook function can call params.merger.get_lines to access the
354
        THIS/OTHER/BASE versions of the file.
355
        """
356
        self.install_hook_log_lines()
357
        builder = self.make_merge_builder()
358
        builder.add_file("1", builder.tree_root, "name1", "text1", True)
359
        builder.change_contents("1", this="text2", other="text3")
360
        conflicts = builder.merge(self.merge_type)
361
        self.assertEqual(
4869.3.10 by Andrew Bennetts
Add more tests.
362
            [('log_lines', ['text2'], ['text3'], ['text1'])], self.hook_log)
363
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
364
    def test_chain_when_not_active(self):
365
        """When a hook function returns None, merging still works."""
366
        self.install_hook_inactive()
367
        self.install_hook_success()
368
        builder = self.make_merge_builder()
369
        self.create_file_needing_contents_merge(builder, "1")
370
        conflicts = builder.merge(self.merge_type)
371
        self.assertEqual(conflicts, [])
372
        self.assertEqual(
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
373
            builder.this.get_file('name1').read(), 'text-merged-by-hook')
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
374
        self.assertEqual([('inactive',), ('success',)], self.hook_log)
375
4869.3.10 by Andrew Bennetts
Add more tests.
376
    def test_chain_when_not_applicable(self):
377
        """When a hook function returns not_applicable, the next function is
378
        tried (when one exists).
379
        """
380
        self.install_hook_noop()
381
        self.install_hook_success()
382
        builder = self.make_merge_builder()
383
        self.create_file_needing_contents_merge(builder, "1")
384
        conflicts = builder.merge(self.merge_type)
385
        self.assertEqual(conflicts, [])
386
        self.assertEqual(
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
387
            builder.this.get_file('name1').read(), 'text-merged-by-hook')
4869.3.10 by Andrew Bennetts
Add more tests.
388
        self.assertEqual([('no-op',), ('success',)], self.hook_log)
389
390
    def test_chain_stops_after_success(self):
391
        """When a hook function returns success, no later functions are tried.
392
        """
393
        self.install_hook_success()
394
        self.install_hook_noop()
395
        builder = self.make_merge_builder()
396
        self.create_file_needing_contents_merge(builder, "1")
397
        conflicts = builder.merge(self.merge_type)
398
        self.assertEqual([('success',)], self.hook_log)
399
400
    def test_chain_stops_after_conflict(self):
401
        """When a hook function returns conflict, no later functions are tried.
402
        """
403
        self.install_hook_conflict()
404
        self.install_hook_noop()
405
        builder = self.make_merge_builder()
406
        self.create_file_needing_contents_merge(builder, "1")
407
        conflicts = builder.merge(self.merge_type)
408
        self.assertEqual([('conflict',)], self.hook_log)
409
410
    def test_chain_stops_after_delete(self):
411
        """When a hook function returns delete, no later functions are tried.
412
        """
413
        self.install_hook_delete()
414
        self.install_hook_noop()
415
        builder = self.make_merge_builder()
416
        self.create_file_needing_contents_merge(builder, "1")
417
        conflicts = builder.merge(self.merge_type)
418
        self.assertEqual([('delete',)], self.hook_log)
4869.3.6 by Andrew Bennetts
Add more tests.
419