~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_shelf_ui.py

  • Committer: Patch Queue Manager
  • Date: 2011-10-14 16:54:26 UTC
  • mfrom: (6216.1.1 remove-this-file)
  • Revision ID: pqm@pqm.ubuntu.com-20111014165426-tjix4e6idryf1r2z
(jelmer) Remove an accidentally committed .THIS file. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 Canonical Ltd
 
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
from cStringIO import StringIO
19
19
import os
20
20
import sys
 
21
from textwrap import dedent
21
22
 
22
 
from bzrlib import errors, shelf_ui, tests
 
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
    )
23
33
 
24
34
 
25
35
class ExpectShelver(shelf_ui.Shelver):
34
44
        self.expected = []
35
45
        self.diff_writer = StringIO()
36
46
 
37
 
    def expect(self, prompt, response):
38
 
        self.expected.append((prompt, response))
 
47
    def expect(self, message, response):
 
48
        self.expected.append((message, response))
39
49
 
40
 
    def prompt(self, message):
 
50
    def prompt(self, message, choices, default):
41
51
        try:
42
 
            prompt, response = self.expected.pop(0)
 
52
            expected_message, response = self.expected.pop(0)
43
53
        except IndexError:
44
54
            raise AssertionError('Unexpected prompt: %s' % message)
45
 
        if prompt != message:
 
55
        if message != expected_message:
46
56
            raise AssertionError('Wrong prompt: %s' % message)
 
57
        if choices != '&yes\n&No\n&finish\n&quit':
 
58
            raise AssertionError('Wrong choices: %s' % choices)
47
59
        return response
48
60
 
49
61
 
56
68
LINES_AY = 'a\nb\nc\nd\ne\nf\ng\nh\ni\ny\n'
57
69
 
58
70
 
59
 
class TestShelver(tests.TestCaseWithTransport):
 
71
class ShelfTestCase(tests.TestCaseWithTransport):
60
72
 
61
73
    def create_shelvable_tree(self):
62
74
        tree = self.make_branch_and_tree('tree')
66
78
        self.build_tree_contents([('tree/foo', LINES_ZY)])
67
79
        return tree
68
80
 
 
81
 
 
82
class TestShelver(ShelfTestCase):
 
83
 
69
84
    def test_unexpected_prompt_failure(self):
70
85
        tree = self.create_shelvable_tree()
 
86
        tree.lock_tree_write()
 
87
        self.addCleanup(tree.unlock)
71
88
        shelver = ExpectShelver(tree, tree.basis_tree())
 
89
        self.addCleanup(shelver.finalize)
72
90
        e = self.assertRaises(AssertionError, shelver.run)
73
 
        self.assertEqual('Unexpected prompt: Shelve? [yNfq?]', str(e))
 
91
        self.assertEqual('Unexpected prompt: Shelve?', str(e))
74
92
 
75
93
    def test_wrong_prompt_failure(self):
76
94
        tree = self.create_shelvable_tree()
 
95
        tree.lock_tree_write()
 
96
        self.addCleanup(tree.unlock)
77
97
        shelver = ExpectShelver(tree, tree.basis_tree())
78
 
        shelver.expect('foo', 'y')
 
98
        self.addCleanup(shelver.finalize)
 
99
        shelver.expect('foo', 0)
79
100
        e = self.assertRaises(AssertionError, shelver.run)
80
 
        self.assertEqual('Wrong prompt: Shelve? [yNfq?]', str(e))
 
101
        self.assertEqual('Wrong prompt: Shelve?', str(e))
81
102
 
82
103
    def test_shelve_not_diff(self):
83
104
        tree = self.create_shelvable_tree()
 
105
        tree.lock_tree_write()
 
106
        self.addCleanup(tree.unlock)
84
107
        shelver = ExpectShelver(tree, tree.basis_tree())
85
 
        shelver.expect('Shelve? [yNfq?]', 'n')
86
 
        shelver.expect('Shelve? [yNfq?]', 'n')
 
108
        self.addCleanup(shelver.finalize)
 
109
        shelver.expect('Shelve?', 1)
 
