~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2005-2011 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.14.8 by Aaron Bentley
Added test_commit.py
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.14.8 by Aaron Bentley
Added test_commit.py
16
17
18
import os
19
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
20
from bzrlib import (
21
    bzrdir,
22
    conflicts,
23
    errors,
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
24
    option,
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
25
    osutils,
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
26
    tests,
27
    )
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
28
from bzrlib.tests import (
29
    script,
30
    scenarios,
31
    )
32
33
34
load_tests = scenarios.load_tests_apply_scenarios
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
35
36
1185.14.8 by Aaron Bentley
Added test_commit.py
37
# TODO: Test commit with some added, and added-but-missing files
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
38
# RBC 20060124 is that not tested in test_commit.py ?
1185.14.8 by Aaron Bentley
Added test_commit.py
39
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
40
# The order of 'path' here is important - do not let it
41
# be a sorted list.
2309.4.13 by John Arbash Meinel
Conflicts go through Stanza so the need to be aware of utf8 versus unicode file ids.
42
# u'\xe5' == a with circle
43
# '\xc3\xae' == u'\xee' == i with hat
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
44
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
45
example_conflicts = conflicts.ConflictList(
46
    [conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
47
     conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
48
     conflicts.TextConflict(u'p\xe5tha'),
49
     conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
50
     conflicts.DuplicateID('Unversioned existing file',
51
                           u'p\xe5thc', u'p\xe5thc2',
52
                           '\xc3\xaedc', '\xc3\xaedc'),
53
    conflicts.DuplicateEntry('Moved existing file to',
54
                             u'p\xe5thdd.moved', u'p\xe5thd',
55
                             '\xc3\xaedd', None),
56
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
57
                         None, '\xc3\xaed2e'),
58
    conflicts.UnversionedParent('Versioned directory',
59
                                u'p\xe5thf', '\xc3\xaedf'),
60
    conflicts.NonDirectoryParent('Created directory',
61
                                 u'p\xe5thg', '\xc3\xaedg'),
1534.10.22 by Aaron Bentley
Got ConflictList implemented
62
])
1534.10.4 by Aaron Bentley
Implemented conflict serialization
63
64
4597.2.2 by Vincent Ladeuil
Cleanup conflict tests.
65
class TestConflicts(tests.TestCaseWithTransport):
1185.14.8 by Aaron Bentley
Added test_commit.py
66
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
67
    def test_resolve_conflict_dir(self):
68
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
69
        self.build_tree_contents([('hello', 'hello world4'),
70
                                  ('hello.THIS', 'hello world2'),
71
                                  ('hello.BASE', 'hello world1'),
72
                                  ])
73
        os.mkdir('hello.OTHER')
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
74
        tree.add('hello', 'q')
4597.2.3 by Vincent Ladeuil
More cleanup.
75
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
1558.12.9 by Aaron Bentley
Handle resolving conflicts with directories properly
76
        l.remove_files(tree)
77
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
78
    def test_select_conflicts(self):
79
        tree = self.make_branch_and_tree('.')
4597.2.3 by Vincent Ladeuil
More cleanup.
80
        clist = conflicts.ConflictList
81
82
        def check_select(not_selected, selected, paths, **kwargs):
