/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([
6855.4.1 by Jelmer Vernooij
Yet more bees.
60
            ('this/file1', b'a\nb\n'),
61
            ('this/file2', b'a\nb\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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([
6855.4.1 by Jelmer Vernooij
Yet more bees.
67
            ('other/file1', b'a\nb\nc\n'),
68
            ('other/file2', b'a\nb\nc\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
69
        ])
70
        other_tree.commit('modified both')
71
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
72
            ('this/file1', b'd\na\nb\n'),
73
            ('this/file2', b'd\na\nb\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
74
        ])
75
        this_tree.commit('modified both')
76
        self.do_merge(this_tree, other_tree, interesting_files=['file1'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
77
        self.assertFileEqual(b'd\na\nb\nc\n', 'this/file1')
78
        self.assertFileEqual(b'd\na\nb\n', 'this/file2')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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([
6855.4.1 by Jelmer Vernooij
Yet more bees.
85
            ('this/file1', b'line 1\nline 2\nline 3\nline 4\n'),
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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([
6855.4.1 by Jelmer Vernooij
Yet more bees.
91
            ('other/file1', b'line 1\nline 2 to 2.1\nline 3\nline 4\n'),
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
92
        ])
93
        other_tree.commit('Changed 2 to 2.1')
94
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
95
            ('this/file1', b'line 1\nline 3\nline 2\nline 4\n'),
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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,
7067.13.9 by Jelmer Vernooij
Fix bytes test.
103
                'line 1\n'
104
                '<<<<<<< TREE\n'
105
                'line 3\n'
106
                'line 2\n'
107
                '=======\n'
108
                'line 2 to 2.1\n'
109
                'line 3\n'
110
                '>>>>>>> MERGE-SOURCE\n'
111
                'line 4\n', 'this/file1')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
112
        else:
7067.13.9 by Jelmer Vernooij
Fix bytes test.
113
            self.assertFileEqual(
114
                'line 1\n'
115
                '<<<<<<< TREE\n'
116
                'line 3\n'
117
                'line 2\n'
118
                '=======\n'
119
                'line 2 to 2.1\n'
120
                'line 3\n'
121
                '>>>>>>> MERGE-SOURCE\n'
122
                'line 4\n', 'this/file1')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
123
124
    def test_modify_conflicts_with_delete(self):
125
        # If one side deletes a line, and the other modifies that line, then
126
        # the modification should be considered a conflict
127
        builder = self.make_branch_builder('test')
128
        builder.start_series()
6816.2.1 by Jelmer Vernooij
Migrate some build_snapshot code over to having revision_id as keyword argument.
129
        builder.build_snapshot(None,
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
130
            [('add', ('', None, 'directory', None)),
6855.4.1 by Jelmer Vernooij
Yet more bees.
131
             ('add', ('foo', b'foo-id', 'file', b'a\nb\nc\nd\ne\n')),
132
            ], revision_id=b'BASE-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
133
        # Delete 'b\n'
6855.4.1 by Jelmer Vernooij
Yet more bees.
134
        builder.build_snapshot([b'BASE-id'],
6883.22.11 by Jelmer Vernooij
merge trunk
135
            [('modify', ('foo', b'a\nc\nd\ne\n'))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
136
            revision_id=b'OTHER-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
137
        # Modify 'b\n', add 'X\n'
6855.4.1 by Jelmer Vernooij
Yet more bees.
138
        builder.build_snapshot([b'BASE-id'],
6883.22.11 by Jelmer Vernooij
merge trunk
139
            [('modify', ('foo', b'a\nb2\nc\nd\nX\ne\n'))],
6855.4.1 by Jelmer Vernooij
Yet more bees.
140
            revision_id=b'THIS-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
141
        builder.finish_series()
142
        branch = builder.get_branch()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
143
        this_tree = branch.controldir.create_workingtree()
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
144
        this_tree.lock_write()
145
        self.addCleanup(this_tree.unlock)
6855.4.1 by Jelmer Vernooij
Yet more bees.
146
        other_tree = this_tree.controldir.sprout('other', b'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,
7067.13.1 by Jelmer Vernooij
Some more fixes for Python 3.
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')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
160
        else:
161
            self.assertFileEqual(
6855.4.1 by Jelmer Vernooij
Yet more bees.
162
                b'a\n'
163
                b'<<<<<<< TREE\n'
164
                b'b2\n'
165
                b'=======\n'
166
                b'>>>>>>> MERGE-SOURCE\n'
167
                b'c\n'
168
                b'd\n'
169
                b'X\n'
170
                b'e\n', 'test/foo')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
242
                if merge_params.file_id == b'1':
6973.12.3 by Jelmer Vernooij
Fixes.
243
                    return 'success', [b'text-merged-by-hook']
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
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',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
255
                if merge_params.file_id == b'1':
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
256
                    return ('conflicted',
6973.12.3 by Jelmer Vernooij
Fixes.
257
                        [b'text-with-conflict-markers-from-hook'])
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
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',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
269
                if merge_params.file_id == b'1':
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
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):
6855.3.1 by Jelmer Vernooij
Several more fixes.
303
        builder.add_file(file_id, builder.tree_root, "name1", b"text1", True)
6973.12.3 by Jelmer Vernooij
Fixes.
304
        builder.change_contents(file_id, other=b"text4", this=b"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()
6973.12.3 by Jelmer Vernooij
Fixes.
310
        builder.add_file(b"1", builder.tree_root, "name1", b"text1", True)
311
        builder.change_contents(b"1", other=b"text4", this=b"text3")
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
312
        conflicts = builder.merge(self.merge_type)
313
        self.assertEqual(conflicts, [])
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
314
        with builder.this.get_file('name1') as f:
315
            self.assertEqual(f.read(), b'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()
6973.12.3 by Jelmer Vernooij
Fixes.
321
        builder.add_file(b"1", builder.tree_root, "name1", b"text1", True)
322
        builder.change_contents(b"1", this=b"text2")
323
        builder.remove_file(b"1", other=True)
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
324
        conflicts = builder.merge(self.merge_type)
325
        self.assertEqual(conflicts, [])
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
326
        with builder.this.get_file('name1') as f:
327
            self.assertEqual(f.read(), b'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()
6973.12.3 by Jelmer Vernooij
Fixes.
333
        self.create_file_needing_contents_merge(builder, b"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, [])
6973.12.3 by Jelmer Vernooij
Fixes.
336
        self.assertRaises(errors.NoSuchId, builder.this.id2path, b'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()
6973.12.3 by Jelmer Vernooij
Fixes.
343
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.6 by Andrew Bennetts
Add more tests.
344
        conflicts = builder.merge(self.merge_type)
6973.12.3 by Jelmer Vernooij
Fixes.
345
        self.assertEqual(conflicts, [TextConflict('name1', file_id=b'1')])
4869.3.6 by Andrew Bennetts
Add more tests.
346
        # The hook still gets to set the file contents in this case, so that it
347
        # can insert custom conflict markers.
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
348
        with builder.this.get_file('name1') as f:
349
            self.assertEqual(f.read(), b'text-with-conflict-markers-from-hook')
4869.3.6 by Andrew Bennetts
Add more tests.
350
351
    def test_can_access_this_other_and_base_versions(self):
352
        """The hook function can call params.merger.get_lines to access the
353
        THIS/OTHER/BASE versions of the file.
354
        """
355
        self.install_hook_log_lines()
356
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
357
        builder.add_file(b"1", builder.tree_root, "name1", b"text1", True)
358
        builder.change_contents(b"1", this=b"text2", other=b"text3")
4869.3.6 by Andrew Bennetts
Add more tests.
359
        conflicts = builder.merge(self.merge_type)
360
        self.assertEqual(
6973.12.3 by Jelmer Vernooij
Fixes.
361
            [('log_lines', [b'text2'], [b'text3'], [b'text1'])], self.hook_log)
4869.3.10 by Andrew Bennetts
Add more tests.
362
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
363
    def test_chain_when_not_active(self):
364
        """When a hook function returns None, merging still works."""
365
        self.install_hook_inactive()
366
        self.install_hook_success()
367
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
368
        self.create_file_needing_contents_merge(builder, b"1")
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
369
        conflicts = builder.merge(self.merge_type)
370
        self.assertEqual(conflicts, [])
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
371
        with builder.this.get_file('name1') as f:
372
            self.assertEqual(f.read(), b'text-merged-by-hook')
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
373
        self.assertEqual([('inactive',), ('success',)], self.hook_log)
374
4869.3.10 by Andrew Bennetts
Add more tests.
375
    def test_chain_when_not_applicable(self):
376
        """When a hook function returns not_applicable, the next function is
377
        tried (when one exists).
378
        """
379
        self.install_hook_noop()
380
        self.install_hook_success()
381
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
382
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.10 by Andrew Bennetts
Add more tests.
383
        conflicts = builder.merge(self.merge_type)
384
        self.assertEqual(conflicts, [])
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
385
        with builder.this.get_file('name1') as f:
386
            self.assertEqual(f.read(), b'text-merged-by-hook')
4869.3.10 by Andrew Bennetts
Add more tests.
387
        self.assertEqual([('no-op',), ('success',)], self.hook_log)
388
389
    def test_chain_stops_after_success(self):
390
        """When a hook function returns success, no later functions are tried.
391
        """
392
        self.install_hook_success()
393
        self.install_hook_noop()
394
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
395
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.10 by Andrew Bennetts
Add more tests.
396
        conflicts = builder.merge(self.merge_type)
397
        self.assertEqual([('success',)], self.hook_log)
398
399
    def test_chain_stops_after_conflict(self):
400
        """When a hook function returns conflict, no later functions are tried.
401
        """
402
        self.install_hook_conflict()
403
        self.install_hook_noop()
404
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
405
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.10 by Andrew Bennetts
Add more tests.
406
        conflicts = builder.merge(self.merge_type)
407
        self.assertEqual([('conflict',)], self.hook_log)
408
409
    def test_chain_stops_after_delete(self):
410
        """When a hook function returns delete, no later functions are tried.
411
        """
412
        self.install_hook_delete()
413
        self.install_hook_noop()
414
        builder = self.make_merge_builder()
6973.12.3 by Jelmer Vernooij
Fixes.
415
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.10 by Andrew Bennetts
Add more tests.
416
        conflicts = builder.merge(self.merge_type)
417
        self.assertEqual([('delete',)], self.hook_log)
4869.3.6 by Andrew Bennetts
Add more tests.
418