110
        shelver.expect('Shelve?', 1)
87
111
        # No final shelving prompt because no changes were selected
88
112
        shelver.run()
89
113
        self.assertFileEqual(LINES_ZY, 'tree/foo')
90
114
 
91
115
    def test_shelve_diff_no(self):
92
116
        tree = self.create_shelvable_tree()
 
117
        tree.lock_tree_write()
 
118
        self.addCleanup(tree.unlock)
93
119
        shelver = ExpectShelver(tree, tree.basis_tree())
94
 
        shelver.expect('Shelve? [yNfq?]', 'y')
95
 
        shelver.expect('Shelve? [yNfq?]', 'y')
96
 
        shelver.expect('Shelve 2 change(s)? [yNfq?]', 'n')
 
120
        self.addCleanup(shelver.finalize)
 
121
        shelver.expect('Shelve?', 0)
 
122
        shelver.expect('Shelve?', 0)
 
123
        shelver.expect('Shelve 2 change(s)?', 1)
97
124
        shelver.run()
98
125
        self.assertFileEqual(LINES_ZY, 'tree/foo')
99
126
 
100
127
    def test_shelve_diff(self):
101
128
        tree = self.create_shelvable_tree()
 
129
        tree.lock_tree_write()
 
130
        self.addCleanup(tree.unlock)
102
131
        shelver = ExpectShelver(tree, tree.basis_tree())
103
 
        shelver.expect('Shelve? [yNfq?]', 'y')
104
 
        shelver.expect('Shelve? [yNfq?]', 'y')
105
 
        shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
 
132
        self.addCleanup(shelver.finalize)
 
133
        shelver.expect('Shelve?', 0)
 
134
        shelver.expect('Shelve?', 0)
 
135
        shelver.expect('Shelve 2 change(s)?', 0)
106
136
        shelver.run()
107
137
        self.assertFileEqual(LINES_AJ, 'tree/foo')
108
138
 
109
139
    def test_shelve_one_diff(self):
110
140
        tree = self.create_shelvable_tree()
 
141
        tree.lock_tree_write()
 
142
        self.addCleanup(tree.unlock)
111
143
        shelver = ExpectShelver(tree, tree.basis_tree())
112
 
        shelver.expect('Shelve? [yNfq?]', 'y')
113
 
        shelver.expect('Shelve? [yNfq?]', 'n')
114
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
144
        self.addCleanup(shelver.finalize)
 
145
        shelver.expect('Shelve?', 0)
 
146
        shelver.expect('Shelve?', 1)
 
147
        shelver.expect('Shelve 1 change(s)?', 0)
115
148
        shelver.run()
116
149
        self.assertFileEqual(LINES_AY, 'tree/foo')
117
150
 
118
151
    def test_shelve_binary_change(self):
119
152
        tree = self.create_shelvable_tree()
120
153
        self.build_tree_contents([('tree/foo', '\x00')])
 
154
        tree.lock_tree_write()
 
155
        self.addCleanup(tree.unlock)
121
156
        shelver = ExpectShelver(tree, tree.basis_tree())
122
 
        shelver.expect('Shelve binary changes? [yNfq?]', 'y')
123
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
157
        self.addCleanup(shelver.finalize)
 
158
        shelver.expect('Shelve binary changes?', 0)
 
159
        shelver.expect('Shelve 1 change(s)?', 0)
124
160
        shelver.run()
125
161
        self.assertFileEqual(LINES_AJ, 'tree/foo')
126
162
 
127
163
    def test_shelve_rename(self):
128
164
        tree = self.create_shelvable_tree()
129
165
        tree.rename_one('foo', 'bar')
 
166
        tree.lock_tree_write()
 
167
        self.addCleanup(tree.unlock)
130
168
        shelver = ExpectShelver(tree, tree.basis_tree())
131
 
        shelver.expect('Shelve renaming "foo" => "bar"? [yNfq?]', 'y')
132
 
        shelver.expect('Shelve? [yNfq?]', 'y')
133
 
        shelver.expect('Shelve? [yNfq?]', 'y')
