/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_shelf_ui.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
from cStringIO import StringIO
 
19
import os
 
20
import sys
 
21
from textwrap import dedent
 
22
 
 
23
from bzrlib import (
 
24
    errors,
 
25
    shelf_ui,
 
26
    revision,
 
27
    tests,
 
28
)
 
29
from bzrlib.tests import script
 
30
from bzrlib.tests import (
 
31
    features,
 
32
    )
 
33
 
 
34
 
 
35
class ExpectShelver(shelf_ui.Shelver):
 
36
    """A variant of Shelver that intercepts console activity, for testing."""
 
37
 
 
38
    def __init__(self, work_tree, target_tree, diff_writer=None,
 
39
                 auto=False, auto_apply=False, file_list=None, message=None,
 
40
                 destroy=False, reporter=None):
 
41
        shelf_ui.Shelver.__init__(self, work_tree, target_tree, diff_writer,
 
42
                                  auto, auto_apply, file_list, message,
 
43
                                  destroy, reporter=reporter)
 
44
        self.expected = []
 
45
        self.diff_writer = StringIO()
 
46
 
 
47
    def expect(self, message, response):
 
48
        self.expected.append((message, response))
 
49
 
 
50
    def prompt(self, message, choices, default):
 
51
        try:
 
52
            expected_message, response = self.expected.pop(0)
 
53
        except IndexError:
 
54
            raise AssertionError('Unexpected prompt: %s' % message)
 
55
        if message != expected_message:
 
56
            raise AssertionError('Wrong prompt: %s' % message)
 
57
        if choices != '&yes\n&No\n&finish\n&quit':
 
58
            raise AssertionError('Wrong choices: %s' % choices)
 
59
        return response
 
60
 
 
61
 
 
62
LINES_AJ = 'a\nb\nc\nd\ne\nf\ng\nh\ni\nj\n'
 
63
 
 
64
 
 
65
LINES_ZY = 'z\nb\nc\nd\ne\nf\ng\nh\ni\ny\n'
 
66
 
 
67
 
 
68
LINES_AY = 'a\nb\nc\nd\ne\nf\ng\nh\ni\ny\n'
 
69
 
 
70
 
 
71
class ShelfTestCase(tests.TestCaseWithTransport):
 
72
 
 
73
    def create_shelvable_tree(self):
 
74
        tree = self.make_branch_and_tree('tree')
 
75
        self.build_tree_contents([('tree/foo', LINES_AJ)])
 
76
        tree.add('foo', 'foo-id')
 
77
        tree.commit('added foo')
 
78
        self.build_tree_contents([('tree/foo', LINES_ZY)])
 
79
        return tree
 
80
 
 
81
 
 
82
class TestShelver(ShelfTestCase):
 
83
 
 
84
    def test_unexpected_prompt_failure(self):
 
85
        tree = self.create_shelvable_tree()
 
86
        tree.lock_tree_write()
 
87
        self.addCleanup(tree.unlock)
 
88
        shelver = ExpectShelver(tree, tree.basis_tree())
 
89
        self.addCleanup(shelver.finalize)
 
90
        e = self.assertRaises(AssertionError, shelver.run)
 
91
        self.assertEqual('Unexpected prompt: Shelve?', str(e))
 
92
 
 
93
    def test_wrong_prompt_failure(self):
 
94
        tree = self.create_shelvable_tree()
 
95
        tree.lock_tree_write()
 
96
        self.addCleanup(tree.unlock)
 
97
        shelver = ExpectShelver(tree, tree.basis_tree())
 
98
        self.addCleanup(shelver.finalize)
 
99
        shelver.expect('foo', 0)
 
100
        e = self.assertRaises(AssertionError, shelver.run)
 
101
        self.assertEqual('Wrong prompt: Shelve?', str(e))
 
102
 
 
103
    def test_shelve_not_diff(self):
 
104
        tree = self.create_shelvable_tree()
 
