1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
1
# Copyright (C) 2008-2011, 2016 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
21
21
from textwrap import dedent
29
from bzrlib.tests import script
29
from brzlib.tests import script
30
from brzlib.tests import (
32
35
class ExpectShelver(shelf_ui.Shelver):
42
45
self.diff_writer = StringIO()
44
def expect(self, prompt, response):
45
self.expected.append((prompt, response))
47
def expect(self, message, response):
48
self.expected.append((message, response))
47
def prompt(self, message):
50
def prompt(self, message, choices, default):
49
prompt, response = self.expected.pop(0)
52
expected_message, response = self.expected.pop(0)
51
54
raise AssertionError('Unexpected prompt: %s' % message)
55
if message != expected_message:
53
56
raise AssertionError('Wrong prompt: %s' % message)
57
if choices != '&yes\n&No\n&finish\n&quit':
58
raise AssertionError('Wrong choices: %s' % choices)
63
68
LINES_AY = 'a\nb\nc\nd\ne\nf\ng\nh\ni\ny\n'
66
class TestShelver(tests.TestCaseWithTransport):
71
class ShelfTestCase(tests.TestCaseWithTransport):
68
73
def create_shelvable_tree(self):
69
74
tree = self.make_branch_and_tree('tree')
73
78
self.build_tree_contents([('tree/foo', LINES_ZY)])
82
class TestShelver(ShelfTestCase):
76
84
def test_unexpected_prompt_failure(self):
77
85
tree = self.create_shelvable_tree()
78
86
tree.lock_tree_write()
80
88
shelver = ExpectShelver(tree, tree.basis_tree())
81
89
self.addCleanup(shelver.finalize)
82
90
e = self.assertRaises(AssertionError, shelver.run)
83
self.assertEqual('Unexpected prompt: Shelve? [yNfq?]', str(e))
91
self.assertEqual('Unexpected prompt: Shelve?', str(e))
85
93
def test_wrong_prompt_failure(self):
86
94
tree = self.create_shelvable_tree()
88
96
self.addCleanup(tree.unlock)
89
97
shelver = ExpectShelver(tree, tree.basis_tree())
90
98
self.addCleanup(shelver.finalize)
91
shelver.expect('foo', 'y')
99
shelver.expect('foo', 0)
92
100
e = self.assertRaises(AssertionError, shelver.run)
93
self.assertEqual('Wrong prompt: Shelve? [yNfq?]', str(e))
101
self.assertEqual('Wrong prompt: Shelve?', str(e))
95
103
def test_shelve_not_diff(self):
96
104
tree = self.create_shelvable_tree()
98
106
self.addCleanup(tree.unlock)
99
107
shelver = ExpectShelver(tree, tree.basis_tree())
100
108
self.addCleanup(shelver.finalize)
101
shelver.expect('Shelve? [yNfq?]', 'n')
102
shelver.expect('Shelve? [yNfq?]', 'n')
109
shelver.expect('Shelve?', 1)
110
shelver.expect('Shelve?', 1)
103
111
# No final shelving prompt because no changes were selected
105
113
self.assertFileEqual(LINES_ZY, 'tree/foo')
110
118
self.addCleanup(tree.unlock)
111
119
shelver = ExpectShelver(tree, tree.basis_tree())
112
120
self.addCleanup(shelver.finalize)
113
shelver.expect('Shelve? [yNfq?]', 'y')
114
shelver.expect('Shelve? [yNfq?]', 'y')
115
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)
117
125
self.assertFileEqual(LINES_ZY, 'tree/foo')
122
130
self.addCleanup(tree.unlock)
123
131
shelver = ExpectShelver(tree, tree.basis_tree())
124
132
self.addCleanup(shelver.finalize)
125
shelver.expect('Shelve? [yNfq?]', 'y')
126
shelver.expect('Shelve? [yNfq?]', 'y')
127
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)
129
137
self.assertFileEqual(LINES_AJ, 'tree/foo')
134
142
self.addCleanup(tree.unlock)
135
143
shelver = ExpectShelver(tree, tree.basis_tree())
136
144
self.addCleanup(shelver.finalize)
137
shelver.expect('Shelve? [yNfq?]', 'y')
138
shelver.expect('Shelve? [yNfq?]', 'n')
139
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)
141
149
self.assertFileEqual(LINES_AY, 'tree/foo')
147
155
self.addCleanup(tree.unlock)
148
156
shelver = ExpectShelver(tree, tree.basis_tree())
149
157
self.addCleanup(shelver.finalize)
150
shelver.expect('Shelve binary changes? [yNfq?]', 'y')
151
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
158
shelver.expect('Shelve binary changes?', 0)
159
shelver.expect('Shelve 1 change(s)?', 0)
153
161
self.assertFileEqual(LINES_AJ, 'tree/foo')
159
167
self.addCleanup(tree.unlock)
160
168
shelver = ExpectShelver(tree, tree.basis_tree())
161
169
self.addCleanup(shelver.finalize)
162
shelver.expect('Shelve renaming "foo" => "bar"? [yNfq?]', 'y')
163
shelver.expect('Shelve? [yNfq?]', 'y')
164
shelver.expect('Shelve? [yNfq?]', 'y')
165
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)
167
175
self.assertFileEqual(LINES_AJ, 'tree/foo')
173
181
self.addCleanup(tree.unlock)
174
182
shelver = ExpectShelver(tree, tree.basis_tree())
175
183
self.addCleanup(shelver.finalize)
176
shelver.expect('Shelve removing file "foo"? [yNfq?]', 'y')
177
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
184
shelver.expect('Shelve removing file "foo"?', 0)
185
shelver.expect('Shelve 1 change(s)?', 0)
179
187
self.assertFileEqual(LINES_AJ, 'tree/foo')
187
195
self.addCleanup(tree.unlock)
188
196
shelver = ExpectShelver(tree, tree.basis_tree())
189
197
self.addCleanup(shelver.finalize)
190
shelver.expect('Shelve adding file "foo"? [yNfq?]', 'y')
191
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
198
shelver.expect('Shelve adding file "foo"?', 0)
199
shelver.expect('Shelve 1 change(s)?', 0)
193
self.failIfExists('tree/foo')
201
self.assertPathDoesNotExist('tree/foo')
195
203
def test_shelve_kind_change(self):
196
204
tree = self.create_shelvable_tree()
200
208
self.addCleanup(tree.unlock)
201
209
shelver = ExpectShelver(tree, tree.basis_tree())
202
210
self.addCleanup(shelver.finalize)
203
shelver.expect('Shelve changing "foo" from file to directory? [yNfq?]',
205
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)
207
215
def test_shelve_modify_target(self):
208
self.requireFeature(tests.SymlinkFeature)
216
self.requireFeature(features.SymlinkFeature)
209
217
tree = self.create_shelvable_tree()
210
218
os.symlink('bar', 'tree/baz')
211
219
tree.add('baz', 'baz-id')
217
225
shelver = ExpectShelver(tree, tree.basis_tree())
218
226
self.addCleanup(shelver.finalize)
219
227
shelver.expect('Shelve changing target of "baz" from "bar" to '
220
'"vax"? [yNfq?]', 'y')
221
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
229
shelver.expect('Shelve 1 change(s)?', 0)
223
231
self.assertEqual('bar', os.readlink('tree/baz'))
228
236
self.addCleanup(tree.unlock)
229
237
shelver = ExpectShelver(tree, tree.basis_tree())
230
238
self.addCleanup(shelver.finalize)
231
shelver.expect('Shelve? [yNfq?]', 'f')
232
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
239
shelver.expect('Shelve?', 2)
240
shelver.expect('Shelve 2 change(s)?', 0)
234
242
self.assertFileEqual(LINES_AJ, 'tree/foo')
239
247
self.addCleanup(tree.unlock)
240
248
shelver = ExpectShelver(tree, tree.basis_tree())
241
249
self.addCleanup(shelver.finalize)
242
shelver.expect('Shelve? [yNfq?]', 'q')
250
shelver.expect('Shelve?', 3)
243
251
self.assertRaises(errors.UserAbort, shelver.run)
244
252
self.assertFileEqual(LINES_ZY, 'tree/foo')
261
269
self.addCleanup(tree.unlock)
262
270
shelver = ExpectShelver(tree, tree.basis_tree(), file_list=['bar'])
263
271
self.addCleanup(shelver.finalize)
264
shelver.expect('Shelve adding file "bar"? [yNfq?]', 'y')
265
shelver.expect('Shelve 1 change(s)? [yNfq?]', 'y')
268
def test_shelve_help(self):
269
tree = self.create_shelvable_tree()
270
tree.lock_tree_write()
271
self.addCleanup(tree.unlock)
272
shelver = ExpectShelver(tree, tree.basis_tree())
273
self.addCleanup(shelver.finalize)
274
shelver.expect('Shelve? [yNfq?]', '?')
275
shelver.expect('Shelve? [(y)es, (N)o, (f)inish, or (q)uit]', 'f')
276
shelver.expect('Shelve 2 change(s)? [yNfq?]', 'y')
272
shelver.expect('Shelve adding file "bar"?', 0)
273
shelver.expect('Shelve 1 change(s)?', 0)
279
276
def test_shelve_destroy(self):
302
def test_shelve_old_root_deleted(self):
299
def test_shelve_old_root_preserved(self):
303
300
tree1 = self.make_branch_and_tree('tree1')
304
301
tree1.commit('add root')
302
tree1_root_id = tree1.get_root_id()
305
303
tree2 = self.make_branch_and_tree('tree2')
306
304
rev2 = tree2.commit('add root')
305
self.assertNotEqual(tree1_root_id, tree2.get_root_id())
307
306
tree1.merge_from_branch(tree2.branch,
308
307
from_revision=revision.NULL_REVISION)
309
tree1.commit('Replaced root entry')
308
tree1.commit('merging in tree2')
309
self.assertEqual(tree1_root_id, tree1.get_root_id())
310
310
# This is essentially assertNotRaises(InconsistentDelta)
311
self.expectFailure('Cannot shelve replacing a root entry',
312
self.assertRaises, AssertionError,
313
self.assertRaises, errors.InconsistentDelta,
314
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))
316
321
def test_shelve_split(self):
317
322
outer_tree = self.make_branch_and_tree('outer')
336
341
shelver = ExpectShelver(tree, tree.basis_tree(),
337
342
reporter=shelf_ui.ApplyReporter())
338
343
self.addCleanup(shelver.finalize)
339
shelver.expect('Apply change? [yNfq?]', 'n')
340
shelver.expect('Apply change? [yNfq?]', 'n')
344
shelver.expect('Apply change?', 1)
345
shelver.expect('Apply change?', 1)
341
346
# No final shelving prompt because no changes were selected
343
348
self.assertFileEqual(LINES_ZY, 'tree/foo')
349
354
shelver = ExpectShelver(tree, tree.basis_tree(),
350
355
reporter=shelf_ui.ApplyReporter())
351
356
self.addCleanup(shelver.finalize)
352
shelver.expect('Apply change? [yNfq?]', 'y')
353
shelver.expect('Apply change? [yNfq?]', 'y')
354
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)
356
361
self.assertFileEqual(LINES_ZY, 'tree/foo')
362
367
shelver = ExpectShelver(tree, tree.basis_tree(),
363
368
reporter=shelf_ui.ApplyReporter())
364
369
self.addCleanup(shelver.finalize)
365
shelver.expect('Apply change? [yNfq?]', 'y')
366
shelver.expect('Apply change? [yNfq?]', 'y')
367
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)
369
374
self.assertFileEqual(LINES_AJ, 'tree/foo')
376
381
shelver = ExpectShelver(tree, tree.basis_tree(),
377
382
reporter=shelf_ui.ApplyReporter())
378
383
self.addCleanup(shelver.finalize)
379
shelver.expect('Apply binary changes? [yNfq?]', 'y')
380
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
384
shelver.expect('Apply binary changes?', 0)
385
shelver.expect('Apply 1 change(s)?', 0)
382
387
self.assertFileEqual(LINES_AJ, 'tree/foo')
389
394
shelver = ExpectShelver(tree, tree.basis_tree(),
390
395
reporter=shelf_ui.ApplyReporter())
391
396
self.addCleanup(shelver.finalize)
392
shelver.expect('Rename "bar" => "foo"? [yNfq?]', 'y')
393
shelver.expect('Apply change? [yNfq?]', 'y')
394
shelver.expect('Apply change? [yNfq?]', 'y')
395
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)
397
402
self.assertFileEqual(LINES_AJ, 'tree/foo')
404
409
shelver = ExpectShelver(tree, tree.basis_tree(),
405
410
reporter=shelf_ui.ApplyReporter())
406
411
self.addCleanup(shelver.finalize)
407
shelver.expect('Add file "foo"? [yNfq?]', 'y')
408
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
412
shelver.expect('Add file "foo"?', 0)
413
shelver.expect('Apply 1 change(s)?', 0)
410
415
self.assertFileEqual(LINES_AJ, 'tree/foo')
419
424
shelver = ExpectShelver(tree, tree.basis_tree(),
420
425
reporter=shelf_ui.ApplyReporter())
421
426
self.addCleanup(shelver.finalize)
422
shelver.expect('Delete file "foo"? [yNfq?]', 'y')
423
shelver.expect('Apply 1 change(s)? [yNfq?]', 'y')
427
shelver.expect('Delete file "foo"?', 0)
428
shelver.expect('Apply 1 change(s)?', 0)
425
self.failIfExists('tree/foo')
430
self.assertPathDoesNotExist('tree/foo')
427
432
def test_shelve_kind_change(self):
428
433
tree = self.create_shelvable_tree()
433
438
shelver = ExpectShelver(tree, tree.basis_tree(),
434
439
reporter=shelf_ui.ApplyReporter())
435
440
self.addCleanup(shelver.finalize)
436
shelver.expect('Change "foo" from directory to a file? [yNfq?]', 'y')
437
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)
439
444
def test_shelve_modify_target(self):
440
self.requireFeature(tests.SymlinkFeature)
445
self.requireFeature(features.SymlinkFeature)
441
446
tree = self.create_shelvable_tree()
442
447
os.symlink('bar', 'tree/baz')
443
448
tree.add('baz', 'baz-id')
449
454
shelver = ExpectShelver(tree, tree.basis_tree(),
450
455
reporter=shelf_ui.ApplyReporter())
451
456
self.addCleanup(shelver.finalize)
452
shelver.expect('Change target of "baz" from "vax" to "bar"? [yNfq?]',
454
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)
456
461
self.assertEqual('bar', os.readlink('tree/baz'))