134
 
        shelver.expect('Shelve 3 change(s)? [yNfq?]', 'y')
 
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)
135
174
        shelver.run()
136
175
        self.assertFileEqual(LINES_AJ, 'tree/foo')
137
176
 
138
177
    def test_shelve_deletion(self):
139
178
        tree = self.create_shelvable_tree()
140
179
        os.unlink('tree/foo')
 
180
        tree.lock_tree_write()
 
181
        self.addCleanup(tree.unlock)
141
182
        shelver = ExpectShelver(tree, tree.basis_tree())
142
 
        shelver.expect('Shelve removing file "foo"? [yNfq?]', 'y')
143
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
183
        self.addCleanup(shelver.finalize)
 
184
        shelver.expect('Shelve removing file "foo"?', 0)
 
185
        shelver.expect('Shelve 1 change(s)?', 0)
144
186
        shelver.run()
145
187
        self.assertFileEqual(LINES_AJ, 'tree/foo')
146
188
 
149
191
        tree.commit('add tree root')
150
192
        self.build_tree(['tree/foo'])
151
193
        tree.add('foo')
 
194
        tree.lock_tree_write()
 
195
        self.addCleanup(tree.unlock)
152
196
        shelver = ExpectShelver(tree, tree.basis_tree())
153
 
        shelver.expect('Shelve adding file "foo"? [yNfq?]', 'y')
154
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
197
        self.addCleanup(shelver.finalize)
 
198
        shelver.expect('Shelve adding file "foo"?', 0)
 
199
        shelver.expect('Shelve 1 change(s)?', 0)
155
200
        shelver.run()
156
 
        self.failIfExists('tree/foo')
 
201
        self.assertPathDoesNotExist('tree/foo')
157
202
 
158
203
    def test_shelve_kind_change(self):
159
204
        tree = self.create_shelvable_tree()
160
205
        os.unlink('tree/foo')
161
206
        os.mkdir('tree/foo')
 
207
        tree.lock_tree_write()
 
208
        self.addCleanup(tree.unlock)
162
209
        shelver = ExpectShelver(tree, tree.basis_tree())
163
 
        shelver.expect('Shelve changing "foo" from file to directory? [yNfq?]',
164
 
                       'y')
165
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
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)
166
214
 
167
215
    def test_shelve_modify_target(self):
168
 
        self.requireFeature(tests.SymlinkFeature)
 
216
        self.requireFeature(features.SymlinkFeature)
169
217
        tree = self.create_shelvable_tree()
170
218
        os.symlink('bar', 'tree/baz')
171
219
        tree.add('baz', 'baz-id')
172
220
        tree.commit("Add symlink")
173
221
        os.unlink('tree/baz')
174
222
        os.symlink('vax', 'tree/baz')
 
223
        tree.lock_tree_write()
 
224
        self.addCleanup(tree.unlock)
175
225
        shelver = ExpectShelver(tree, tree.basis_tree())
 
226
        self.addCleanup(shelver.finalize)
176
227
        shelver.expect('Shelve changing target of "baz" from "bar" to '
177
 
                '"vax"? [yNfq?]', 'y')
178
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
 
228
                '"vax"?', 0)
 
229
        shelver.expect('Shelve 1 change(s)?', 0)
179
230
        shelver.run()
180
231
        self.assertEqual('bar', os.readlink('tree/baz'))
181
232
 
182
233
    def test_shelve_finish(self):
183
234
        tree = self.create_shelvable_tree()
 
235
        tree.lock_tree_write()
 
236
        self.addCleanup(tree.unlock)
184
237
        shelver = ExpectShelver(tree, tree.basis_tree())
185
 
        shelver.expect('Shelve? [yNfq?]', 'f')
186
 
        shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
 
238
        self.addCleanup(shelver.finalize)
 
239
        shelver.expect('Shelve?', 2)
 
240
        shelver.expect('Shelve 2 change(s)?', 0)
187
241
        shelver.run()
188
242
        self.assertFileEqual(LINES_AJ, 'tree/foo')
189
243
 
190
244
    def test_shelve_quit(self):
191
245
        tree = self.create_shelvable_tree()
 