105
        tree.lock_tree_write()
 
106
        self.addCleanup(tree.unlock)
 
107
        shelver = ExpectShelver(tree, tree.basis_tree())
 
108
        self.addCleanup(shelver.finalize)
 
109
        shelver.expect('Shelve?', 1)
 
110
        shelver.expect('Shelve?', 1)
 
111
        # No final shelving prompt because no changes were selected
 
112
        shelver.run()
 
113
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
114
 
 
115
    def test_shelve_diff_no(self):
 
116
        tree = self.create_shelvable_tree()
 
117
        tree.lock_tree_write()
 
118
        self.addCleanup(tree.unlock)
 
119
        shelver = ExpectShelver(tree, tree.basis_tree())
 
120
        self.addCleanup(shelver.finalize)
 
121
        shelver.expect('Shelve?', 0)
 
122
        shelver.expect('Shelve?', 0)
 
123
        shelver.expect('Shelve 2 change(s)?', 1)
 
124
        shelver.run()
 
125
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
126
 
 
127
    def test_shelve_diff(self):
 
128
        tree = self.create_shelvable_tree()
 
129
        tree.lock_tree_write()
 
130
        self.addCleanup(tree.unlock)
 
131
        shelver = ExpectShelver(tree, tree.basis_tree())
 
132
        self.addCleanup(shelver.finalize)
 
133
        shelver.expect('Shelve?', 0)
 
134
        shelver.expect('Shelve?', 0)
 
135
        shelver.expect('Shelve 2 change(s)?', 0)
 
136
        shelver.run()
 
137
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
138
 
 
139
    def test_shelve_one_diff(self):
 
140
        tree = self.create_shelvable_tree()
 
141
        tree.lock_tree_write()
 
142
        self.addCleanup(tree.unlock)
 
143
        shelver = ExpectShelver(tree, tree.basis_tree())
 
144
        self.addCleanup(shelver.finalize)
 
145
        shelver.expect('Shelve?', 0)
 
146
        shelver.expect('Shelve?', 1)
 
147
        shelver.expect('Shelve 1 change(s)?', 0)
 
148
        shelver.run()
 
149
        self.assertFileEqual(LINES_AY, 'tree/foo')
 
150
 
 
151
    def test_shelve_binary_change(self):
 
152
        tree = self.create_shelvable_tree()
 
153
        self.build_tree_contents([('tree/foo', '\x00')])
 
154
        tree.lock_tree_write()
 
155
        self.addCleanup(tree.unlock)
 
156
        shelver = ExpectShelver(tree, tree.basis_tree())
 
157
        self.addCleanup(shelver.finalize)
 
158
        shelver.expect('Shelve binary changes?', 0)
 
159
        shelver.expect('Shelve 1 change(s)?', 0)
 
160
        shelver.run()
 
161
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
162
 
 
163
    def test_shelve_rename(self):
 
164
        tree = self.create_shelvable_tree()
 
165
        tree.rename_one('foo', 'bar')
 
166
        tree.lock_tree_write()
 
167
        self.addCleanup(tree.unlock)
 
168
        shelver = ExpectShelver(tree, tree.basis_tree())
 
169
        self.addCleanup(shelver.finalize)
 
170
        shelver.expect('Shelve renaming "foo" => "bar"?', 0)
 
171
        shelver.expect('Shelve?', 0)
 
172
        shelver.expect('Shelve?', 0)
 
173
        shelver.expect('Shelve 3 change(s)?', 0)
 
174
        shelver.run()
 
175
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
176
 
 
177
    def test_shelve_deletion(self):
 
178
        tree = self.create_shelvable_tree()
 
179
        os.unlink('tree/foo')
 
180
        tree.lock_tree_write()
 
181
        self.addCleanup(tree.unlock)
 
182
        shelver = ExpectShelver(tree, tree.basis_tree())
 
183
        self.addCleanup(shelver.finalize)
 
