/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
6625.1.5 by Martin
Drop custom load_tests implementation and use unittest signature
34
def load_tests(loader, standard_tests, pattern):
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
35
    """Multiply tests for tranport implementations."""
36
    result = loader.suiteClass()
37
    scenarios = [
4869.2.8 by Andrew Bennetts
Use _merge_type_registry for per_merger tests.
38
        (name, {'merge_type': merger})
6259.3.5 by Martin Packman
Update bt.per_merger parametrisation to new registry location
39
        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.
40
    return multiply_tests(standard_tests, scenarios, result)
41
42
43
class TestMergeImplementation(TestCaseWithTransport):
44
45
    def do_merge(self, target_tree, source_tree, **kwargs):
6719.1.2 by Jelmer Vernooij
Fix some tests.
46
        merger = _mod_merge.Merger.from_revision_ids(
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
47
            target_tree, source_tree.last_revision(),
48
            other_branch=source_tree.branch)
7143.15.2 by Jelmer Vernooij
Run autopep8.
49
        merger.merge_type = self.merge_type
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
50
        for name, value in kwargs.items():
51
            setattr(merger, name, value)
52
        merger.do_merge()
53
54
    def test_merge_specific_file(self):
55
        this_tree = self.make_branch_and_tree('this')
56
        this_tree.lock_write()
57
        self.addCleanup(this_tree.unlock)
58
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
59
            ('this/file1', b'a\nb\n'),
60
            ('this/file2', b'a\nb\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
61
        ])
62
        this_tree.add(['file1', 'file2'])
63
        this_tree.commit('Added files')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
64
        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.
65
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
66
            ('other/file1', b'a\nb\nc\n'),
67
            ('other/file2', b'a\nb\nc\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
68
        ])
69
        other_tree.commit('modified both')
70
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
71
            ('this/file1', b'd\na\nb\n'),
72
            ('this/file2', b'd\na\nb\n')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
73
        ])
74
        this_tree.commit('modified both')
75
        self.do_merge(this_tree, other_tree, interesting_files=['file1'])
6855.4.1 by Jelmer Vernooij
Yet more bees.
76
        self.assertFileEqual(b'd\na\nb\nc\n', 'this/file1')
77
        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.
78
79
    def test_merge_move_and_change(self):
80
        this_tree = self.make_branch_and_tree('this')
81
        this_tree.lock_write()
82
        self.addCleanup(this_tree.unlock)
83
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
84
            ('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.
85
        ])
86
        this_tree.add('file1',)
87
        this_tree.commit('Added file')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
88
        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.
89
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
90
            ('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.
91
        ])
92
        other_tree.commit('Changed 2 to 2.1')
93
        self.build_tree_contents([
6855.4.1 by Jelmer Vernooij
Yet more bees.
94
            ('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.
95
        ])
96
        this_tree.commit('Swapped 2 & 3')
97
        self.do_merge(this_tree, other_tree)
98
        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.
99
            self.expectFailure(
100
                "lca merge doesn't conflict for move and change",
101
                self.assertFileEqual,
7067.13.9 by Jelmer Vernooij
Fix bytes test.
102
                'line 1\n'
103
                '<<<<<<< TREE\n'
104
                'line 3\n'
105
                'line 2\n'
106
                '=======\n'
107
                'line 2 to 2.1\n'
108
                'line 3\n'
109
                '>>>>>>> MERGE-SOURCE\n'
110
                'line 4\n', 'this/file1')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
111
        else:
7067.13.9 by Jelmer Vernooij
Fix bytes test.
112
            self.assertFileEqual(
113
                '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')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
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,
7143.15.2 by Jelmer Vernooij
Run autopep8.
129
                               [('add', ('', None, 'directory', None)),
130
                                ('add', ('foo', b'foo-id', 'file', b'a\nb\nc\nd\ne\n')),
131
                                ], revision_id=b'BASE-id')
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
132
        # Delete 'b\n'