246
        tree.lock_tree_write()
 
247
        self.addCleanup(tree.unlock)
192
248
        shelver = ExpectShelver(tree, tree.basis_tree())
193
 
        shelver.expect('Shelve? [yNfq?]', 'q')
 
249
        self.addCleanup(shelver.finalize)
 
250
        shelver.expect('Shelve?', 3)
194
251
        self.assertRaises(errors.UserAbort, shelver.run)
195
252
        self.assertFileEqual(LINES_ZY, 'tree/foo')
196
253
 
197
254
    def test_shelve_all(self):
198
255
        tree = self.create_shelvable_tree()
199
 
        ExpectShelver.from_args(sys.stdout, all=True, directory='tree').run()
 
256
        shelver = ExpectShelver.from_args(sys.stdout, all=True,
 
257
            directory='tree')
 
258
        try:
 
259
            shelver.run()
 
260
        finally:
 
261
            shelver.finalize()
200
262
        self.assertFileEqual(LINES_AJ, 'tree/foo')
201
263
 
202
264
    def test_shelve_filename(self):
203
265
        tree = self.create_shelvable_tree()
204
266
        self.build_tree(['tree/bar'])
205
267
        tree.add('bar')
 
268
        tree.lock_tree_write()
 
269
        self.addCleanup(tree.unlock)
206
270
        shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar'])
207
 
        shelver.expect('Shelve adding file "bar"? [yNfq?]', 'y')
208
 
        shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
209
 
        shelver.run()
210
 
 
211
 
    def test_shelve_help(self):
212
 
        tree = self.create_shelvable_tree()
213
 
        shelver = ExpectShelver(tree, tree.basis_tree())
214
 
        shelver.expect('Shelve? [yNfq?]', '?')
215
 
        shelver.expect('Shelve? [(y)es, (N)o, (f)inish, or (q)uit]', 'f')
216
 
        shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
217
 
        shelver.run()
218
 
 
219
 
    def test_shelve_distroy(self):
 
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):
220
277
        tree = self.create_shelvable_tree()
221
278
        shelver = shelf_ui.Shelver.from_args(sys.stdout, all=True,
222
279
                                             directory='tree', destroy=True)
 
280
        self.addCleanup(shelver.finalize)
223
281
        shelver.run()
224
282
        self.assertIs(None, tree.get_shelf_manager().last_shelf())
225
283
        self.assertFileEqual(LINES_AJ, 'tree/foo')
226
284
 
227
 
 
228
 
class TestApplyReporter(TestShelver):
 
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):
229
336
 
230
337
    def test_shelve_not_diff(self):
231
338
        tree = self.create_shelvable_tree()
 
339
        tree.lock_tree_write()
 
340
        self.addCleanup(tree.unlock)
232
341
        shelver = ExpectShelver(tree, tree.basis_tree(),
233
342
                                reporter=shelf_ui.ApplyReporter())
234
 
        shelver.expect('Apply change? [yNfq?]', 'n')
235
 
        shelver.expect('Apply change? [yNfq?]', 'n')
 
343
        self.addCleanup(shelver.finalize)
 
344
        shelver.expect('Apply change?', 1)
 
345
        shelver.expect('Apply change?', 1)
236
346
        # No final shelving prompt because no changes were selected
237
347
        shelver.run()
238
348
        self.assertFileEqual(LINES_ZY, 'tree/foo')
239
349
 
240
350
    def test_shelve_diff_no(self):
241
351
        tree = self.create_shelvable_tree()
 
352
        tree.lock_tree_write()
 
353
        self.addCleanup(tree.unlock)
242
354
        shelver = ExpectShelver(tree, tree.basis_tree(),
243
355
                                reporter=shelf_ui.ApplyReporter())
244
 
        shelver.expect('Apply change? [yNfq?]', 'y')
245
 
        shelver.expect('Apply change? [yNfq?]', 'y')
246
 
        shelver.expect('Apply 2 change(s)? [yNfq?]', 'n')
 
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)
247
360
        shelver.run()
248
361
        self.assertFileEqual(LINES_ZY, 'tree/foo')