184
        shelver.expect('Shelve removing file "foo"?', 0)
 
185
        shelver.expect('Shelve 1 change(s)?', 0)
 
186
        shelver.run()
 
187
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
188
 
 
189
    def test_shelve_creation(self):
 
190
        tree = self.make_branch_and_tree('tree')
 
191
        tree.commit('add tree root')
 
192
        self.build_tree(['tree/foo'])
 
193
        tree.add('foo')
 
194
        tree.lock_tree_write()
 
195
        self.addCleanup(tree.unlock)
 
196
        shelver = ExpectShelver(tree, tree.basis_tree())
 
197
        self.addCleanup(shelver.finalize)
 
198
        shelver.expect('Shelve adding file "foo"?', 0)
 
199
        shelver.expect('Shelve 1 change(s)?', 0)
 
200
        shelver.run()
 
201
        self.assertPathDoesNotExist('tree/foo')
 
202
 
 
203
    def test_shelve_kind_change(self):
 
204
        tree = self.create_shelvable_tree()
 
205
        os.unlink('tree/foo')
 
206
        os.mkdir('tree/foo')
 
207
        tree.lock_tree_write()
 
208
        self.addCleanup(tree.unlock)
 
209
        shelver = ExpectShelver(tree, tree.basis_tree())
 
210
        self.addCleanup(shelver.finalize)
 
211
        shelver.expect('Shelve changing "foo" from file to directory?',
 
212
                       0)
 
213
        shelver.expect('Shelve 1 change(s)?', 0)
 
214
 
 
215
    def test_shelve_modify_target(self):
 
216
        self.requireFeature(features.SymlinkFeature)
 
217
        tree = self.create_shelvable_tree()
 
218
        os.symlink('bar', 'tree/baz')
 
219
        tree.add('baz', 'baz-id')
 
220
        tree.commit("Add symlink")
 
221
        os.unlink('tree/baz')
 
222
        os.symlink('vax', 'tree/baz')
 
223
        tree.lock_tree_write()
 
224
        self.addCleanup(tree.unlock)
 
225
        shelver = ExpectShelver(tree, tree.basis_tree())
 
226
        self.addCleanup(shelver.finalize)
 
227
        shelver.expect('Shelve changing target of "baz" from "bar" to '
 
228
                '"vax"?', 0)
 
229
        shelver.expect('Shelve 1 change(s)?', 0)
 
230
        shelver.run()
 
231
        self.assertEqual('bar', os.readlink('tree/baz'))
 
232
 
 
233
    def test_shelve_finish(self):
 
234
        tree = self.create_shelvable_tree()
 
235
        tree.lock_tree_write()
 
236
        self.addCleanup(tree.unlock)
 
237
        shelver = ExpectShelver(tree, tree.basis_tree())
 
238
        self.addCleanup(shelver.finalize)
 
239
        shelver.expect('Shelve?', 2)
 
240
        shelver.expect('Shelve 2 change(s)?', 0)
 
241
        shelver.run()
 
242
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
243
 
 
244
    def test_shelve_quit(self):
 
245
        tree = self.create_shelvable_tree()
 
246
        tree.lock_tree_write()
 
247
        self.addCleanup(tree.unlock)
 
248
        shelver = ExpectShelver(tree, tree.basis_tree())
 
249
        self.addCleanup(shelver.finalize)
 
250
        shelver.expect('Shelve?', 3)
 
251
        self.assertRaises(errors.UserAbort, shelver.run)
 
252
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
253
 
 
254
    def test_shelve_all(self):
 
255
        tree = self.create_shelvable_tree()
 
256
        shelver = ExpectShelver.from_args(sys.stdout, all=True,
 
257
            directory='tree')
 
258
        try:
 
259
            shelver.run()
 
260
        finally:
 
261
            shelver.finalize()
 
262
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
263
 
 
264
    def test_shelve_filename(self):
 