6855.4.1 by Jelmer Vernooij
Yet more bees.
133
        builder.build_snapshot([b'BASE-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
134
                               [('modify', ('foo', b'a\nc\nd\ne\n'))],
135
                               revision_id=b'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'
6855.4.1 by Jelmer Vernooij
Yet more bees.
137
        builder.build_snapshot([b'BASE-id'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
138
                               [('modify', ('foo', b'a\nb2\nc\nd\nX\ne\n'))],
139
                               revision_id=b'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)
7143.15.2 by Jelmer Vernooij
Run autopep8.
145
        other_tree = this_tree.controldir.sprout(
146
            '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",
7143.15.2 by Jelmer Vernooij
Run autopep8.
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')
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')
7143.15.2 by Jelmer Vernooij
Run autopep8.
182
        (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
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')
7143.15.2 by Jelmer Vernooij
Run autopep8.
188
        (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
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')
7143.15.2 by Jelmer Vernooij
Run autopep8.
196
        (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
6015.51.2 by Martin Pool
Get the test names right
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')
7143.15.2 by Jelmer Vernooij
Run autopep8.
203
        (limbodir, deletiondir) = self.get_limbodir_deletiondir(wt)
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
204
        os.mkdir(deletiondir)
205
        os.mkdir(os.path.join(deletiondir, 'something'))
7143.15.2 by Jelmer Vernooij
Run autopep8.
206
        self.assertRaises(errors.ExistingPendingDeletion,
207
                          self.do_merge, wt, wt)
6015.51.1 by Martin Pool
Tolerate empty limbo and pending-deletion directories
208
        self.assertRaises(errors.LockError, wt.unlock)
209
4869.2.5 by Andrew Bennetts
Move per-merger tests into a per_merger test module.
210
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
211
class TestHookMergeFileContent(TestCaseWithTransport):
212
    """Tests that the 'merge_file_content' hook is invoked."""
213
4869.3.10 by Andrew Bennetts
Add more tests.
214
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
215
        super(TestHookMergeFileContent, self).setUp()
4869.3.10 by Andrew Bennetts
Add more tests.
216
        self.hook_log = []
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
217
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
218
    def install_hook_inactive(self):
219
        def inactive_factory(merger):
220
            # This hook is never active
221
            self.hook_log.append(('inactive',))
222
            return None
223
        _mod_merge.Merger.hooks.install_named_hook(
224
            'merge_file_content', inactive_factory, 'test hook (inactive)')
225
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
226
    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.
227
        test = self
7143.15.2 by Jelmer Vernooij
Run autopep8.
228
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
229
        class HookNA(_mod_merge.AbstractPerFileMerger):
230
            def merge_contents(self, merge_params):
231
                # This hook unconditionally does nothing.
232
                test.hook_log.append(('no-op',))
233
                return 'not_applicable', None
7143.15.2 by Jelmer Vernooij
Run autopep8.
234
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
235
        def hook_na_factory(merger):
236
            return HookNA(merger)
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
237
        _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.
238
            '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.
239
240
    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.
241
        test = self
7143.15.2 by Jelmer Vernooij
Run autopep8.
242
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
243
        class HookSuccess(_mod_merge.AbstractPerFileMerger):
244
            def merge_contents(self, merge_params):
245
                test.hook_log.append(('success',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
246
                if merge_params.file_id == b'1':
6973.12.3 by Jelmer Vernooij
Fixes.
247
                    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.
248
                return 'not_applicable', None
7143.15.2 by Jelmer Vernooij
Run autopep8.
249
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
250
        def hook_success_factory(merger):
251
            return HookSuccess(merger)
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
252
        _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.
253
            'merge_file_content', hook_success_factory, 'test hook (success)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
254
4869.3.6 by Andrew Bennetts
Add more tests.
255
    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.
256
        test = self
7143.15.2 by Jelmer Vernooij
Run autopep8.
257
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
258
        class HookConflict(_mod_merge.AbstractPerFileMerger):
259
            def merge_contents(self, merge_params):
260
                test.hook_log.append(('conflict',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
261
                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.
262
                    return ('conflicted',
7143.15.2 by Jelmer Vernooij
Run autopep8.
263
                            [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.
264
                return 'not_applicable', None
7143.15.2 by Jelmer Vernooij
Run autopep8.
265
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
266
        def hook_conflict_factory(merger):
267
            return HookConflict(merger)
4869.3.6 by Andrew Bennetts
Add more tests.
268
        _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.
269
            'merge_file_content', hook_conflict_factory, 'test hook (delete)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
270
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
271
    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.
272
        test = self
7143.15.2 by Jelmer Vernooij
Run autopep8.
273
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
274
        class HookDelete(_mod_merge.AbstractPerFileMerger):
275
            def merge_contents(self, merge_params):
276
                test.hook_log.append(('delete',))
7045.4.29 by Jelmer Vernooij
Fix some merge tests.
277
                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.
278
                    return 'delete', None
279
                return 'not_applicable', None
7143.15.2 by Jelmer Vernooij
Run autopep8.
280
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
281
        def hook_delete_factory(merger):
282
            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.
283
        _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.
284
            'merge_file_content', hook_delete_factory, 'test hook (delete)')
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
285
4869.3.6 by Andrew Bennetts
Add more tests.
286
    def install_hook_log_lines(self):
287
        """Install a hook that saves the get_lines for the this, base and other
288
        versions of the file.
289
        """
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
290
        test = self
7143.15.2 by Jelmer Vernooij
Run autopep8.
291
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
292
        class HookLogLines(_mod_merge.AbstractPerFileMerger):
293
            def merge_contents(self, merge_params):
294
                test.hook_log.append((
295
                    'log_lines',
296
                    merge_params.this_lines,
297
                    merge_params.other_lines,
298
                    merge_params.base_lines,
299
                    ))
300
                return 'not_applicable', None
7143.15.2 by Jelmer Vernooij
Run autopep8.
301
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
302
        def hook_log_lines_factory(merger):
303
            return HookLogLines(merger)
4869.3.6 by Andrew Bennetts
Add more tests.
304
        _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.
305
            'merge_file_content', hook_log_lines_factory,
306
            'test hook (log_lines)')
4869.3.6 by Andrew Bennetts
Add more tests.
307
4869.3.3 by Andrew Bennetts
Move test_hook_merge_file_content to per_merger.
308
    def make_merge_builder(self):
309
        builder = MergeBuilder(self.test_base_dir)
310
        self.addCleanup(builder.cleanup)
311
        return builder
312
4869.3.10 by Andrew Bennetts
Add more tests.
313
    def create_file_needing_contents_merge(self, builder, file_id):
6855.3.1 by Jelmer Vernooij
Several more fixes.
314
        builder.add_file(file_id, builder.tree_root, "name1", 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()
6973.12.3 by Jelmer Vernooij
Fixes.
344
        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.
345
        conflicts = builder.merge(self.merge_type)
346
        self.assertEqual(conflicts, [])
6973.12.3 by Jelmer Vernooij
Fixes.
347
        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.
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()
6973.12.3 by Jelmer Vernooij
Fixes.
354
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.6 by Andrew Bennetts
Add more tests.
355
        conflicts = builder.merge(self.merge_type)
6973.12.3 by Jelmer Vernooij
Fixes.
356
        self.assertEqual(conflicts, [TextConflict('name1', file_id=b'1')])
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()
6973.12.3 by Jelmer Vernooij
Fixes.
379
        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.
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()
6973.12.3 by Jelmer Vernooij
Fixes.
393
        self.create_file_needing_contents_merge(builder, b"1")
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()
6973.12.3 by Jelmer Vernooij
Fixes.
406
        self.create_file_needing_contents_merge(builder, b"1")
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()
6973.12.3 by Jelmer Vernooij
Fixes.
416
        self.create_file_needing_contents_merge(builder, b"1")
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()
6973.12.3 by Jelmer Vernooij
Fixes.
426
        self.create_file_needing_contents_merge(builder, b"1")
4869.3.10 by Andrew Bennetts
Add more tests.
427
        conflicts = builder.merge(self.merge_type)
428
        self.assertEqual([('delete',)], self.hook_log)