/brz/remove-bazaar

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