265
        tree = self.create_shelvable_tree()
 
266
        self.build_tree(['tree/bar'])
 
267
        tree.add('bar')
 
268
        tree.lock_tree_write()
 
269
        self.addCleanup(tree.unlock)
 
270
        shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar'])
 
271
        self.addCleanup(shelver.finalize)
 
272
        shelver.expect('Shelve adding file "bar"?', 0)
 
273
        shelver.expect('Shelve 1 change(s)?', 0)
 
274
        shelver.run()
 
275
 
 
276
    def test_shelve_destroy(self):
 
277
        tree = self.create_shelvable_tree()
 
278
        shelver = shelf_ui.Shelver.from_args(sys.stdout, all=True,
 
279
                                             directory='tree', destroy=True)
 
280
        self.addCleanup(shelver.finalize)
 
281
        shelver.run()
 
282
        self.assertIs(None, tree.get_shelf_manager().last_shelf())
 
283
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
284
 
 
285
    @staticmethod
 
286
    def shelve_all(tree, target_revision_id):
 
287
        tree.lock_write()
 
288
        try:
 
289
            target = tree.branch.repository.revision_tree(target_revision_id)
 
290
            shelver = shelf_ui.Shelver(tree, target, auto=True,
 
291
                                       auto_apply=True)
 
292
            try:
 
293
                shelver.run()
 
294
            finally:
 
295
                shelver.finalize()
 
296
        finally:
 
297
            tree.unlock()
 
298
 
 
299
    def test_shelve_old_root_preserved(self):
 
300
        tree1 = self.make_branch_and_tree('tree1')
 
301
        tree1.commit('add root')
 
302
        tree1_root_id = tree1.get_root_id()
 
303
        tree2 = self.make_branch_and_tree('tree2')
 
304
        rev2 = tree2.commit('add root')
 
305
        self.assertNotEquals(tree1_root_id, tree2.get_root_id())
 
306
        tree1.merge_from_branch(tree2.branch,
 
307
                                from_revision=revision.NULL_REVISION)
 
308
        tree1.commit('merging in tree2')
 
309
        self.assertEquals(tree1_root_id, tree1.get_root_id())
 
310
        # This is essentially assertNotRaises(InconsistentDelta)
 
311
        # With testtools 0.9.9, it can be rewritten as:
 
312
        # with ExpectedException(AssertionError,
 
313
        #                        'InconsistentDelta not raised'):
 
314
        #     with ExpectedException(errors.InconsistentDelta, ''):
 
315
        #         self.shelve_all(tree1, rev2)
 
316
        e = self.assertRaises(AssertionError, self.assertRaises,
 
317
                              errors.InconsistentDelta, self.shelve_all, tree1,
 
318
                              rev2)
 
319
        self.assertContainsRe('InconsistentDelta not raised', str(e))
 
320
 
 
321
    def test_shelve_split(self):
 
322
        outer_tree = self.make_branch_and_tree('outer')
 
323
        outer_tree.commit('Add root')
 
324
        inner_tree = self.make_branch_and_tree('outer/inner')
 
325
        rev2 = inner_tree.commit('Add root')
 
326
        outer_tree.subsume(inner_tree)
 
327
        # This is essentially assertNotRaises(ValueError).
 
328
        # The ValueError is 'None is not a valid file id'.
 
329
        self.expectFailure('Cannot shelve a join back to the inner tree.',
 
330
                           self.assertRaises, AssertionError,
 
331
                           self.assertRaises, ValueError, self.shelve_all,
 
332
                           outer_tree, rev2)
 
333
 
 
334
 
 
335
class TestApplyReporter(ShelfTestCase):
 
336
 
 
337
    def test_shelve_not_diff(self):
 
338
        tree = self.create_shelvable_tree()
 
339
        tree.lock_tree_write()
 
340
        self.addCleanup(tree.unlock)
 
341
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
342
                                reporter=shelf_ui.ApplyReporter())
 
