44
41
class TestPrepareShelf(tests.TestCaseWithTransport):
46
def prepare_shelve_rename(self):
43
def test_shelve_rename(self):
47
44
tree = self.make_branch_and_tree('.')
48
45
self.build_tree(['foo'])
49
46
tree.add(['foo'], ['foo-id'])
51
48
tree.rename_one('foo', 'bar')
52
tree.lock_tree_write()
53
self.addCleanup(tree.unlock)
54
49
creator = shelf.ShelfCreator(tree, tree.basis_tree())
55
50
self.addCleanup(creator.finalize)
56
51
self.assertEqual([('rename', 'foo-id', 'foo', 'bar')],
57
52
list(creator.iter_shelvable()))
60
def check_shelve_rename(self, creator):
53
creator.shelve_rename('foo-id')
61
54
work_trans_id = creator.work_transform.trans_id_file_id('foo-id')
62
55
self.assertEqual('foo', creator.work_transform.final_name(
65
58
self.assertEqual('bar', creator.shelf_transform.final_name(
68
def test_shelve_rename(self):
69
creator = self.prepare_shelve_rename()
70
creator.shelve_rename('foo-id')
71
self.check_shelve_rename(creator)
73
def test_shelve_change_handles_rename(self):
74
creator = self.prepare_shelve_rename()
75
creator.shelve_change(('rename', 'foo-id', 'foo', 'bar'))
76
self.check_shelve_rename(creator)
78
def prepare_shelve_move(self):
61
def test_shelve_move(self):
79
62
tree = self.make_branch_and_tree('.')
80
63
self.build_tree(['foo/', 'bar/', 'foo/baz'])
81
64
tree.add(['foo', 'bar', 'foo/baz'], ['foo-id', 'bar-id', 'baz-id'])
83
66
tree.rename_one('foo/baz', 'bar/baz')
84
tree.lock_tree_write()
85
self.addCleanup(tree.unlock)
86
67
creator = shelf.ShelfCreator(tree, tree.basis_tree())
87
68
self.addCleanup(creator.finalize)
88
69
self.assertEqual([('rename', 'baz-id', 'foo/baz', 'bar/baz')],
89
70
list(creator.iter_shelvable()))
92
def check_shelve_move(self, creator, tree):
71
creator.shelve_rename('baz-id')
93
72
work_trans_id = creator.work_transform.trans_id_file_id('baz-id')
94
73
work_foo = creator.work_transform.trans_id_file_id('foo-id')
95
74
self.assertEqual(work_foo, creator.work_transform.final_parent(
101
80
creator.transform()
102
81
self.assertEqual('foo/baz', tree.id2path('baz-id'))
104
def test_shelve_move(self):
105
creator, tree = self.prepare_shelve_move()
106
creator.shelve_rename('baz-id')
107
self.check_shelve_move(creator, tree)
109
def test_shelve_change_handles_move(self):
110
creator, tree = self.prepare_shelve_move()
111
creator.shelve_change(('rename', 'baz-id', 'foo/baz', 'bar/baz'))
112
self.check_shelve_move(creator, tree)
114
def test_shelve_changed_root_id(self):
115
tree = self.make_branch_and_tree('.')
116
self.build_tree(['foo'])
117
tree.set_root_id('first-root-id')
118
tree.add(['foo'], ['foo-id'])
120
tree.set_root_id('second-root-id')
121
tree.lock_tree_write()
122
self.addCleanup(tree.unlock)
123
creator = shelf.ShelfCreator(tree, tree.basis_tree())
124
self.addCleanup(creator.finalize)
125
self.expectFailure('shelf doesn\'t support shelving root changes yet',
127
('delete file', 'first-root-id', 'directory', ''),
128
('add file', 'second-root-id', 'directory', ''),
129
('rename', 'foo-id', u'foo', u'foo'),
130
], list(creator.iter_shelvable()))
132
self.assertEqual([('delete file', 'first-root-id', 'directory', ''),
133
('add file', 'second-root-id', 'directory', ''),
134
('rename', 'foo-id', u'foo', u'foo'),
135
], list(creator.iter_shelvable()))
137
83
def assertShelvedFileEqual(self, expected_content, creator, file_id):
138
84
s_trans_id = creator.shelf_transform.trans_id_file_id(file_id)
139
85
shelf_file = creator.shelf_transform._limbo_name(s_trans_id)
140
86
self.assertFileEqual(expected_content, shelf_file)
142
def prepare_content_change(self):
88
def test_shelve_content_change(self):
143
89
tree = self.make_branch_and_tree('.')
145
91
self.addCleanup(tree.unlock)
160
102
self.assertFileEqual('a\nc\n', 'foo')
161
103
self.assertShelvedFileEqual('b\na\n', creator, 'foo-id')
163
def test_shelve_change_handles_modify_text(self):
164
creator = self.prepare_content_change()
165
creator.shelve_change(('modify text', 'foo-id'))
167
self.assertFileEqual('a\n', 'foo')
168
self.assertShelvedFileEqual('b\na\nc\n', creator, 'foo-id')
170
def test_shelve_all(self):
171
creator = self.prepare_content_change()
174
self.assertFileEqual('a\n', 'foo')
175
self.assertShelvedFileEqual('b\na\nc\n', creator, 'foo-id')
177
def prepare_shelve_creation(self):
105
def test_shelve_creation(self):
178
106
tree = self.make_branch_and_tree('.')
179
107
tree.lock_write()
180
108
self.addCleanup(tree.unlock)
186
114
self.assertEqual([('add file', 'bar-id', 'directory', 'bar'),
187
115
('add file', 'foo-id', 'file', 'foo')],
188
116
sorted(list(creator.iter_shelvable())))
191
def check_shelve_creation(self, creator, tree):
117
creator.shelve_creation('foo-id')
118
creator.shelve_creation('bar-id')
192
120
self.assertRaises(StopIteration,
193
121
tree.iter_entries_by_dir(['foo-id']).next)
194
122
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
195
123
self.assertEqual('foo-id',
196
124
creator.shelf_transform.final_file_id(s_trans_id))
197
self.assertPathDoesNotExist('foo')
198
self.assertPathDoesNotExist('bar')
125
self.failIfExists('foo')
126
self.failIfExists('bar')
199
127
self.assertShelvedFileEqual('a\n', creator, 'foo-id')
200
128
s_bar_trans_id = creator.shelf_transform.trans_id_file_id('bar-id')
201
129
self.assertEqual('directory',
202
130
creator.shelf_transform.final_kind(s_bar_trans_id))
204
def test_shelve_creation(self):
205
creator, tree = self.prepare_shelve_creation()
206
creator.shelve_creation('foo-id')
207
creator.shelve_creation('bar-id')
209
self.check_shelve_creation(creator, tree)
211
def test_shelve_change_handles_creation(self):
212
creator, tree = self.prepare_shelve_creation()
213
creator.shelve_change(('add file', 'foo-id', 'file', 'foo'))
214
creator.shelve_change(('add file', 'bar-id', 'directory', 'bar'))
216
self.check_shelve_creation(creator, tree)
218
def _test_shelve_symlink_creation(self, link_name, link_target,
219
shelve_change=False):
220
self.requireFeature(features.SymlinkFeature)
132
def _test_shelve_symlink_creation(self, link_name, link_target):
133
self.requireFeature(tests.SymlinkFeature)
221
134
tree = self.make_branch_and_tree('.')
222
135
tree.lock_write()
223
136
self.addCleanup(tree.unlock)
228
141
self.addCleanup(creator.finalize)
229
142
self.assertEqual([('add file', 'foo-id', 'symlink', link_name)],
230
143
list(creator.iter_shelvable()))
232
creator.shelve_change(('add file', 'foo-id', 'symlink', link_name))
234
creator.shelve_creation('foo-id')
144
creator.shelve_creation('foo-id')
235
145
creator.transform()
236
146
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
237
self.assertPathDoesNotExist(link_name)
147
self.failIfExists(link_name)
238
148
limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
239
149
self.assertEqual(link_target, osutils.readlink(limbo_name))
240
150
ptree = creator.shelf_transform.get_preview_tree()
244
154
self._test_shelve_symlink_creation('foo', 'bar')
246
156
def test_shelve_unicode_symlink_creation(self):
247
self.requireFeature(features.UnicodeFilenameFeature)
157
self.requireFeature(tests.UnicodeFilenameFeature)
248
158
self._test_shelve_symlink_creation(u'fo\N{Euro Sign}o',
249
159
u'b\N{Euro Sign}ar')
251
def test_shelve_change_handles_symlink_creation(self):
252
self._test_shelve_symlink_creation('foo', 'bar', shelve_change=True)
254
161
def _test_shelve_symlink_target_change(self, link_name,
255
old_target, new_target,
256
shelve_change=False):
257
self.requireFeature(features.SymlinkFeature)
162
old_target, new_target):
163
self.requireFeature(tests.SymlinkFeature)
258
164
tree = self.make_branch_and_tree('.')
259
165
tree.lock_write()
260
166
self.addCleanup(tree.unlock)
285
187
self._test_shelve_symlink_target_change('foo', 'bar', 'baz')
287
189
def test_shelve_unicode_symlink_target_change(self):
288
self.requireFeature(features.UnicodeFilenameFeature)
190
self.requireFeature(tests.UnicodeFilenameFeature)
289
191
self._test_shelve_symlink_target_change(
290
192
u'fo\N{Euro Sign}o', u'b\N{Euro Sign}ar', u'b\N{Euro Sign}az')
292
def test_shelve_change_handles_symlink_target_change(self):
293
self._test_shelve_symlink_target_change('foo', 'bar', 'baz',
296
194
def test_shelve_creation_no_contents(self):
297
195
tree = self.make_branch_and_tree('.')
298
196
tree.lock_write()
330
228
self.assertEqual([('delete file', 'bar-id', 'file', 'foo/bar'),
331
229
('delete file', 'foo-id', 'directory', 'foo')],
332
230
sorted(list(creator.iter_shelvable())))
335
def check_shelve_deletion(self, tree):
336
self.assertTrue(tree.has_id('foo-id'))
337
self.assertTrue(tree.has_id('bar-id'))
338
self.assertFileEqual('baz', 'tree/foo/bar')
340
def test_shelve_deletion(self):
341
creator, tree = self.prepare_shelve_deletion()
342
231
creator.shelve_deletion('foo-id')
343
232
creator.shelve_deletion('bar-id')
344
233
creator.transform()
345
self.check_shelve_deletion(tree)
347
def test_shelve_change_handles_deletion(self):
348
creator, tree = self.prepare_shelve_deletion()
349
creator.shelve_change(('delete file', 'foo-id', 'directory', 'foo'))
350
creator.shelve_change(('delete file', 'bar-id', 'file', 'foo/bar'))
352
self.check_shelve_deletion(tree)
234
self.assertTrue('foo-id' in tree)
235
self.assertTrue('bar-id' in tree)
236
self.assertFileEqual('baz', 'tree/foo/bar')
354
238
def test_shelve_delete_contents(self):
355
239
tree = self.make_branch_and_tree('tree')
357
241
tree.add('foo', 'foo-id')
358
242
tree.commit('Added file and directory')
359
243
os.unlink('tree/foo')
360
tree.lock_tree_write()
361
self.addCleanup(tree.unlock)
362
244
creator = shelf.ShelfCreator(tree, tree.basis_tree())
363
245
self.addCleanup(creator.finalize)
364
246
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
365
247
sorted(list(creator.iter_shelvable())))
366
248
creator.shelve_deletion('foo-id')
367
249
creator.transform()
368
self.assertPathExists('tree/foo')
250
self.failUnlessExists('tree/foo')
370
def prepare_shelve_change_kind(self):
252
def test_shelve_change_kind(self):
371
253
tree = self.make_branch_and_tree('tree')
372
254
self.build_tree_contents([('tree/foo', 'bar')])
373
255
tree.add('foo', 'foo-id')
374
256
tree.commit('Added file and directory')
375
257
os.unlink('tree/foo')
376
258
os.mkdir('tree/foo')
377
tree.lock_tree_write()
378
self.addCleanup(tree.unlock)
379
259
creator = shelf.ShelfCreator(tree, tree.basis_tree())
380
260
self.addCleanup(creator.finalize)
381
261
self.assertEqual([('change kind', 'foo-id', 'file', 'directory',
382
262
'foo')], sorted(list(creator.iter_shelvable())))
385
def check_shelve_change_kind(self, creator):
263
creator.shelve_content_change('foo-id')
386
265
self.assertFileEqual('bar', 'tree/foo')
387
266
s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
388
267
self.assertEqual('directory',
389
268
creator.shelf_transform._new_contents[s_trans_id])
391
def test_shelve_change_kind(self):
392
creator = self.prepare_shelve_change_kind()
393
creator.shelve_content_change('foo-id')
395
self.check_shelve_change_kind(creator)
397
def test_shelve_change_handles_change_kind(self):
398
creator = self.prepare_shelve_change_kind()
399
creator.shelve_change(('change kind', 'foo-id', 'file', 'directory',
402
self.check_shelve_change_kind(creator)
404
def test_shelve_change_unknown_change(self):
405
tree = self.make_branch_and_tree('tree')
406
tree.lock_tree_write()
407
self.addCleanup(tree.unlock)
408
creator = shelf.ShelfCreator(tree, tree.basis_tree())
409
self.addCleanup(creator.finalize)
410
e = self.assertRaises(ValueError, creator.shelve_change, ('unknown',))
411
self.assertEqual('Unknown change kind: "unknown"', str(e))
413
270
def test_shelve_unversion(self):
414
271
tree = self.make_branch_and_tree('tree')
415
272
self.build_tree(['tree/foo',])
416
273
tree.add('foo', 'foo-id')
417
274
tree.commit('Added file and directory')
418
275
tree.unversion(['foo-id'])
419
tree.lock_tree_write()
420
self.addCleanup(tree.unlock)
421
276
creator = shelf.ShelfCreator(tree, tree.basis_tree())
422
277
self.addCleanup(creator.finalize)
423
278
self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
424
279
sorted(list(creator.iter_shelvable())))
425
280
creator.shelve_deletion('foo-id')
426
281
creator.transform()
427
self.assertPathExists('tree/foo')
282
self.failUnlessExists('tree/foo')
429
284
def test_shelve_serialization(self):
430
285
tree = self.make_branch_and_tree('.')
431
tree.lock_tree_write()
432
self.addCleanup(tree.unlock)
433
286
creator = shelf.ShelfCreator(tree, tree.basis_tree())
434
287
self.addCleanup(creator.finalize)
435
288
shelf_file = open('shelf', 'wb')
484
331
# And a second tentative should raise the same error (no
485
332
# limbo/pending_deletion leftovers).
486
tree.lock_tree_write()
488
self.assertRaises(errors.PathsNotVersionedError,
489
shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
493
def test_shelve_skips_added_root(self):
494
"""Skip adds of the root when iterating through shelvable changes."""
495
tree = self.make_branch_and_tree('tree')
496
tree.lock_tree_write()
497
self.addCleanup(tree.unlock)
498
creator = shelf.ShelfCreator(tree, tree.basis_tree())
499
self.addCleanup(creator.finalize)
500
self.assertEqual([], list(creator.iter_shelvable()))
502
def test_shelve_skips_added_root(self):
503
"""Skip adds of the root when iterating through shelvable changes."""
504
tree = self.make_branch_and_tree('tree')
505
tree.lock_tree_write()
506
self.addCleanup(tree.unlock)
507
creator = shelf.ShelfCreator(tree, tree.basis_tree())
508
self.addCleanup(creator.finalize)
509
self.assertEqual([], list(creator.iter_shelvable()))
333
self.assertRaises(errors.PathsNotVersionedError,
334
shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
512
337
class TestUnshelver(tests.TestCaseWithTransport):
571
394
list(creator.iter_shelvable())
572
395
creator.shelve_deletion('foo-id')
573
396
creator.shelve_deletion('bar-id')
574
with open('shelf', 'w+b') as shelf_file:
575
creator.write_shelf(shelf_file)
397
shelf_file = open('shelf', 'w+b')
398
self.addCleanup(shelf_file.close)
399
creator.write_shelf(shelf_file)
578
402
# validate the test setup
579
self.assertTrue(tree.has_id('foo-id'))
580
self.assertTrue(tree.has_id('bar-id'))
403
self.assertTrue('foo-id' in tree)
404
self.assertTrue('bar-id' in tree)
581
405
self.assertFileEqual('baz', 'tree/foo/bar')
582
with open('shelf', 'r+b') as shelf_file:
583
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
584
self.addCleanup(unshelver.finalize)
585
unshelver.make_merger().do_merge()
586
self.assertFalse(tree.has_id('foo-id'))
587
self.assertFalse(tree.has_id('bar-id'))
407
unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
408
unshelver.make_merger().do_merge()
409
self.assertFalse('foo-id' in tree)
410
self.assertFalse('bar-id' in tree)
589
412
def test_unshelve_base(self):
590
413
tree = self.make_branch_and_tree('tree')
626
448
self.assertEqual('Shelf corrupt.', str(e))
628
def test_unshelve_subdir_in_now_removed_dir(self):
629
tree = self.make_branch_and_tree('.')
630
self.addCleanup(tree.lock_write().unlock)
631
self.build_tree(['dir/', 'dir/subdir/', 'dir/subdir/foo'])
632
tree.add(['dir'], ['dir-id'])
633
tree.commit('versioned dir')
634
tree.add(['dir/subdir', 'dir/subdir/foo'], ['subdir-id', 'foo-id'])
635
creator = shelf.ShelfCreator(tree, tree.basis_tree())
636
self.addCleanup(creator.finalize)
637
for change in creator.iter_shelvable():
638
creator.shelve_change(change)
639
shelf_manager = tree.get_shelf_manager()
640
shelf_id = shelf_manager.shelve_changes(creator)
641
self.assertPathDoesNotExist('dir/subdir')
643
unshelver = shelf_manager.get_unshelver(shelf_id)
644
self.addCleanup(unshelver.finalize)
645
unshelver.make_merger().do_merge()
646
self.assertPathExists('dir/subdir/foo')
647
self.assertEqual('dir-id', tree.path2id('dir'))
648
self.assertEqual('subdir-id', tree.path2id('dir/subdir'))
649
self.assertEqual('foo-id', tree.path2id('dir/subdir/foo'))
652
451
class TestShelfManager(tests.TestCaseWithTransport):
748
547
creator.shelve_creation('foo-id')
749
548
shelf_manager = tree.get_shelf_manager()
750
549
shelf_id = shelf_manager.shelve_changes(creator)
751
self.assertPathDoesNotExist('tree/foo')
550
self.failIfExists('tree/foo')
752
551
unshelver = shelf_manager.get_unshelver(shelf_id)
753
self.addCleanup(unshelver.finalize)
754
552
unshelver.make_merger().do_merge()
755
553
self.assertFileEqual('bar', 'tree/foo')
757
555
def test_get_metadata(self):
758
556
tree = self.make_branch_and_tree('.')
759
tree.lock_tree_write()
760
self.addCleanup(tree.unlock)
761
557
creator = shelf.ShelfCreator(tree, tree.basis_tree())
762
self.addCleanup(creator.finalize)
763
558
shelf_manager = tree.get_shelf_manager()
764
559
shelf_id = shelf_manager.shelve_changes(creator, 'foo')
765
560
metadata = shelf_manager.get_metadata(shelf_id)