1
# Copyright (C) 2008 Canonical Ltd
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
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
40
45
self.diff_writer = StringIO()
42
def expect(self, prompt, response):
43
self.expected.append((prompt, response))
47
def expect(self, message, response):
48
self.expected.append((message, response))
45
def prompt(self, message):
50
def prompt(self, message, choices, default):
47
prompt, response = self.expected.pop(0)
52
expected_message, response = self.expected.pop(0)
49
54
raise AssertionError('Unexpected prompt: %s' % message)
55
if message != expected_message:
51
56
raise AssertionError('Wrong prompt: %s' % message)
57
if choices != '&yes\n&No\n&finish\n&quit':
58
raise AssertionError('Wrong choices: %s' % choices)
61
68
LINES_AY = 'a\nb\nc\nd\ne\nf\ng\nh\ni\ny\n'
64
class TestShelver(tests.TestCaseWithTransport):
71
class ShelfTestCase(tests.TestCaseWithTransport):
66
73
def create_shelvable_tree(self):
67
74
tree = self.make_branch_and_tree('tree')
71
78
self.build_tree_contents([('tree/foo', LINES_ZY)])
82
class TestShelver(ShelfTestCase):
74
84
def test_unexpected_prompt_failure(self):
75
85
tree = self.create_shelvable_tree()
76
86
tree.lock_tree_write()
78
88
shelver = ExpectShelver(tree, tree.basis_tree())
79
89
self.addCleanup(shelver.finalize)
80
90
e = self.assertRaises(AssertionError, shelver.run)
81
self.assertEqual('Unexpected prompt: Shelve? [yNfq?]', str(e))
91
self.assertEqual('Unexpected prompt: Shelve?', str(e))
83
93
def test_wrong_prompt_failure(self):
84
94
tree = self.create_shelvable_tree()
86
96
self.addCleanup(tree.unlock)
87
97
shelver = ExpectShelver(tree, tree.basis_tree())
88
98
self.addCleanup(shelver.finalize)
89
shelver.expect('foo', 'y')
99
shelver.expect('foo', 0)
90
100
e = self.assertRaises(AssertionError, shelver.run)
91
self.assertEqual('Wrong prompt: Shelve? [yNfq?]', str(e))
101
self.assertEqual('Wrong prompt: Shelve?', str(e))
93
103
def test_shelve_not_diff(self):
94
104
tree = self.create_shelvable_tree()
96
106
self.addCleanup(tree.unlock)
97
107
shelver = ExpectShelver(tree, tree.basis_tree())
98
108
self.addCleanup(shelver.finalize)
99
shelver.expect('Shelve? [yNfq?]', 'n')
100
shelver.expect('Shelve? [yNfq?]', 'n')
109
shelver.expect('Shelve?', 1)
110
shelver.expect('Shelve?', 1)
101
111
# No final shelving prompt because no changes were selected
103
113
self.assertFileEqual(LINES_ZY, 'tree/foo')
108
118
self.addCleanup(tree.unlock)
109
119
shelver = ExpectShelver(tree, tree.basis_tree())
110
120
self.addCleanup(shelver.finalize)
111
shelver.expect('Shelve? [yNfq?]', 'y')
112
shelver.expect('Shelve? [yNfq?]', 'y')
113
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'n')
121
shelver.expect('Shelve?', 0)
122
shelver.expect('Shelve?', 0)
123
shelver.expect('Shelve 2 change(s)?', 1)
115
125
self.assertFileEqual(LINES_ZY, 'tree/foo')
120
130
self.addCleanup(tree.unlock)
121
131
shelver = ExpectShelver(tree, tree.basis_tree())
122
132
self.addCleanup(shelver.finalize)
123
shelver.expect('Shelve? [yNfq?]', 'y')
124
shelver.expect('Shelve? [yNfq?]', 'y')
125
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
133
shelver.expect('Shelve?', 0)
134
shelver.expect('Shelve?', 0)
135
shelver.expect('Shelve 2 change(s)?', 0)
127
137
self.assertFileEqual(LINES_AJ, 'tree/foo')
132
142
self.addCleanup(tree.unlock)
133
143
shelver = ExpectShelver(tree, tree.basis_tree())
134
144
self.addCleanup(shelver.finalize)
135
shelver.expect('Shelve? [yNfq?]', 'y')
136
shelver.expect('Shelve? [yNfq?]', 'n')
137
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
145
shelver.expect('Shelve?', 0)
146
shelver.expect('Shelve?', 1)
147
shelver.expect('Shelve 1 change(s)?', 0)
139
149
self.assertFileEqual(LINES_AY, 'tree/foo')
145
155
self.addCleanup(tree.unlock)
146
156
shelver = ExpectShelver(tree, tree.basis_tree())
147
157
self.addCleanup(shelver.finalize)
148
shelver.expect('Shelve binary changes? [yNfq?]', 'y')
149
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
158
shelver.expect('Shelve binary changes?', 0)
159
shelver.expect('Shelve 1 change(s)?', 0)
151
161
self.assertFileEqual(LINES_AJ, 'tree/foo')
157
167
self.addCleanup(tree.unlock)
158
168
shelver = ExpectShelver(tree, tree.basis_tree())
159
169
self.addCleanup(shelver.finalize)
160
shelver.expect('Shelve renaming "foo" => "bar"? [yNfq?]', 'y')
161
shelver.expect('Shelve? [yNfq?]', 'y')
162
shelver.expect('Shelve? [yNfq?]', 'y')
163
shelver.expect('Shelve 3 change(s)? [yNfq?]', 'y')
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)
165
175
self.assertFileEqual(LINES_AJ, 'tree/foo')
171
181
self.addCleanup(tree.unlock)
172
182
shelver = ExpectShelver(tree, tree.basis_tree())
173
183
self.addCleanup(shelver.finalize)
174
shelver.expect('Shelve removing file "foo"? [yNfq?]', 'y')
175
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
184
shelver.expect('Shelve removing file "foo"?', 0)
185
shelver.expect('Shelve 1 change(s)?', 0)
177
187
self.assertFileEqual(LINES_AJ, 'tree/foo')
185
195
self.addCleanup(tree.unlock)
186
196
shelver = ExpectShelver(tree, tree.basis_tree())
187
197
self.addCleanup(shelver.finalize)
188
shelver.expect('Shelve adding file "foo"? [yNfq?]', 'y')
189
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
198
shelver.expect('Shelve adding file "foo"?', 0)
199
shelver.expect('Shelve 1 change(s)?', 0)
191
self.failIfExists('tree/foo')
201
self.assertPathDoesNotExist('tree/foo')
193
203
def test_shelve_kind_change(self):
194
204
tree = self.create_shelvable_tree()
198
208
self.addCleanup(tree.unlock)
199
209
shelver = ExpectShelver(tree, tree.basis_tree())
200
210
self.addCleanup(shelver.finalize)
201
shelver.expect('Shelve changing "foo" from file to directory? [yNfq?]',
203
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
211
shelver.expect('Shelve changing "foo" from file to directory?',
213
shelver.expect('Shelve 1 change(s)?', 0)
205
215
def test_shelve_modify_target(self):
206
self.requireFeature(tests.SymlinkFeature)
216
self.requireFeature(features.SymlinkFeature)
207
217
tree = self.create_shelvable_tree()
208
218
os.symlink('bar', 'tree/baz')
209
219
tree.add('baz', 'baz-id')
215
225
shelver = ExpectShelver(tree, tree.basis_tree())
216
226
self.addCleanup(shelver.finalize)
217
227
shelver.expect('Shelve changing target of "baz" from "bar" to '
218
'"vax"? [yNfq?]', 'y')
219
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
229
shelver.expect('Shelve 1 change(s)?', 0)
221
231
self.assertEqual('bar', os.readlink('tree/baz'))
226
236
self.addCleanup(tree.unlock)
227
237
shelver = ExpectShelver(tree, tree.basis_tree())
228
238
self.addCleanup(shelver.finalize)
229
shelver.expect('Shelve? [yNfq?]', 'f')
230
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
239
shelver.expect('Shelve?', 2)
240
shelver.expect('Shelve 2 change(s)?', 0)
232
242
self.assertFileEqual(LINES_AJ, 'tree/foo')
237
247
self.addCleanup(tree.unlock)
238
248
shelver = ExpectShelver(tree, tree.basis_tree())
239
249
self.addCleanup(shelver.finalize)
240
shelver.expect('Shelve? [yNfq?]', 'q')
250
shelver.expect('Shelve?', 3)
241
251
self.assertRaises(errors.UserAbort, shelver.run)
242
252
self.assertFileEqual(LINES_ZY, 'tree/foo')
259
269
self.addCleanup(tree.unlock)
260
270
shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar'])
261
271
self.addCleanup(shelver.finalize)
262
shelver.expect('Shelve adding file "bar"? [yNfq?]', 'y')
263
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
266
def test_shelve_help(self):
267
tree = self.create_shelvable_tree()
268
tree.lock_tree_write()
269
self.addCleanup(tree.unlock)
270
shelver = ExpectShelver(tree, tree.basis_tree())
271
self.addCleanup(shelver.finalize)
272
shelver.expect('Shelve? [yNfq?]', '?')
273
shelver.expect('Shelve? [(y)es, (N)o, (f)inish, or (q)uit]', 'f')
274
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
272
shelver.expect('Shelve adding file "bar"?', 0)
273
shelver.expect('Shelve 1 change(s)?', 0)
277
276
def test_shelve_destroy(self):
300
def test_shelve_old_root_deleted(self):
299
def test_shelve_old_root_preserved(self):
301
300
tree1 = self.make_branch_and_tree('tree1')
302
301
tree1.commit('add root')
302
tree1_root_id = tree1.get_root_id()
303
303
tree2 = self.make_branch_and_tree('tree2')
304
304
rev2 = tree2.commit('add root')
305
self.assertNotEquals(tree1_root_id, tree2.get_root_id())
305
306
tree1.merge_from_branch(tree2.branch,
306
307
from_revision=revision.NULL_REVISION)
307
tree1.commit('Replaced root entry')
308
tree1.commit('merging in tree2')
309
self.assertEquals(tree1_root_id, tree1.get_root_id())
308
310
# This is essentially assertNotRaises(InconsistentDelta)
309
self.expectFailure('Cannot shelve replacing a root entry',
310
self.assertRaises, AssertionError,
311
self.assertRaises, errors.InconsistentDelta,
312
self.shelve_all, tree1, rev2)
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,
319
self.assertContainsRe('InconsistentDelta not raised', str(e))
314
321
def test_shelve_split(self):
315
322
outer_tree = self.make_branch_and_tree('outer')
334
341
shelver = ExpectShelver(tree, tree.basis_tree(),
335
342
reporter=shelf_ui.ApplyReporter())
336
343
self.addCleanup(shelver.finalize)
337
shelver.expect('Apply change? [yNfq?]', 'n')
338
shelver.expect('Apply change? [yNfq?]', 'n')
344
shelver.expect('Apply change?', 1)
345
shelver.expect('Apply change?', 1)
339
346
# No final shelving prompt because no changes were selected
341
348
self.assertFileEqual(LINES_ZY, 'tree/foo')
347
354
shelver = ExpectShelver(tree, tree.basis_tree(),
348
355
reporter=shelf_ui.ApplyReporter())
349
356
self.addCleanup(shelver.finalize)
350
shelver.expect('Apply change? [yNfq?]', 'y')
351
shelver.expect('Apply change? [yNfq?]', 'y')
352
shelver.expect('Apply 2 change(s)? [yNfq?]', 'n')
357
shelver.expect('Apply change?', 0)
358
shelver.expect('Apply change?', 0)
359
shelver.expect('Apply 2 change(s)?', 1)
354
361
self.assertFileEqual(LINES_ZY, 'tree/foo')
360
367
shelver = ExpectShelver(tree, tree.basis_tree(),
361
368
reporter=shelf_ui.ApplyReporter())
362
369
self.addCleanup(shelver.finalize)
363
shelver.expect('Apply change? [yNfq?]', 'y')
364
shelver.expect('Apply change? [yNfq?]', 'y')
365
shelver.expect('Apply 2 change(s)? [yNfq?]', 'y')
370
shelver.expect('Apply change?', 0)
371
shelver.expect('Apply change?', 0)
372
shelver.expect('Apply 2 change(s)?', 0)
367
374
self.assertFileEqual(LINES_AJ, 'tree/foo')
374
381
shelver = ExpectShelver(tree, tree.basis_tree(),
375
382
reporter=shelf_ui.ApplyReporter())
376
383
self.addCleanup(shelver.finalize)
377
shelver.expect('Apply binary changes? [yNfq?]', 'y')
378
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
384
shelver.expect('Apply binary changes?', 0)
385
shelver.expect('Apply 1 change(s)?', 0)
380
387
self.assertFileEqual(LINES_AJ, 'tree/foo')
387
394
shelver = ExpectShelver(tree, tree.basis_tree(),
388
395
reporter=shelf_ui.ApplyReporter())
389
396
self.addCleanup(shelver.finalize)
390
shelver.expect('Rename "bar" => "foo"? [yNfq?]', 'y')
391
shelver.expect('Apply change? [yNfq?]', 'y')
392
shelver.expect('Apply change? [yNfq?]', 'y')
393
shelver.expect('Apply 3 change(s)? [yNfq?]', 'y')
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)
395
402
self.assertFileEqual(LINES_AJ, 'tree/foo')
402
409
shelver = ExpectShelver(tree, tree.basis_tree(),
403
410
reporter=shelf_ui.ApplyReporter())
404
411
self.addCleanup(shelver.finalize)
405
shelver.expect('Add file "foo"? [yNfq?]', 'y')
406
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
412
shelver.expect('Add file "foo"?', 0)
413
shelver.expect('Apply 1 change(s)?', 0)
408
415
self.assertFileEqual(LINES_AJ, 'tree/foo')
417
424
shelver = ExpectShelver(tree, tree.basis_tree(),
418
425
reporter=shelf_ui.ApplyReporter())
419
426
self.addCleanup(shelver.finalize)
420
shelver.expect('Delete file "foo"? [yNfq?]', 'y')
421
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
427
shelver.expect('Delete file "foo"?', 0)
428
shelver.expect('Apply 1 change(s)?', 0)
423
self.failIfExists('tree/foo')
430
self.assertPathDoesNotExist('tree/foo')
425
432
def test_shelve_kind_change(self):
426
433
tree = self.create_shelvable_tree()
431
438
shelver = ExpectShelver(tree, tree.basis_tree(),
432
439
reporter=shelf_ui.ApplyReporter())
433
440
self.addCleanup(shelver.finalize)
434
shelver.expect('Change "foo" from directory to a file? [yNfq?]', 'y')
435
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
441
shelver.expect('Change "foo" from directory to a file?', 0)
442
shelver.expect('Apply 1 change(s)?', 0)
437
444
def test_shelve_modify_target(self):
438
self.requireFeature(tests.SymlinkFeature)
445
self.requireFeature(features.SymlinkFeature)
439
446
tree = self.create_shelvable_tree()
440
447
os.symlink('bar', 'tree/baz')
441
448
tree.add('baz', 'baz-id')
447
454
shelver = ExpectShelver(tree, tree.basis_tree(),
448
455
reporter=shelf_ui.ApplyReporter())
449
456
self.addCleanup(shelver.finalize)
450
shelver.expect('Change target of "baz" from "vax" to "bar"? [yNfq?]',
452
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
457
shelver.expect('Change target of "baz" from "vax" to "bar"?',
459
shelver.expect('Apply 1 change(s)?', 0)
454
461
self.assertEqual('bar', os.readlink('tree/baz'))
503
510
self.assertFileEqual(LINES_AJ, 'tree/foo')
504
511
self.assertEqual(1, tree.get_shelf_manager().last_shelf())
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)
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())
526
# But the diff was written to write_diff_to.
527
diff = write_diff_to.getvalue()
528
expected = dedent("""\
543
self.assertEqualDiff(expected, diff[-len(expected):])
506
545
def test_unshelve_args_delete_only(self):
507
546
tree = self.make_branch_and_tree('tree')
508
547
manager = tree.get_shelf_manager()
530
569
self.assertRaises(errors.InvalidShelfId,
531
570
shelf_ui.Unshelver.from_args, directory='tree',
532
571
action='delete-only', shelf_id='foo')
574
class TestUnshelveScripts(TestUnshelver,
575
script.TestCaseWithTransportAndScript):
577
def test_unshelve_messages_keep(self):
578
self.create_tree_with_shelf()
581
$ bzr unshelve --keep
582
2>Using changes with id "1".
584
2>All changes applied successfully.
587
def test_unshelve_messages_delete(self):
588
self.create_tree_with_shelf()
591
$ bzr unshelve --delete-only
592
2>Deleted changes with id "1".
595
def test_unshelve_messages_apply(self):
596
self.create_tree_with_shelf()
599
$ bzr unshelve --apply
600
2>Using changes with id "1".
602
2>All changes applied successfully.
603
2>Deleted changes with id "1".
606
def test_unshelve_messages_dry_run(self):
607
self.create_tree_with_shelf()
610
$ bzr unshelve --dry-run
611
2>Using changes with id "1".