343
        self.addCleanup(shelver.finalize)
 
344
        shelver.expect('Apply change?', 1)
 
345
        shelver.expect('Apply change?', 1)
 
346
        # No final shelving prompt because no changes were selected
 
347
        shelver.run()
 
348
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
349
 
 
350
    def test_shelve_diff_no(self):
 
351
        tree = self.create_shelvable_tree()
 
352
        tree.lock_tree_write()
 
353
        self.addCleanup(tree.unlock)
 
354
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
355
                                reporter=shelf_ui.ApplyReporter())
 
356
        self.addCleanup(shelver.finalize)
 
357
        shelver.expect('Apply change?', 0)
 
358
        shelver.expect('Apply change?', 0)
 
359
        shelver.expect('Apply 2 change(s)?', 1)
 
360
        shelver.run()
 
361
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
362
 
 
363
    def test_shelve_diff(self):
 
364
        tree = self.create_shelvable_tree()
 
365
        tree.lock_tree_write()
 
366
        self.addCleanup(tree.unlock)
 
367
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
368
                                reporter=shelf_ui.ApplyReporter())
 
369
        self.addCleanup(shelver.finalize)
 
370
        shelver.expect('Apply change?', 0)
 
371
        shelver.expect('Apply change?', 0)
 
372
        shelver.expect('Apply 2 change(s)?', 0)
 
373
        shelver.run()
 
374
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
375
 
 
376
    def test_shelve_binary_change(self):
 
377
        tree = self.create_shelvable_tree()
 
378
        self.build_tree_contents([('tree/foo', '\x00')])
 
379
        tree.lock_tree_write()
 
380
        self.addCleanup(tree.unlock)
 
381
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
382
                                reporter=shelf_ui.ApplyReporter())
 
383
        self.addCleanup(shelver.finalize)
 
384
        shelver.expect('Apply binary changes?', 0)
 
385
        shelver.expect('Apply 1 change(s)?', 0)
 
386
        shelver.run()
 
387
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
388
 
 
389
    def test_shelve_rename(self):
 
390
        tree = self.create_shelvable_tree()
 
391
        tree.rename_one('foo', 'bar')
 
392
        tree.lock_tree_write()
 
393
        self.addCleanup(tree.unlock)
 
394
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
395
                                reporter=shelf_ui.ApplyReporter())
 
396
        self.addCleanup(shelver.finalize)
 
397
        shelver.expect('Rename "bar" => "foo"?', 0)
 
398
        shelver.expect('Apply change?', 0)
 
399
        shelver.expect('Apply change?', 0)
 
400
        shelver.expect('Apply 3 change(s)?', 0)
 
401
        shelver.run()
 
402
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
403
 
 
404
    def test_shelve_deletion(self):
 
405
        tree = self.create_shelvable_tree()
 
406
        os.unlink('tree/foo')
 
407
        tree.lock_tree_write()
 
408
        self.addCleanup(tree.unlock)
 
409
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
410
                                reporter=shelf_ui.ApplyReporter())
 
411
        self.addCleanup(shelver.finalize)
 
412
        shelver.expect('Add file "foo"?', 0)
 
413
        shelver.expect('Apply 1 change(s)?', 0)
 
414
        shelver.run()
 
415
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
416
 
 
417
    def test_shelve_creation(self):
 
418
        tree = self.make_branch_and_tree('tree')
 
419
        tree.commit('add tree root')
 
420
        self.build_tree(['tree/foo'])
 
421
        tree.add('foo')
 
422
        tree.lock_tree_write()
 
423
        self.addCleanup(tree.unlock)
 
424
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
425
                                reporter=shelf_ui.ApplyReporter())
 
426
        self.addCleanup(shelver.finalize)
 
427
        shelver.expect('Delete file "foo"?', 0)
 
428
        shelver.expect('Apply 1 change(s)?', 0)
 
429
        shelver.run()
 