249
362
 
250
363
    def test_shelve_diff(self):
251
364
        tree = self.create_shelvable_tree()
 
365
        tree.lock_tree_write()
 
366
        self.addCleanup(tree.unlock)
252
367
        shelver = ExpectShelver(tree, tree.basis_tree(),
253
368
                                reporter=shelf_ui.ApplyReporter())
254
 
        shelver.expect('Apply change? [yNfq?]', 'y')
255
 
        shelver.expect('Apply change? [yNfq?]', 'y')
256
 
        shelver.expect('Apply 2 change(s)? [yNfq?]', 'y')
 
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)
257
373
        shelver.run()
258
374
        self.assertFileEqual(LINES_AJ, 'tree/foo')
259
375
 
260
376
    def test_shelve_binary_change(self):
261
377
        tree = self.create_shelvable_tree()
262
378
        self.build_tree_contents([('tree/foo', '\x00')])
 
379
        tree.lock_tree_write()
 
380
        self.addCleanup(tree.unlock)
263
381
        shelver = ExpectShelver(tree, tree.basis_tree(),
264
382
                                reporter=shelf_ui.ApplyReporter())
265
 
        shelver.expect('Apply binary changes? [yNfq?]', 'y')
266
 
        shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
 
383
        self.addCleanup(shelver.finalize)
 
384
        shelver.expect('Apply binary changes?', 0)
 
385
        shelver.expect('Apply 1 change(s)?', 0)
267
386
        shelver.run()
268
387
        self.assertFileEqual(LINES_AJ, 'tree/foo')
269
388
 
270
389
    def test_shelve_rename(self):
271
390
        tree = self.create_shelvable_tree()
272
391
        tree.rename_one('foo', 'bar')
 
392
        tree.lock_tree_write()
 
393
        self.addCleanup(tree.unlock)
273
394
        shelver = ExpectShelver(tree, tree.basis_tree(),
274
395
                                reporter=shelf_ui.ApplyReporter())
275
 
        shelver.expect('Rename "bar" => "foo"? [yNfq?]', 'y')
276
 
        shelver.expect('Apply change? [yNfq?]', 'y')
277
 
        shelver.expect('Apply change? [yNfq?]', 'y')
278
 
        shelver.expect('Apply 3 change(s)? [yNfq?]', 'y')
 
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)
279
401
        shelver.run()
280
402
        self.assertFileEqual(LINES_AJ, 'tree/foo')
281
403
 
282
404
    def test_shelve_deletion(self):
283
405
        tree = self.create_shelvable_tree()
284
406
        os.unlink('tree/foo')
 
407
        tree.lock_tree_write()
 
408
        self.addCleanup(tree.unlock)
285
409
        shelver = ExpectShelver(tree, tree.basis_tree(),
286
410
                                reporter=shelf_ui.ApplyReporter())
287
 
        shelver.expect('Add file "foo"? [yNfq?]', 'y')
288
 
        shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
 
411
        self.addCleanup(shelver.finalize)
 
412
        shelver.expect('Add file "foo"?', 0)
 
413
        shelver.expect('Apply 1 change(s)?', 0)
289
414
        shelver.run()
290
415
        self.assertFileEqual(LINES_AJ, 'tree/foo')
291
416
 
294
419
        tree.commit('add tree root')
295
420
        self.build_tree(['tree/foo'])
296
421
        tree.add('foo')
 
422
        tree.lock_tree_write()
 
423
        self.addCleanup(tree.unlock)
297
424
        shelver = ExpectShelver(tree, tree.basis_tree(),
298
425
                                reporter=shelf_ui.ApplyReporter())
299
 
        shelver.expect('Delete file "foo"? [yNfq?]', 'y')
300
 
        shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
 
426
        self.addCleanup(shelver.finalize)
 
427
        shelver.expect('Delete file "foo"?', 0)
 
428
        shelver.expect('Apply 1 change(s)?', 0)
301
429
        shelver.run()
302
 
        self.failIfExists('tree/foo')
 
430
        self.assertPathDoesNotExist('tree/foo')
303
431
 
