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