430
        self.assertPathDoesNotExist('tree/foo')
 
431
 
 
432
    def test_shelve_kind_change(self):
 
433
        tree = self.create_shelvable_tree()
 
434
        os.unlink('tree/foo')
 
435
        os.mkdir('tree/foo')
 
436
        tree.lock_tree_write()
 
437
        self.addCleanup(tree.unlock)
 
438
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
439
                               reporter=shelf_ui.ApplyReporter())
 
440
        self.addCleanup(shelver.finalize)
 
441
        shelver.expect('Change "foo" from directory to a file?', 0)
 
442
        shelver.expect('Apply 1 change(s)?', 0)
 
443
 
 
444
    def test_shelve_modify_target(self):
 
445
        self.requireFeature(features.SymlinkFeature)
 
446
        tree = self.create_shelvable_tree()
 
447
        os.symlink('bar', 'tree/baz')
 
448
        tree.add('baz', 'baz-id')
 
449
        tree.commit("Add symlink")
 
450
        os.unlink('tree/baz')
 
451
        os.symlink('vax', 'tree/baz')
 
452
        tree.lock_tree_write()
 
453
        self.addCleanup(tree.unlock)
 
454
        shelver = ExpectShelver(tree, tree.basis_tree(),
 
455
                                reporter=shelf_ui.ApplyReporter())
 
456
        self.addCleanup(shelver.finalize)
 
457
        shelver.expect('Change target of "baz" from "vax" to "bar"?',
 
458
                       0)
 
459
        shelver.expect('Apply 1 change(s)?', 0)
 
460
        shelver.run()
 
461
        self.assertEqual('bar', os.readlink('tree/baz'))
 
462
 
 
463
 
 
464
class TestUnshelver(tests.TestCaseWithTransport):
 
465
 
 
466
    def create_tree_with_shelf(self):
 
467
        tree = self.make_branch_and_tree('tree')
 
468
        tree.lock_write()
 
469
        try:
 
470
            self.build_tree_contents([('tree/foo', LINES_AJ)])
 
471
            tree.add('foo', 'foo-id')
 
472
            tree.commit('added foo')
 
473
            self.build_tree_contents([('tree/foo', LINES_ZY)])
 
474
            shelver = shelf_ui.Shelver(tree, tree.basis_tree(),
 
475
                                       auto_apply=True, auto=True)
 
476
            try:
 
477
                shelver.run()
 
478
            finally:
 
479
                shelver.finalize()
 
480
        finally:
 
481
            tree.unlock()
 
482
        return tree
 
483
 
 
484
    def test_unshelve(self):
 
485
        tree = self.create_tree_with_shelf()
 
486
        tree.lock_write()
 
487
        self.addCleanup(tree.unlock)
 
488
        manager = tree.get_shelf_manager()
 
489
        shelf_ui.Unshelver(tree, manager, 1, True, True, True).run()
 
490
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
491
 
 
492
    def test_unshelve_args(self):
 
493
        tree = self.create_tree_with_shelf()
 
494
        unshelver = shelf_ui.Unshelver.from_args(directory='tree')
 
495
        try:
 
496
            unshelver.run()
 
497
        finally:
 
498
            unshelver.tree.unlock()
 
499
        self.assertFileEqual(LINES_ZY, 'tree/foo')
 
500
        self.assertIs(None, tree.get_shelf_manager().last_shelf())
 
501
 
 
502
    def test_unshelve_args_dry_run(self):
 
503
        tree = self.create_tree_with_shelf()
 
504
        unshelver = shelf_ui.Unshelver.from_args(directory='tree',
 
505
            action='dry-run')
 
506
        try:
 
507
            unshelver.run()
 
508
        finally:
 
509
            unshelver.tree.unlock()
 
510
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
511
        self.assertEqual(1, tree.get_shelf_manager().last_shelf())
 
512
 
 
513
    def test_unshelve_args_preview(self):
 