304
432
    def test_shelve_kind_change(self):
305
433
        tree = self.create_shelvable_tree()
306
434
        os.unlink('tree/foo')
307
435
        os.mkdir('tree/foo')
 
436
        tree.lock_tree_write()
 
437
        self.addCleanup(tree.unlock)
308
438
        shelver = ExpectShelver(tree, tree.basis_tree(),
309
439
                               reporter=shelf_ui.ApplyReporter())
310
 
        shelver.expect('Change "foo" from directory to a file? [yNfq?]', 'y')
311
 
        shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
 
440
        self.addCleanup(shelver.finalize)
 
441
        shelver.expect('Change "foo" from directory to a file?', 0)
 
442
        shelver.expect('Apply 1 change(s)?', 0)
312
443
 
313
444
    def test_shelve_modify_target(self):
314
 
        self.requireFeature(tests.SymlinkFeature)
 
445
        self.requireFeature(features.SymlinkFeature)
315
446
        tree = self.create_shelvable_tree()
316
447
        os.symlink('bar', 'tree/baz')
317
448
        tree.add('baz', 'baz-id')
318
449
        tree.commit("Add symlink")
319
450
        os.unlink('tree/baz')
320
451
        os.symlink('vax', 'tree/baz')
 
452
        tree.lock_tree_write()
 
453
        self.addCleanup(tree.unlock)
321
454
        shelver = ExpectShelver(tree, tree.basis_tree(),
322
455
                                reporter=shelf_ui.ApplyReporter())
323
 
        shelver.expect('Change target of "baz" from "vax" to "bar"? [yNfq?]',
324
 
                       'y')
325
 
        shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
 
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)
326
460
        shelver.run()
327
461
        self.assertEqual('bar', os.readlink('tree/baz'))
328
462
 
331
465
 
332
466
    def create_tree_with_shelf(self):
333
467
        tree = self.make_branch_and_tree('tree')
334
 
        self.build_tree_contents([('tree/foo', LINES_AJ)])
335
 
        tree.add('foo', 'foo-id')
336
 
        tree.commit('added foo')
337
 
        self.build_tree_contents([('tree/foo', LINES_ZY)])
338
 
        shelf_ui.Shelver(tree, tree.basis_tree(), auto_apply=True,
339
 
                         auto=True).run()
 
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()
340
482
        return tree
341
483
 
342
484
    def test_unshelve(self):
349
491
 
350
492
    def test_unshelve_args(self):
351
493
        tree = self.create_tree_with_shelf()
352
 
        shelf_ui.Unshelver.from_args(directory='tree').run()
 
494
        unshelver = shelf_ui.Unshelver.from_args(directory='tree')
 
495
        try:
 
496
            unshelver.run()
 
497
        finally:
 
498
            unshelver.tree.unlock()
353
499
        self.assertFileEqual(LINES_ZY, 'tree/foo')
354
500
        self.assertIs(None, tree.get_shelf_manager().last_shelf())
355
501
 
356
502
    def test_unshelve_args_dry_run(self):
357
503
        tree = self.create_tree_with_shelf()
358
 
        shelf_ui.Unshelver.from_args(directory='tree', action='dry-run').run()
359
 
        self.assertFileEqual(LINES_AJ, 'tree/foo')
360
 
        self.assertEqual(1, tree.get_shelf_manager().last_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):])
361
544
 
362
545
    def test_unshelve_args_delete_only(self):
363
546
        tree = self.make_branch_and_tree('tree')
369
552
            shelf_file.close()
370
553
        unshelver = shelf_ui.Unshelver.from_args(directory='tree',
371
554
                                                 action='delete-only')
372
 
        unshelver.run()
 
555
        try:
 
556
            unshelver.run()
 
557
        finally:
 
558
            unshelver.tree.unlock()
373
559
        self.assertIs(None, manager.last_shelf())
374
560
 
375
561
    def test_unshelve_args_invalid_shelf_id(self):
383
569
        self.assertRaises(errors.InvalidShelfId,
384
570
            shelf_ui.Unshelver.from_args, directory='tree',
385
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
""")