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