514
        tree = self.create_tree_with_shelf()
 
515
        write_diff_to = StringIO()
 
516
        unshelver = shelf_ui.Unshelver.from_args(
 
517
            directory='tree', action='preview', write_diff_to=write_diff_to)
 
518
        try:
 
519
            unshelver.run()
 
520
        finally:
 
521
            unshelver.tree.unlock()
 
522
        # The changes were not unshelved.
 
523
        self.assertFileEqual(LINES_AJ, 'tree/foo')
 
524
        self.assertEqual(1, tree.get_shelf_manager().last_shelf())
 
525
 
 
526
        # But the diff was written to write_diff_to.
 
527
        diff = write_diff_to.getvalue()
 
528
        expected = dedent("""\
 
529
            @@ -1,4 +1,4 @@
 
530
            -a
 
531
            +z
 
532
             b
 
533
             c
 
534
             d
 
535
            @@ -7,4 +7,4 @@
 
536
             g
 
537
             h
 
538
             i
 
539
            -j
 
540
            +y
 
541
 
 
542
            """)
 
543
        self.assertEqualDiff(expected, diff[-len(expected):])
 
544
 
 
545
    def test_unshelve_args_delete_only(self):
 
546
        tree = self.make_branch_and_tree('tree')
 
547
        manager = tree.get_shelf_manager()
 
548
        shelf_file = manager.new_shelf()[1]
 
549
        try:
 
550
            shelf_file.write('garbage')
 
551
        finally:
 
552
            shelf_file.close()
 
553
        unshelver = shelf_ui.Unshelver.from_args(directory='tree',
 
554
                                                 action='delete-only')
 
555
        try:
 
556
            unshelver.run()
 
557
        finally:
 
558
            unshelver.tree.unlock()
 
559
        self.assertIs(None, manager.last_shelf())
 
560
 
 
561
    def test_unshelve_args_invalid_shelf_id(self):
 
562
        tree = self.make_branch_and_tree('tree')
 
563
        manager = tree.get_shelf_manager()
 
564
        shelf_file = manager.new_shelf()[1]
 
565
        try:
 
566
            shelf_file.write('garbage')
 
567
        finally:
 
568
            shelf_file.close()
 
569
        self.assertRaises(errors.InvalidShelfId,
 
570
            shelf_ui.Unshelver.from_args, directory='tree',
 
571
            action='delete-only', shelf_id='foo')
 
572
 
 
573
 
 
574
class TestUnshelveScripts(TestUnshelver, 
 
575
                          script.TestCaseWithTransportAndScript): 
 
576
 
 
577
    def test_unshelve_messages_keep(self):
 
578
        self.create_tree_with_shelf()
 
579
        self.run_script("""
 
580
$ cd tree
 
581
$ bzr unshelve --keep
 
582
2>Using changes with id "1".
 
583
2> M  foo
 
584
2>All changes applied successfully.
 
585
""")
 
586
 
 
587
    def test_unshelve_messages_delete(self):
 
588
        self.create_tree_with_shelf()
 
589
        self.run_script("""
 
590
$ cd tree
 
591
$ bzr unshelve --delete-only
 
592
2>Deleted changes with id "1".
 
593
""")
 
594
 
 
595
    def test_unshelve_messages_apply(self):
 
596
        self.create_tree_with_shelf()
 
597
        self.run_script("""
 
598
$ cd tree
 
599
$ bzr unshelve --apply
 
600
2>Using changes with id "1".
 
601
2> M  foo
 
602
2>All changes applied successfully.
 
603
2>Deleted changes with id "1".
 
604
""")
 
605
 
 
606
    def test_unshelve_messages_dry_run(self):
 
607
        self.create_tree_with_shelf()
 
608
        self.run_script("""
 
609
$ cd tree
 
610
$ bzr unshelve --dry-run
 
611
2>Using changes with id "1".
 
612
2> M  foo
 
613
""")