83
            self.assertEqual(
84
                (not_selected, selected),
85
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
86
87
        foo = conflicts.ContentsConflict('foo')
88
        bar = conflicts.ContentsConflict('bar')
89
        tree_conflicts = clist([foo, bar])
90
91
        check_select(clist([bar]), clist([foo]), ['foo'])
92
        check_select(clist(), tree_conflicts,
93
                     [''], ignore_misses=True, recurse=True)
94
95
        foobaz  = conflicts.ContentsConflict('foo/baz')
96
        tree_conflicts = clist([foobaz, bar])
97
98
        check_select(clist([bar]), clist([foobaz]),
99
                     ['foo'], ignore_misses=True, recurse=True)
100
101
        qux = conflicts.PathConflict('qux', 'foo/baz')
102
        tree_conflicts = clist([qux])
103
104
        check_select(clist(), tree_conflicts,
105
                     ['foo'], ignore_misses=True, recurse=True)
106
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
107
3017.2.1 by Aaron Bentley
Revert now resolves conflicts recursively (#102739)
108
    def test_resolve_conflicts_recursive(self):
109
        tree = self.make_branch_and_tree('.')
110
        self.build_tree(['dir/', 'dir/hello'])
111
        tree.add(['dir', 'dir/hello'])
4597.2.3 by Vincent Ladeuil
More cleanup.
112
113
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
114
        tree.set_conflicts(dirhello)
115
116
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
117
        self.assertEqual(dirhello, tree.conflicts())
118
119
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
120
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
4773.1.1 by Vincent Ladeuil
Cleanup imports in test_conflicts
121
122
4597.3.43 by Vincent Ladeuil
Cleanups, ready to record.
123
class TestConflictStanzas(tests.TestCase):
124
125
    def test_stanza_roundtrip(self):
126
        # write and read our example stanza.
127
        stanza_iter = example_conflicts.to_stanzas()
128
        processed = conflicts.ConflictList.from_stanzas(stanza_iter)
129
        for o, p in zip(processed, example_conflicts):
130
            self.assertEqual(o, p)
131
132
            self.assertIsInstance(o.path, unicode)
133
134
            if o.file_id is not None:
135
                self.assertIsInstance(o.file_id, str)
136
137
            conflict_path = getattr(o, 'conflict_path', None)
138
            if conflict_path is not None:
139
                self.assertIsInstance(conflict_path, unicode)
140
141
            conflict_file_id = getattr(o, 'conflict_file_id', None)
142
            if conflict_file_id is not None:
143
                self.assertIsInstance(conflict_file_id, str)
144
145
    def test_stanzification(self):
146
        for stanza in example_conflicts.to_stanzas():
147
            if 'file_id' in stanza:
148
                # In Stanza form, the file_id has to be unicode.
149
                self.assertStartsWith(stanza['file_id'], u'\xeed')
150
            self.assertStartsWith(stanza['path'], u'p\xe5th')
151
            if 'conflict_path' in stanza:
152
                self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
153
            if 'conflict_file_id' in stanza:
154
                self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
155
156
4597.3.74 by Vincent Ladeuil
Add a FIXME about rewriting shell-like tests into real whitebox tests.
157
# FIXME: The shell-like tests should be converted to real whitebox tests... or
158
# moved to a blackbox module -- vila 20100205
159
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
160
# FIXME: test missing for multiple conflicts
161
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
162
# FIXME: Tests missing for DuplicateID conflict type
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
163
class TestResolveConflicts(script.TestCaseWithTransportAndScript):
164
165
    preamble = None # The setup script set by daughter classes
166
167
    def setUp(self):
168
        super(TestResolveConflicts, self).setUp()
169
        self.run_script(self.preamble)
170
171
4597.10.11 by Vincent Ladeuil
Turn mirror_scenarios into a simple function.
172
def mirror_scenarios(base_scenarios):
173
    """Return a list of mirrored scenarios.
174
175
    Each scenario in base_scenarios is duplicated switching the roles of 'this'
176
    and 'other'
177
    """
178
    scenarios = []
4597.10.14 by Vincent Ladeuil
Some more cleanup and typos.
179
    for common, (lname, ldict), (rname, rdict) in base_scenarios:
4597.10.11 by Vincent Ladeuil
Turn mirror_scenarios into a simple function.
180
        a = tests.multiply_scenarios([(lname, dict(_this=ldict))],
181
                                     [(rname, dict(_other=rdict))])
182
        b = tests.multiply_scenarios([(rname, dict(_this=rdict))],
183
                                     [(lname, dict(_other=ldict))])
184
        # Inject the common parameters in all scenarios
185
        for name, d in a + b:
186
            d.update(common)
187
        scenarios.extend(a + b)
188
    return scenarios
189
190
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
191
# FIXME: Get rid of parametrized (in the class name) once we delete
192
# TestResolveConflicts -- vila 20100308
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
193
class TestParametrizedResolveConflicts(tests.TestCaseWithTransport):
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
194
    """This class provides a base to test single conflict resolution.
195
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
196
    Since all conflict objects are created with specific semantics for their
197
    attributes, each class should implement the necessary functions and
198
    attributes described below.
199
200
    Each class should define the scenarios that create the expected (single)
201
    conflict.
202
203
    Each scenario describes:
204
    * how to create 'base' tree (and revision)
205
    * how to create 'left' tree (and revision, parent rev 'base')
206
    * how to create 'right' tree (and revision, parent rev 'base')
207
    * how to check that changes in 'base'->'left' have been taken
208
    * how to check that changes in 'base'->'right' have been taken
209
210
    From each base scenario, we generate two concrete scenarios where:
211
    * this=left, other=right
212
    * this=right, other=left
213
214
    Then the test case verifies each concrete scenario by:
215
    * creating a branch containing the 'base', 'this' and 'other' revisions
216
    * creating a working tree for the 'this' revision
217
    * performing the merge of 'other' into 'this'
218
    * verifying the expected conflict was generated
219
    * resolving with --take-this or --take-other, and running the corresponding
220
      checks (for either 'base'->'this', or 'base'->'other')
221
222
    :cvar _conflict_type: The expected class of the generated conflict.
223
224
    :cvar _assert_conflict: A method receiving the working tree and the
225
        conflict object and checking its attributes.
226
4597.10.9 by Vincent Ladeuil
More doc.
227
    :cvar _base_actions: The branchbuilder actions to create the 'base'
228
        revision.
229
230
    :cvar _this: The dict related to 'base' -> 'this'. It contains at least:
231
      * 'actions': The branchbuilder actions to create the 'this'
232
          revision.
4597.10.10 by Vincent Ladeuil
Fix typo.
233
      * 'check': how to check the changes after resolution with --take-this.
4597.10.9 by Vincent Ladeuil
More doc.
234
235
    :cvar _other: The dict related to 'base' -> 'other'. It contains at least:
236
      * 'actions': The branchbuilder actions to create the 'other'
237
          revision.
4597.10.10 by Vincent Ladeuil
Fix typo.
238
      * 'check': how to check the changes after resolution with --take-other.
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
239
    """
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
240
4597.7.16 by Vincent Ladeuil
Some cleanup.
241
    # Set by daughter classes
242
    _conflict_type = None
243
    _assert_conflict = None
244
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
245
    # Set by load_tests
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
246
    _base_actions = None
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
247
    _this = None
248
    _other = None
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
249
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
250
    scenarios = []
251
    """The scenario list for the conflict type defined by the class.
252
253
    Each scenario is of the form:
254
    (common, (left_name, left_dict), (right_name, right_dict))
255
256
    * common is a dict
257
258
    * left_name and right_name are the scenario names that will be combined
259
260
    * left_dict and right_dict are the attributes specific to each half of
261
      the scenario. They should include at least 'actions' and 'check' and
262
      will be available as '_this' and '_other' test instance attributes.
263
264
    Daughters classes are free to add their specific attributes as they see
265
    fit in any of the three dicts.
266
267
    This is a class method so that load_tests can find it.
268
269
    '_base_actions' in the common dict, 'actions' and 'check' in the left
270
    and right dicts use names that map to methods in the test classes. Some
271
    prefixes are added to these names to get the correspong methods (see
272
    _get_actions() and _get_check()). The motivation here is to avoid
273
    collisions in the class namespace.
274
    """
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
275
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
276
    def setUp(self):
4597.7.4 by Vincent Ladeuil
Abstract the test class some more to address more conflict
277
        super(TestParametrizedResolveConflicts, self).setUp()
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
278
        builder = self.make_branch_builder('trunk')
279
        builder.start_series()
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
280
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
281
        # Create an empty trunk
282
        builder.build_snapshot('start', None, [
283
                ('add', ('', 'root-id', 'directory', ''))])
284
        # Add a minimal base content
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
285
        base_actions = self._get_actions(self._base_actions)()
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
286
        builder.build_snapshot('base', ['start'], base_actions)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
287
        # Modify the base content in branch
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
288
        actions_other = self._get_actions(self._other['actions'])()
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
289
        builder.build_snapshot('other', ['base'], actions_other)
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
290
        # Modify the base content in trunk
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
291
        actions_this = self._get_actions(self._this['actions'])()
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
292
        builder.build_snapshot('this', ['base'], actions_this)
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
293
        # builder.get_branch() tip is now 'this'
4597.7.6 by Vincent Ladeuil
Cleanup TestParametrizedResolveConflicts some more.
294
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
295
        builder.finish_series()
296
        self.builder = builder
297
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
298
    def _get_actions(self, name):
299
        return getattr(self, 'do_%s' % name)
300
301
    def _get_check(self, name):
302
        return getattr(self, 'check_%s' % name)
303
4597.2.24 by Vincent Ladeuil
Translate one more test.
304
    def _merge_other_into_this(self):
4597.2.23 by Vincent Ladeuil
Start translating blackbox tests into whitebox ones.
305
        b = self.builder.get_branch()
306
        wt = b.bzrdir.sprout('branch').open_workingtree()
307
        wt.merge_from_branch(b, 'other')
4597.2.24 by Vincent Ladeuil
Translate one more test.
308
        return wt
309
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
310
    def assertConflict(self, wt):
311
        confs = wt.conflicts()
312
        self.assertLength(1, confs)
313
        c = confs[0]
314
        self.assertIsInstance(c, self._conflict_type)
315
        self._assert_conflict(wt, c)
316
317
    def _get_resolve_path_arg(self, wt, action):
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
318
        raise NotImplementedError(self._get_resolve_path_arg)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
319
320
    def check_resolved(self, wt, action):
321
        path = self._get_resolve_path_arg(wt, action)
322
        conflicts.resolve(wt, [path], action=action)
323
        # Check that we don't have any conflicts nor unknown left
324
        self.assertLength(0, wt.conflicts())
325
        self.assertLength(0, list(wt.unknowns()))
326
4597.2.24 by Vincent Ladeuil
Translate one more test.
327
    def test_resolve_taking_this(self):
328
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
329
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
330
        self.check_resolved(wt, 'take_this')
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
331
        check_this = self._get_check(self._this['check'])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
332
        check_this()
4597.2.24 by Vincent Ladeuil
Translate one more test.
333
334
    def test_resolve_taking_other(self):
335
        wt = self._merge_other_into_this()
4597.7.7 by Vincent Ladeuil
Reproduce bug #531967 on various aspects.
336
        self.assertConflict(wt)
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
337
        self.check_resolved(wt, 'take_other')
4597.10.7 by Vincent Ladeuil
Simplify scenarios mirroring and give a better docstring for TestParametrizedResolveConflicts.
338
        check_other = self._get_check(self._other['check'])
4597.2.26 by Vincent Ladeuil
Fix bug #529968 by renaming the kept file on content conflicts.
339
        check_other()
4597.3.28 by Vincent Ladeuil
Implement --interactive for ContentsConflict.
340
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
341
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
342
class TestResolveTextConflicts(TestParametrizedResolveConflicts):
343
344
    _conflict_type = conflicts.TextConflict
345
346
    # Set by the scenarios
347
    # path and file-id for the file involved in the conflict
348
    _path = None
349
    _file_id = None
350
351
    scenarios = mirror_scenarios(
352
        [
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
353
            # File modified on both sides
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
354
            (dict(_base_actions='create_file',
355
                  _path='file', _file_id='file-id'),
356
             ('filed_modified_A',
357
              dict(actions='modify_file_A', check='file_has_content_A')),
358
             ('file_modified_B',
359
              dict(actions='modify_file_B', check='file_has_content_B')),),
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
360
            # File modified on both sides in dir
361
            (dict(_base_actions='create_file_in_dir',
362
                  _path='dir/file', _file_id='file-id'),
363
             ('filed_modified_A_in_dir',
364
              dict(actions='modify_file_A',
365
                   check='file_in_dir_has_content_A')),
366
             ('file_modified_B',
367
              dict(actions='modify_file_B',
368
                   check='file_in_dir_has_content_B')),),
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
369
            ])
370
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
371
    def do_create_file(self, path='file'):
372
        return [('add', (path, 'file-id', 'file', 'trunk content\n'))]
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
373
374
    def do_modify_file_A(self):
375
        return [('modify', ('file-id', 'trunk content\nfeature A\n'))]
376
377
    def do_modify_file_B(self):
378
        return [('modify', ('file-id', 'trunk content\nfeature B\n'))]
379
5609.17.1 by Vincent Ladeuil
Reproduce bug #715068.
380
    def check_file_has_content_A(self, path='file'):
381
        self.assertFileEqual('trunk content\nfeature A\n',
382
                             osutils.pathjoin('branch', path))
383
384
    def check_file_has_content_B(self, path='file'):
385
        self.assertFileEqual('trunk content\nfeature B\n',
386
                             osutils.pathjoin('branch', path))
387
388
    def do_create_file_in_dir(self):
389
        return [('add', ('dir', 'dir-id', 'directory', '')),
390
            ] + self.do_create_file('dir/file')
391
392
    def check_file_in_dir_has_content_A(self):
393
        self.check_file_has_content_A('dir/file')
394
395
    def check_file_in_dir_has_content_B(self):
396
        self.check_file_has_content_B('dir/file')
4597.14.2 by Vincent Ladeuil
Implements --take-this and --take-other when resolving text conflicts
397
398
    def _get_resolve_path_arg(self, wt, action):
399
        return self._path
400
401
    def assertTextConflict(self, wt, c):
402
        self.assertEqual(self._file_id, c.file_id)
403
        self.assertEqual(self._path, c.path)
404
    _assert_conflict = assertTextConflict
405
406
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
407
class TestResolveContentsConflict(TestParametrizedResolveConflicts):
408
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
409
    _conflict_type = conflicts.ContentsConflict
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
410
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
411
    # Set by the scenarios
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
412
    # path and file-id for the file involved in the conflict
413
    _path = None
414
    _file_id = None
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
415
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
416
    scenarios = mirror_scenarios(
417
        [
4597.10.12 by Vincent Ladeuil
Some more doc.
418
            # File modified/deleted
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
419
            (dict(_base_actions='create_file',
420
                  _path='file', _file_id='file-id'),
4597.10.12 by Vincent Ladeuil
Some more doc.
421
             ('file_modified',
422
              dict(actions='modify_file', check='file_has_more_content')),
423
             ('file_deleted',
424
              dict(actions='delete_file', check='file_doesnt_exist')),),
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
425
            # File modified/deleted in dir
426
            (dict(_base_actions='create_file_in_dir',
427
                  _path='dir/file', _file_id='file-id'),
428
             ('file_modified_in_dir',
429
              dict(actions='modify_file_in_dir',
430
                   check='file_in_dir_has_more_content')),
431
             ('file_deleted_in_dir',
432
              dict(actions='delete_file',
433
                   check='file_in_dir_doesnt_exist')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
434
            ])
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
435
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
436
    def do_create_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
437
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
438
439
    def do_modify_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
440
        return [('modify', ('file-id', 'trunk content\nmore content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
441
442
    def check_file_has_more_content(self):
443
        self.assertFileEqual('trunk content\nmore content\n', 'branch/file')
444
445
    def do_delete_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
446
        return [('unversion', 'file-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
447
448
    def check_file_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
449
        self.assertPathDoesNotExist('branch/file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
450
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
451
    def do_create_file_in_dir(self):
452
        return [('add', ('dir', 'dir-id', 'directory', '')),
453
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
454
455
    def do_modify_file_in_dir(self):
456
        return [('modify', ('file-id', 'trunk content\nmore content\n'))]
457
458
    def check_file_in_dir_has_more_content(self):
459
        self.assertFileEqual('trunk content\nmore content\n', 'branch/dir/file')
460
461
    def check_file_in_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
462
        self.assertPathDoesNotExist('branch/dir/file')
5050.63.3 by Vincent Ladeuil
Correctly resolve content conflicts for files in subdirs
463
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
464
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
465
        return self._path
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
466
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
467
    def assertContentsConflict(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
468
        self.assertEqual(self._file_id, c.file_id)
469
        self.assertEqual(self._path, c.path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
470
    _assert_conflict = assertContentsConflict
471
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
472
473
class TestResolvePathConflict(TestParametrizedResolveConflicts):
474
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
475
    _conflict_type = conflicts.PathConflict
4597.7.16 by Vincent Ladeuil
Some cleanup.
476
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
477
    def do_nothing(self):
478
        return []
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
479
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
480
    # Each side dict additionally defines:
481
    # - path path involved (can be '<deleted>')
482
    # - file-id involved
483
    scenarios = mirror_scenarios(
484
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
485
            # File renamed/deleted
486
            (dict(_base_actions='create_file'),
487
             ('file_renamed',
488
              dict(actions='rename_file', check='file_renamed',
489
                   path='new-file', file_id='file-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
490
             ('file_deleted',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
491
              dict(actions='delete_file', check='file_doesnt_exist',
492
                   # PathConflicts deletion handling requires a special
493
                   # hard-coded value
494
                   path='<deleted>', file_id='file-id')),),
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
495
            # File renamed/deleted in dir
496
            (dict(_base_actions='create_file_in_dir'),
497
             ('file_renamed_in_dir',
498
              dict(actions='rename_file_in_dir', check='file_in_dir_renamed',
499
                   path='dir/new-file', file_id='file-id')),
500
             ('file_deleted',
501
              dict(actions='delete_file', check='file_in_dir_doesnt_exist',
502
                   # PathConflicts deletion handling requires a special
503
                   # hard-coded value
504
                   path='<deleted>', file_id='file-id')),),
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
505
            # File renamed/renamed differently
506
            (dict(_base_actions='create_file'),
507
             ('file_renamed',
508
              dict(actions='rename_file', check='file_renamed',
509
                   path='new-file', file_id='file-id')),
4597.8.4 by Vincent Ladeuil
Delete PathConflict bloackbox tests.
510
             ('file_renamed2',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
511
              dict(actions='rename_file2', check='file_renamed2',
512
                   path='new-file2', file_id='file-id')),),
513
            # Dir renamed/deleted
514
            (dict(_base_actions='create_dir'),
515
             ('dir_renamed',
516
              dict(actions='rename_dir', check='dir_renamed',
517
                   path='new-dir', file_id='dir-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
518
             ('dir_deleted',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
519
              dict(actions='delete_dir', check='dir_doesnt_exist',
520
                   # PathConflicts deletion handling requires a special
521
                   # hard-coded value
522
                   path='<deleted>', file_id='dir-id')),),
523
            # Dir renamed/renamed differently
524
            (dict(_base_actions='create_dir'),
525
             ('dir_renamed',
526
              dict(actions='rename_dir', check='dir_renamed',
527
                   path='new-dir', file_id='dir-id')),
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
528
             ('dir_renamed2',
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
529
              dict(actions='rename_dir2', check='dir_renamed2',
530
                   path='new-dir2', file_id='dir-id')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
531
            ])
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
532
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
533
    def do_create_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
534
        return [('add', ('file', 'file-id', 'file', 'trunk content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
535
536
    def do_create_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
537
        return [('add', ('dir', 'dir-id', 'directory', ''))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
538
539
    def do_rename_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
540
        return [('rename', ('file', 'new-file'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
541
542
    def check_file_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
543
        self.assertPathDoesNotExist('branch/file')
544
        self.assertPathExists('branch/new-file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
545
546
    def do_rename_file2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
547
        return [('rename', ('file', 'new-file2'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
548
549
    def check_file_renamed2(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
550
        self.assertPathDoesNotExist('branch/file')
551
        self.assertPathExists('branch/new-file2')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
552
553
    def do_rename_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
554
        return [('rename', ('dir', 'new-dir'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
555
556
    def check_dir_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
557
        self.assertPathDoesNotExist('branch/dir')
558
        self.assertPathExists('branch/new-dir')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
559
560
    def do_rename_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
561
        return [('rename', ('dir', 'new-dir2'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
562
563
    def check_dir_renamed2(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
564
        self.assertPathDoesNotExist('branch/dir')
565
        self.assertPathExists('branch/new-dir2')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
566
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
567
    def do_delete_file(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
568
        return [('unversion', 'file-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
569
570
    def check_file_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
571
        self.assertPathDoesNotExist('branch/file')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
572
573
    def do_delete_dir(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
574
        return [('unversion', 'dir-id')]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
575
576
    def check_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
577
        self.assertPathDoesNotExist('branch/dir')
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
578
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
579
    def do_create_file_in_dir(self):
580
        return [('add', ('dir', 'dir-id', 'directory', '')),
581
                ('add', ('dir/file', 'file-id', 'file', 'trunk content\n'))]
582
583
    def do_rename_file_in_dir(self):
584
        return [('rename', ('dir/file', 'dir/new-file'))]
585
586
    def check_file_in_dir_renamed(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
587
        self.assertPathDoesNotExist('branch/dir/file')
588
        self.assertPathExists('branch/dir/new-file')
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
589
590
    def check_file_in_dir_doesnt_exist(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
591
        self.assertPathDoesNotExist('branch/dir/file')
5050.63.6 by Vincent Ladeuil
Same fix for path conflicts.
592
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
593
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
594
        tpath = self._this['path']
595
        opath = self._other['path']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
596
        if tpath == '<deleted>':
597
            path = opath
598
        else:
599
            path = tpath
600
        return path
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
601
602
    def assertPathConflict(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
603
        tpath = self._this['path']
604
        tfile_id = self._this['file_id']
605
        opath = self._other['path']
606
        ofile_id = self._other['file_id']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
607
        self.assertEqual(tfile_id, ofile_id) # Sanity check
608
        self.assertEqual(tfile_id, c.file_id)
609
        self.assertEqual(tpath, c.path)
610
        self.assertEqual(opath, c.conflict_path)
4597.7.16 by Vincent Ladeuil
Some cleanup.
611
    _assert_conflict = assertPathConflict
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
612
613
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
614
class TestResolvePathConflictBefore531967(TestResolvePathConflict):
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
615
    """Same as TestResolvePathConflict but a specific conflict object.
616
    """
617
4597.7.16 by Vincent Ladeuil
Some cleanup.
618
    def assertPathConflict(self, c):
4597.7.17 by Vincent Ladeuil
Add a scenario and activate the compatibility tests.
619
        # We create a conflict object as it was created before the fix and
620
        # inject it into the working tree, the test will exercise the
621
        # compatibility code.
622
        old_c = conflicts.PathConflict('<deleted>', self._item_path,
623
                                       file_id=None)
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
624
        wt.set_conflicts(conflicts.ConflictList([old_c]))
4597.7.10 by Vincent Ladeuil
Define scenarios by test classes.
625
626
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
627
class TestResolveDuplicateEntry(TestParametrizedResolveConflicts):
628
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
629
    _conflict_type = conflicts.DuplicateEntry
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
630
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
631
    scenarios = mirror_scenarios(
632
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
633
            # File created with different file-ids
634
            (dict(_base_actions='nothing'),
635
             ('filea_created',
636
              dict(actions='create_file_a', check='file_content_a',
637
                   path='file', file_id='file-a-id')),
638
             ('fileb_created',
639
              dict(actions='create_file_b', check='file_content_b',
640
                   path='file', file_id='file-b-id')),),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
641
            ])
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
642
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
643
    def do_nothing(self):
644
        return []
645
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
646
    def do_create_file_a(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
647
        return [('add', ('file', 'file-a-id', 'file', 'file a content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
648
649
    def check_file_content_a(self):
650
        self.assertFileEqual('file a content\n', 'branch/file')
651
652
    def do_create_file_b(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
653
        return [('add', ('file', 'file-b-id', 'file', 'file b content\n'))]
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
654
655
    def check_file_content_b(self):
656
        self.assertFileEqual('file b content\n', 'branch/file')
657
658
    def _get_resolve_path_arg(self, wt, action):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
659
        return self._this['path']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
660
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
661
    def assertDuplicateEntry(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
662
        tpath = self._this['path']
663
        tfile_id = self._this['file_id']
664
        opath = self._other['path']
665
        ofile_id = self._other['file_id']
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
666
        self.assertEqual(tpath, opath) # Sanity check
667
        self.assertEqual(tfile_id, c.file_id)
668
        self.assertEqual(tpath + '.moved', c.path)
669
        self.assertEqual(tpath, c.conflict_path)
4597.8.5 by Vincent Ladeuil
Replace DuplicateEntry blackbox tests by whitebox ones.
670
    _assert_conflict = assertDuplicateEntry
4597.3.19 by Vincent Ladeuil
Some failing tests.
671
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
672
673
class TestResolveUnversionedParent(TestResolveConflicts):
674
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
675
    # FIXME: Add the reverse tests: dir deleted in trunk, file added in branch
676
4597.3.30 by Vincent Ladeuil
Light changes learned while starting to understand multiple conflicts on
677
    # FIXME: While this *creates* UnversionedParent conflicts, this really only
678
    # tests MissingParent resolution :-/
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
679
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
680
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
681
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
682
$ cd trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
683
$ mkdir dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
684
$ bzr add -q dir
685
$ bzr commit -m 'Create trunk' -q
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
686
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
687
$ bzr add -q dir/file
688
$ bzr commit -q -m 'Add dir/file in trunk'
689
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
690
$ cd ../branch
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
691
$ bzr rm dir -q
692
$ bzr commit -q -m 'Remove dir in branch'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
693
$ bzr merge ../trunk
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
694
2>+N  dir/
695
2>+N  dir/file
696
2>Conflict adding files to dir.  Created directory.
697
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
698
2>2 conflicts encountered.
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
699
"""
700
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
701
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
702
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
703
$ bzr rm -q dir  --force
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
704
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
705
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
706
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
707
""")
708
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
709
    def test_take_other(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
710
        self.run_script("""
4597.3.29 by Vincent Ladeuil
Fix bogus tests.
711
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
712
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
713
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
714
""")
715
716
717
class TestResolveMissingParent(TestResolveConflicts):
718
719
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
720
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
721
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
722
$ cd trunk
723
$ mkdir dir
724
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
725
$ bzr add -q
726
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
727
$ echo 'trunk content' >dir/file2
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
728
$ bzr add -q dir/file2
729
$ bzr commit -q -m 'Add dir/file2 in branch'
730
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
731
$ cd ../branch
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
732
$ bzr rm -q dir/file --force
733
$ bzr rm -q dir
734
$ bzr commit -q -m 'Remove dir/file'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
735
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
736
2>+N  dir/
737
2>+N  dir/file2
738
2>Conflict adding files to dir.  Created directory.
739
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
740
2>2 conflicts encountered.
741
"""
742
743
    def test_keep_them_all(self):
744
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
745
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
746
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
747
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
748
""")
749
750
    def test_adopt_child(self):
751
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
752
$ bzr mv -q dir/file2 file2
753
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
754
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
755
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
756
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
757
""")
758
759
    def test_kill_them_all(self):
760
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
761
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
762
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
763
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
764
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
765
""")
766
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
767
    def test_resolve_taking_this(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
768
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
769
$ bzr resolve --take-this dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
770
2>...
771
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
772
""")
773
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
774
    def test_resolve_taking_other(self):
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
775
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
776
$ bzr resolve --take-other dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
777
2>...
778
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.31 by Vincent Ladeuil
Implement --interactive for MissingParent.
779
""")
780
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
781
782
class TestResolveDeletingParent(TestResolveConflicts):
783
784
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
785
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
786
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
787
$ cd trunk
788
$ mkdir dir
789
$ echo 'trunk content' >dir/file
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
790
$ bzr add -q
791
$ bzr commit -m 'Create trunk' -q
792
$ bzr rm -q dir/file --force
793
$ bzr rm -q dir --force
794
$ bzr commit -q -m 'Remove dir/file'
795
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
796
$ cd ../branch
797
$ echo 'branch content' >dir/file2
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
798
$ bzr add -q dir/file2
799
$ bzr commit -q -m 'Add dir/file2 in branch'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
800
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
801
2>-D  dir/file
802
2>Conflict: can't delete dir because it is not empty.  Not deleting.
803
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
804
2>2 conflicts encountered.
805
"""
806
807
    def test_keep_them_all(self):
808
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
809
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
810
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
811
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
812
""")
813
814
    def test_adopt_child(self):
815
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
816
$ bzr mv -q dir/file2 file2
817
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
818
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
819
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
820
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
821
""")
822
823
    def test_kill_them_all(self):
824
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
825
$ bzr rm -q dir --force
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
826
$ bzr resolve dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
827
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
828
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
829
""")
830
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
831
    def test_resolve_taking_this(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
832
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
833
$ bzr resolve --take-this dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
834
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
835
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
836
""")
837
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
838
    def test_resolve_taking_other(self):
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
839
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
840
$ bzr resolve --take-other dir
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
841
2>deleted dir/file2
842
2>deleted dir
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
843
2>2 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
844
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.32 by Vincent Ladeuil
Implement --interactive for DeletingParent noting the inconsistency.
845
""")
846
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
847
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
848
class TestResolveParentLoop(TestParametrizedResolveConflicts):
849
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
850
    _conflict_type = conflicts.ParentLoop
4597.10.1 by Vincent Ladeuil
Refactor to better handle various conflict types.
851
852
    _this_args = None
853
    _other_args = None
854
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
855
    # Each side dict additionally defines:
856
    # - dir_id: the directory being moved
857
    # - target_id: The target directory
858
    # - xfail: whether the test is expected to fail if the action is
859
    #   involved as 'other'
860
    scenarios = mirror_scenarios(
861
        [
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
862
            # Dirs moved into each other
863
            (dict(_base_actions='create_dir1_dir2'),
864
             ('dir1_into_dir2',
865
              dict(actions='move_dir1_into_dir2', check='dir1_moved',
866
                   dir_id='dir1-id', target_id='dir2-id', xfail=False)),
867
             ('dir2_into_dir1',
868
              dict(actions='move_dir2_into_dir1', check='dir2_moved',
869
                   dir_id='dir2-id', target_id='dir1-id', xfail=False))),
870
            # Subdirs moved into each other
871
            (dict(_base_actions='create_dir1_4'),
872
             ('dir1_into_dir4',
873
              dict(actions='move_dir1_into_dir4', check='dir1_2_moved',
874
                   dir_id='dir1-id', target_id='dir4-id', xfail=True)),
875
             ('dir3_into_dir2',
876
              dict(actions='move_dir3_into_dir2', check='dir3_4_moved',
877
                   dir_id='dir3-id', target_id='dir2-id', xfail=True))),
4597.13.3 by Vincent Ladeuil
Switch to load_tests_apply_scenarios.
878
            ])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
879
880
    def do_create_dir1_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
881
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
882
                ('add', ('dir2', 'dir2-id', 'directory', '')),]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
883
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
884
    def do_move_dir1_into_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
885
        return [('rename', ('dir1', 'dir2/dir1'))]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
886
887
    def check_dir1_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
888
        self.assertPathDoesNotExist('branch/dir1')
889
        self.assertPathExists('branch/dir2/dir1')
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
890
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
891
    def do_move_dir2_into_dir1(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
892
        return [('rename', ('dir2', 'dir1/dir2'))]
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
893
894
    def check_dir2_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
895
        self.assertPathDoesNotExist('branch/dir2')
896
        self.assertPathExists('branch/dir1/dir2')
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
897
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
898
    def do_create_dir1_4(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
899
        return [('add', ('dir1', 'dir1-id', 'directory', '')),
900
                ('add', ('dir1/dir2', 'dir2-id', 'directory', '')),
901
                ('add', ('dir3', 'dir3-id', 'directory', '')),
902
                ('add', ('dir3/dir4', 'dir4-id', 'directory', '')),]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
903
904
    def do_move_dir1_into_dir4(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
905
        return [('rename', ('dir1', 'dir3/dir4/dir1'))]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
906
907
    def check_dir1_2_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
908
        self.assertPathDoesNotExist('branch/dir1')
909
        self.assertPathExists('branch/dir3/dir4/dir1')
910
        self.assertPathExists('branch/dir3/dir4/dir1/dir2')
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
911
912
    def do_move_dir3_into_dir2(self):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
913
        return [('rename', ('dir3', 'dir1/dir2/dir3'))]
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
914
915
    def check_dir3_4_moved(self):
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
916
        self.assertPathDoesNotExist('branch/dir3')
917
        self.assertPathExists('branch/dir1/dir2/dir3')
918
        self.assertPathExists('branch/dir1/dir2/dir3/dir4')
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
919
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
920
    def _get_resolve_path_arg(self, wt, action):
4597.10.9 by Vincent Ladeuil
More doc.
921
        # ParentLoop says: moving <conflict_path> into <path>. Cancelled move.
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
922
        # But since <path> doesn't exist in the working tree, we need to use
4597.10.9 by Vincent Ladeuil
More doc.
923
        # <conflict_path> instead, and that, in turn, is given by dir_id. Pfew.
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
924
        return wt.id2path(self._other['dir_id'])
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
925
926
    def assertParentLoop(self, wt, c):
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
927
        self.assertEqual(self._other['dir_id'], c.file_id)
928
        self.assertEqual(self._other['target_id'], c.conflict_file_id)
4597.8.8 by Vincent Ladeuil
Exhibit bug #537956.
929
        # The conflict paths are irrelevant (they are deterministic but not
930
        # worth checking since they don't provide the needed information
931
        # anyway)
4597.10.8 by Vincent Ladeuil
Separate actions and conflict attributes.
932
        if self._other['xfail']:
933
            # It's a bit hackish to raise from here relying on being called for
934
            # both tests but this avoid overriding test_resolve_taking_other
4597.10.4 by Vincent Ladeuil
Handle TestResolveParentLoop expected failures more precisely.
935
            raise tests.KnownFailure(
936
                "ParentLoop doesn't carry enough info to resolve --take-other")
4597.8.7 by Vincent Ladeuil
Add whitebox tests for ParentLoop.
937
    _assert_conflict = assertParentLoop
938
939
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
940
class TestResolveNonDirectoryParent(TestResolveConflicts):
941
942
    preamble = """
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
943
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
944
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
945
$ cd trunk
946
$ bzr mkdir foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
947
...
948
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
949
$ echo "Boing" >foo/bar
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
950
$ bzr add -q foo/bar
951
$ bzr commit -q -m 'Add foo/bar'
952
$ bzr branch -q . -r 1 ../branch
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
953
$ cd ../branch
954
$ rm -r foo
955
$ echo "Boo!" >foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
956
$ bzr commit -q -m 'foo is now a file'
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
957
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
958
2>+N  foo.new/bar
959
2>RK  foo => foo.new/
960
# FIXME: The message is misleading, foo.new *is* a directory when the message
961
# is displayed -- vila 090916
962
2>Conflict: foo.new is not a directory, but has files in it.  Created directory.
963
2>1 conflicts encountered.
964
"""
965
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
966
    def test_take_this(self):
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
967
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
968
$ bzr rm -q foo.new --force
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
969
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
970
# aside ? -- vila 090916
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
971
$ bzr add -q foo
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
972
$ bzr resolve foo.new
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
973
2>1 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
974
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
975
""")
976
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
977
    def test_take_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
978
        self.run_script("""
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
979
$ bzr rm -q foo --force
980
$ bzr mv -q foo.new foo
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
981
$ bzr resolve foo
4597.9.19 by Vincent Ladeuil
resolve now reports conflicts resolved/remaining.
982
2>1 conflict(s) resolved, 0 remaining
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
983
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
984
""")
985
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
986
    def test_resolve_taking_this(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
987
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
988
$ bzr resolve --take-this foo.new
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
989
2>...
990
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
991
""")
992
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
993
    def test_resolve_taking_other(self):
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
994
        self.run_script("""
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
995
$ bzr resolve --take-other foo.new
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
996
2>...
997
$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
4597.3.35 by Vincent Ladeuil
Implement --interactive for NonDirectoryParent, sort of.
998
""")
999
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1000
1001
class TestMalformedTransform(script.TestCaseWithTransportAndScript):
1002
1003
    def test_bug_430129(self):
1004
        # This is nearly like TestResolveNonDirectoryParent but with branch and
1005
        # trunk switched. As such it should certainly produce the same
1006
        # conflict.
1007
        self.run_script("""
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1008
$ bzr init trunk
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1009
...
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1010
$ cd trunk
1011
$ bzr mkdir foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1012
...
1013
$ bzr commit -m 'Create trunk' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1014
$ rm -r foo
1015
$ echo "Boo!" >foo
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1016
$ bzr commit -m 'foo is now a file' -q
1017
$ bzr branch -q . -r 1 ../branch -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1018
$ cd ../branch
1019
$ echo "Boing" >foo/bar
5422.3.4 by Martin Pool
Update test_resolve to pass --quiet or ignore command output it doesn't care about
1020
$ bzr add -q foo/bar -q
1021
$ bzr commit -m 'Add foo/bar' -q
4597.3.15 by Vincent Ladeuil
Update to new shell-like tests syntax.
1022
$ bzr merge ../trunk
4597.3.12 by Vincent Ladeuil
Start writing tests for all expected conflict resolution actions.
1023
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
1024
""")
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1025
5050.63.2 by Vincent Ladeuil
The file should be in a subdir to reproduce the bug.
1026
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1027
class TestResolveActionOption(tests.TestCase):
1028
1029
    def setUp(self):
1030
        super(TestResolveActionOption, self).setUp()
1031
        self.options = [conflicts.ResolveActionOption()]
1032
        self.parser = option.get_optparser(dict((o.name, o)
1033
                                                for o in self.options))
1034
1035
    def parse(self, args):
1036
        return self.parser.parse_args(args)
1037
1038
    def test_unknown_action(self):
1039
        self.assertRaises(errors.BadOptionValue,
1040
                          self.parse, ['--action', 'take-me-to-the-moon'])
1041
1042
    def test_done(self):
1043
        opts, args = self.parse(['--action', 'done'])
1044
        self.assertEqual({'action':'done'}, opts)
1045
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1046
    def test_take_this(self):
1047
        opts, args = self.parse(['--action', 'take-this'])
1048
        self.assertEqual({'action': 'take_this'}, opts)
1049
        opts, args = self.parse(['--take-this'])
1050
        self.assertEqual({'action': 'take_this'}, opts)
4597.3.51 by Vincent Ladeuil
Implement conflicts.ResolveActionOption.
1051
4597.3.67 by Vincent Ladeuil
Settle with --take-this and --take-other as action names.
1052
    def test_take_other(self):
1053
        opts, args = self.parse(['--action', 'take-other'])
1054
        self.assertEqual({'action': 'take_other'}, opts)
1055
        opts, args = self.parse(['--take-other'])
1056
        self.assertEqual({'action': 'take_other'}, opts)