/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.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-22 16:28:47 UTC
  • mto: This revision was merged to the branch mainline in revision 4922.
  • Revision ID: john@arbash-meinel.com-20091222162847-tvnsc69to4l4uf5r
Implement a permute_for_extension helper.

Use it for all of the 'simple' extension permutations.
It basically permutes all tests in the current module, by setting TestCase.module.
Which works well for most of our extension tests. Some had more advanced
handling of permutations (extra permutations, custom vars, etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008 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
import os
 
18
 
 
19
from bzrlib import (
 
20
    errors,
 
21
    osutils,
 
22
    pack,
 
23
    shelf,
 
24
    tests,
 
25
    transform,
 
26
    workingtree,
 
27
    )
 
28
 
 
29
 
 
30
EMPTY_SHELF = ("Bazaar pack format 1 (introduced in 0.18)\n"
 
31
               "B23\n"
 
32
               "metadata\n\n"
 
33
               "d11:revision_id5:null:e"
 
34
               "B159\n"
 
35
               "attribs\n\n"
 
36
               "d10:_id_numberi0e18:_new_executabilityde7:_new_idde"
 
37
               "9:_new_namede11:_new_parentde16:_non_present_idsde"
 
38
               "17:_removed_contentsle11:_removed_idle14:_tree_path_idsdeeE")
 
39
 
 
40
 
 
41
class TestPrepareShelf(tests.TestCaseWithTransport):
 
42
 
 
43
    def prepare_shelve_rename(self):
 
44
        tree = self.make_branch_and_tree('.')
 
45
        self.build_tree(['foo'])
 
46
        tree.add(['foo'], ['foo-id'])
 
47
        tree.commit('foo')
 
48
        tree.rename_one('foo', 'bar')
 
49
        tree.lock_tree_write()
 
50
        self.addCleanup(tree.unlock)
 
51
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
52
        self.addCleanup(creator.finalize)
 
53
        self.assertEqual([('rename', 'foo-id', 'foo', 'bar')],
 
54
                          list(creator.iter_shelvable()))
 
55
        return creator
 
56
 
 
57
    def check_shelve_rename(self, creator):
 
58
        work_trans_id = creator.work_transform.trans_id_file_id('foo-id')
 
59
        self.assertEqual('foo', creator.work_transform.final_name(
 
60
                         work_trans_id))
 
61
        shelf_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
62
        self.assertEqual('bar', creator.shelf_transform.final_name(
 
63
                         shelf_trans_id))
 
64
 
 
65
    def test_shelve_rename(self):
 
66
        creator = self.prepare_shelve_rename()
 
67
        creator.shelve_rename('foo-id')
 
68
        self.check_shelve_rename(creator)
 
69
 
 
70
    def test_shelve_change_handles_rename(self):
 
71
        creator = self.prepare_shelve_rename()
 
72
        creator.shelve_change(('rename', 'foo-id', 'foo', 'bar'))
 
73
        self.check_shelve_rename(creator)
 
74
 
 
75
    def prepare_shelve_move(self):
 
76
        tree = self.make_branch_and_tree('.')
 
77
        self.build_tree(['foo/', 'bar/', 'foo/baz'])
 
78
        tree.add(['foo', 'bar', 'foo/baz'], ['foo-id', 'bar-id', 'baz-id'])
 
79
        tree.commit('foo')
 
80
        tree.rename_one('foo/baz', 'bar/baz')
 
81
        tree.lock_tree_write()
 
82
        self.addCleanup(tree.unlock)
 
83
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
84
        self.addCleanup(creator.finalize)
 
85
        self.assertEqual([('rename', 'baz-id', 'foo/baz', 'bar/baz')],
 
86
                         list(creator.iter_shelvable()))
 
87
        return creator, tree
 
88
 
 
89
    def check_shelve_move(self, creator, tree):
 
90
        work_trans_id = creator.work_transform.trans_id_file_id('baz-id')
 
91
        work_foo = creator.work_transform.trans_id_file_id('foo-id')
 
92
        self.assertEqual(work_foo, creator.work_transform.final_parent(
 
93
                         work_trans_id))
 
94
        shelf_trans_id = creator.shelf_transform.trans_id_file_id('baz-id')
 
95
        shelf_bar = creator.shelf_transform.trans_id_file_id('bar-id')
 
96
        self.assertEqual(shelf_bar, creator.shelf_transform.final_parent(
 
97
                         shelf_trans_id))
 
98
        creator.transform()
 
99
        self.assertEqual('foo/baz', tree.id2path('baz-id'))
 
100
 
 
101
    def test_shelve_move(self):
 
102
        creator, tree = self.prepare_shelve_move()
 
103
        creator.shelve_rename('baz-id')
 
104
        self.check_shelve_move(creator, tree)
 
105
 
 
106
    def test_shelve_change_handles_move(self):
 
107
        creator, tree = self.prepare_shelve_move()
 
108
        creator.shelve_change(('rename', 'baz-id', 'foo/baz', 'bar/baz'))
 
109
        self.check_shelve_move(creator, tree)
 
110
 
 
111
    def assertShelvedFileEqual(self, expected_content, creator, file_id):
 
112
        s_trans_id = creator.shelf_transform.trans_id_file_id(file_id)
 
113
        shelf_file = creator.shelf_transform._limbo_name(s_trans_id)
 
114
        self.assertFileEqual(expected_content, shelf_file)
 
115
 
 
116
    def prepare_content_change(self):
 
117
        tree = self.make_branch_and_tree('.')
 
118
        tree.lock_write()
 
119
        self.addCleanup(tree.unlock)
 
120
        self.build_tree_contents([('foo', 'a\n')])
 
121
        tree.add('foo', 'foo-id')
 
122
        tree.commit('Committed foo')
 
123
        self.build_tree_contents([('foo', 'b\na\nc\n')])
 
124
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
125
        self.addCleanup(creator.finalize)
 
126
        return creator
 
127
 
 
128
    def test_shelve_content_change(self):
 
129
        creator = self.prepare_content_change()
 
130
        self.assertEqual([('modify text', 'foo-id')],
 
131
                         list(creator.iter_shelvable()))
 
132
        creator.shelve_lines('foo-id', ['a\n', 'c\n'])
 
133
        creator.transform()
 
134
        self.assertFileEqual('a\nc\n', 'foo')
 
135
        self.assertShelvedFileEqual('b\na\n', creator, 'foo-id')
 
136
 
 
137
    def test_shelve_change_handles_modify_text(self):
 
138
        creator = self.prepare_content_change()
 
139
        creator.shelve_change(('modify text', 'foo-id'))
 
140
        creator.transform()
 
141
        self.assertFileEqual('a\n', 'foo')
 
142
        self.assertShelvedFileEqual('b\na\nc\n', creator, 'foo-id')
 
143
 
 
144
    def test_shelve_all(self):
 
145
        creator = self.prepare_content_change()
 
146
        creator.shelve_all()
 
147
        creator.transform()
 
148
        self.assertFileEqual('a\n', 'foo')
 
149
        self.assertShelvedFileEqual('b\na\nc\n', creator, 'foo-id')
 
150
 
 
151
    def prepare_shelve_creation(self):
 
152
        tree = self.make_branch_and_tree('.')
 
153
        tree.lock_write()
 
154
        self.addCleanup(tree.unlock)
 
155
        tree.commit('Empty tree')
 
156
        self.build_tree_contents([('foo', 'a\n'), ('bar/',)])
 
157
        tree.add(['foo', 'bar'], ['foo-id', 'bar-id'])
 
158
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
159
        self.addCleanup(creator.finalize)
 
160
        self.assertEqual([('add file', 'bar-id', 'directory', 'bar'),
 
161
                          ('add file', 'foo-id', 'file', 'foo')],
 
162
                          sorted(list(creator.iter_shelvable())))
 
163
        return creator, tree
 
164
 
 
165
    def check_shelve_creation(self, creator, tree):
 
166
        self.assertRaises(StopIteration,
 
167
                          tree.iter_entries_by_dir(['foo-id']).next)
 
168
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
169
        self.assertEqual('foo-id',
 
170
                         creator.shelf_transform.final_file_id(s_trans_id))
 
171
        self.failIfExists('foo')
 
172
        self.failIfExists('bar')
 
173
        self.assertShelvedFileEqual('a\n', creator, 'foo-id')
 
174
        s_bar_trans_id = creator.shelf_transform.trans_id_file_id('bar-id')
 
175
        self.assertEqual('directory',
 
176
            creator.shelf_transform.final_kind(s_bar_trans_id))
 
177
 
 
178
    def test_shelve_creation(self):
 
179
        creator, tree = self.prepare_shelve_creation()
 
180
        creator.shelve_creation('foo-id')
 
181
        creator.shelve_creation('bar-id')
 
182
        creator.transform()
 
183
        self.check_shelve_creation(creator, tree)
 
184
 
 
185
    def test_shelve_change_handles_creation(self):
 
186
        creator, tree = self.prepare_shelve_creation()
 
187
        creator.shelve_change(('add file', 'foo-id', 'file', 'foo'))
 
188
        creator.shelve_change(('add file', 'bar-id', 'directory', 'bar'))
 
189
        creator.transform()
 
190
        self.check_shelve_creation(creator, tree)
 
191
 
 
192
    def _test_shelve_symlink_creation(self, link_name, link_target,
 
193
                                      shelve_change=False):
 
194
        self.requireFeature(tests.SymlinkFeature)
 
195
        tree = self.make_branch_and_tree('.')
 
196
        tree.lock_write()
 
197
        self.addCleanup(tree.unlock)
 
198
        tree.commit('Empty tree')
 
199
        os.symlink(link_target, link_name)
 
200
        tree.add(link_name, 'foo-id')
 
201
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
202
        self.addCleanup(creator.finalize)
 
203
        self.assertEqual([('add file', 'foo-id', 'symlink', link_name)],
 
204
                         list(creator.iter_shelvable()))
 
205
        if shelve_change:
 
206
            creator.shelve_change(('add file', 'foo-id', 'symlink', link_name))
 
207
        else:
 
208
            creator.shelve_creation('foo-id')
 
209
        creator.transform()
 
210
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
211
        self.failIfExists(link_name)
 
212
        limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
 
213
        self.assertEqual(link_target, osutils.readlink(limbo_name))
 
214
        ptree = creator.shelf_transform.get_preview_tree()
 
215
        self.assertEqual(link_target, ptree.get_symlink_target('foo-id'))
 
216
 
 
217
    def test_shelve_symlink_creation(self):
 
218
        self._test_shelve_symlink_creation('foo', 'bar')
 
219
 
 
220
    def test_shelve_unicode_symlink_creation(self):
 
221
        self.requireFeature(tests.UnicodeFilenameFeature)
 
222
        self._test_shelve_symlink_creation(u'fo\N{Euro Sign}o',
 
223
                                           u'b\N{Euro Sign}ar')
 
224
 
 
225
    def test_shelve_change_handles_symlink_creation(self):
 
226
        self._test_shelve_symlink_creation('foo', 'bar', shelve_change=True)
 
227
 
 
228
    def _test_shelve_symlink_target_change(self, link_name,
 
229
                                           old_target, new_target,
 
230
                                           shelve_change=False):
 
231
        self.requireFeature(tests.SymlinkFeature)
 
232
        tree = self.make_branch_and_tree('.')
 
233
        tree.lock_write()
 
234
        self.addCleanup(tree.unlock)
 
235
        os.symlink(old_target, link_name)
 
236
        tree.add(link_name, 'foo-id')
 
237
        tree.commit("commit symlink")
 
238
        os.unlink(link_name)
 
239
        os.symlink(new_target, link_name)
 
240
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
241
        self.addCleanup(creator.finalize)
 
242
        self.assertEqual([('modify target', 'foo-id', link_name,
 
243
                           old_target, new_target)],
 
244
                         list(creator.iter_shelvable()))
 
245
        if shelve_change:
 
246
            creator.shelve_change(('modify target', 'foo-id', link_name,
 
247
                                   old_target, new_target))
 
248
        else:
 
249
            creator.shelve_modify_target('foo-id')
 
250
        creator.transform()
 
251
        self.assertEqual(old_target, osutils.readlink(link_name))
 
252
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
253
        limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
 
254
        self.assertEqual(new_target, osutils.readlink(limbo_name))
 
255
        ptree = creator.shelf_transform.get_preview_tree()
 
256
        self.assertEqual(new_target, ptree.get_symlink_target('foo-id'))
 
257
 
 
258
    def test_shelve_symlink_target_change(self):
 
259
        self._test_shelve_symlink_target_change('foo', 'bar', 'baz')
 
260
 
 
261
    def test_shelve_unicode_symlink_target_change(self):
 
262
        self.requireFeature(tests.UnicodeFilenameFeature)
 
263
        self._test_shelve_symlink_target_change(
 
264
            u'fo\N{Euro Sign}o', u'b\N{Euro Sign}ar', u'b\N{Euro Sign}az')
 
265
 
 
266
    def test_shelve_change_handles_symlink_target_change(self):
 
267
        self._test_shelve_symlink_target_change('foo', 'bar', 'baz',
 
268
                                                shelve_change=True)
 
269
 
 
270
    def test_shelve_creation_no_contents(self):
 
271
        tree = self.make_branch_and_tree('.')
 
272
        tree.lock_write()
 
273
        self.addCleanup(tree.unlock)
 
274
        tree.commit('Empty tree')
 
275
        self.build_tree(['foo'])
 
276
        tree.add('foo', 'foo-id')
 
277
        os.unlink('foo')
 
278
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
279
        self.addCleanup(creator.finalize)
 
280
        self.assertEqual([('add file', 'foo-id', None, 'foo')],
 
281
                         sorted(list(creator.iter_shelvable())))
 
282
        creator.shelve_creation('foo-id')
 
283
        creator.transform()
 
284
        self.assertRaises(StopIteration,
 
285
                          tree.iter_entries_by_dir(['foo-id']).next)
 
286
        self.assertShelvedFileEqual('', creator, 'foo-id')
 
287
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
288
        self.assertEqual('foo-id',
 
289
                         creator.shelf_transform.final_file_id(s_trans_id))
 
290
        self.failIfExists('foo')
 
291
 
 
292
    def prepare_shelve_deletion(self):
 
293
        tree = self.make_branch_and_tree('tree')
 
294
        tree.lock_write()
 
295
        self.addCleanup(tree.unlock)
 
296
        self.build_tree_contents([('tree/foo/',), ('tree/foo/bar', 'baz')])
 
297
        tree.add(['foo', 'foo/bar'], ['foo-id', 'bar-id'])
 
298
        tree.commit('Added file and directory')
 
299
        tree.unversion(['foo-id', 'bar-id'])
 
300
        os.unlink('tree/foo/bar')
 
301
        os.rmdir('tree/foo')
 
302
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
303
        self.addCleanup(creator.finalize)
 
304
        self.assertEqual([('delete file', 'bar-id', 'file', 'foo/bar'),
 
305
                          ('delete file', 'foo-id', 'directory', 'foo')],
 
306
                          sorted(list(creator.iter_shelvable())))
 
307
        return creator, tree
 
308
 
 
309
    def check_shelve_deletion(self, tree):
 
310
        self.assertTrue('foo-id' in tree)
 
311
        self.assertTrue('bar-id' in tree)
 
312
        self.assertFileEqual('baz', 'tree/foo/bar')
 
313
 
 
314
    def test_shelve_deletion(self):
 
315
        creator, tree = self.prepare_shelve_deletion()
 
316
        creator.shelve_deletion('foo-id')
 
317
        creator.shelve_deletion('bar-id')
 
318
        creator.transform()
 
319
        self.check_shelve_deletion(tree)
 
320
 
 
321
    def test_shelve_change_handles_deletion(self):
 
322
        creator, tree = self.prepare_shelve_deletion()
 
323
        creator.shelve_change(('delete file', 'foo-id', 'directory', 'foo'))
 
324
        creator.shelve_change(('delete file', 'bar-id', 'file', 'foo/bar'))
 
325
        creator.transform()
 
326
        self.check_shelve_deletion(tree)
 
327
 
 
328
    def test_shelve_delete_contents(self):
 
329
        tree = self.make_branch_and_tree('tree')
 
330
        self.build_tree(['tree/foo',])
 
331
        tree.add('foo', 'foo-id')
 
332
        tree.commit('Added file and directory')
 
333
        os.unlink('tree/foo')
 
334
        tree.lock_tree_write()
 
335
        self.addCleanup(tree.unlock)
 
336
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
337
        self.addCleanup(creator.finalize)
 
338
        self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
 
339
                         sorted(list(creator.iter_shelvable())))
 
340
        creator.shelve_deletion('foo-id')
 
341
        creator.transform()
 
342
        self.failUnlessExists('tree/foo')
 
343
 
 
344
    def prepare_shelve_change_kind(self):
 
345
        tree = self.make_branch_and_tree('tree')
 
346
        self.build_tree_contents([('tree/foo', 'bar')])
 
347
        tree.add('foo', 'foo-id')
 
348
        tree.commit('Added file and directory')
 
349
        os.unlink('tree/foo')
 
350
        os.mkdir('tree/foo')
 
351
        tree.lock_tree_write()
 
352
        self.addCleanup(tree.unlock)
 
353
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
354
        self.addCleanup(creator.finalize)
 
355
        self.assertEqual([('change kind', 'foo-id', 'file', 'directory',
 
356
                           'foo')], sorted(list(creator.iter_shelvable())))
 
357
        return creator
 
358
 
 
359
    def check_shelve_change_kind(self, creator):
 
360
        self.assertFileEqual('bar', 'tree/foo')
 
361
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
 
362
        self.assertEqual('directory',
 
363
                         creator.shelf_transform._new_contents[s_trans_id])
 
364
 
 
365
    def test_shelve_change_kind(self):
 
366
        creator = self.prepare_shelve_change_kind()
 
367
        creator.shelve_content_change('foo-id')
 
368
        creator.transform()
 
369
        self.check_shelve_change_kind(creator)
 
370
 
 
371
    def test_shelve_change_handles_change_kind(self):
 
372
        creator = self.prepare_shelve_change_kind()
 
373
        creator.shelve_change(('change kind', 'foo-id', 'file', 'directory',
 
374
                               'foo'))
 
375
        creator.transform()
 
376
        self.check_shelve_change_kind(creator)
 
377
 
 
378
    def test_shelve_change_unknown_change(self):
 
379
        tree = self.make_branch_and_tree('tree')
 
380
        tree.lock_tree_write()
 
381
        self.addCleanup(tree.unlock)
 
382
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
383
        self.addCleanup(creator.finalize)
 
384
        e = self.assertRaises(ValueError, creator.shelve_change, ('unknown',))
 
385
        self.assertEqual('Unknown change kind: "unknown"', str(e))
 
386
 
 
387
    def test_shelve_unversion(self):
 
388
        tree = self.make_branch_and_tree('tree')
 
389
        self.build_tree(['tree/foo',])
 
390
        tree.add('foo', 'foo-id')
 
391
        tree.commit('Added file and directory')
 
392
        tree.unversion(['foo-id'])
 
393
        tree.lock_tree_write()
 
394
        self.addCleanup(tree.unlock)
 
395
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
396
        self.addCleanup(creator.finalize)
 
397
        self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
 
398
                         sorted(list(creator.iter_shelvable())))
 
399
        creator.shelve_deletion('foo-id')
 
400
        creator.transform()
 
401
        self.failUnlessExists('tree/foo')
 
402
 
 
403
    def test_shelve_serialization(self):
 
404
        tree = self.make_branch_and_tree('.')
 
405
        tree.lock_tree_write()
 
406
        self.addCleanup(tree.unlock)
 
407
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
408
        self.addCleanup(creator.finalize)
 
409
        shelf_file = open('shelf', 'wb')
 
410
        self.addCleanup(shelf_file.close)
 
411
        try:
 
412
            creator.write_shelf(shelf_file)
 
413
        finally:
 
414
            shelf_file.close()
 
415
        self.assertFileEqual(EMPTY_SHELF, 'shelf')
 
416
 
 
417
    def test_write_shelf(self):
 
418
        tree = self.make_branch_and_tree('tree')
 
419
        self.build_tree(['tree/foo'])
 
420
        tree.add('foo', 'foo-id')
 
421
        tree.lock_tree_write()
 
422
        self.addCleanup(tree.unlock)
 
423
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
424
        self.addCleanup(creator.finalize)
 
425
        list(creator.iter_shelvable())
 
426
        creator.shelve_creation('foo-id')
 
427
        shelf_file = open('shelf', 'wb')
 
428
        try:
 
429
            creator.write_shelf(shelf_file)
 
430
        finally:
 
431
            shelf_file.close()
 
432
        parser = pack.ContainerPushParser()
 
433
        shelf_file = open('shelf', 'rb')
 
434
        try:
 
435
            parser.accept_bytes(shelf_file.read())
 
436
        finally:
 
437
            shelf_file.close()
 
438
        tt = transform.TransformPreview(tree)
 
439
        self.addCleanup(tt.finalize)
 
440
        records = iter(parser.read_pending_records())
 
441
        #skip revision-id
 
442
        records.next()
 
443
        tt.deserialize(records)
 
444
 
 
445
    def test_shelve_unversioned(self):
 
446
        tree = self.make_branch_and_tree('tree')
 
447
        tree.lock_tree_write()
 
448
        try:
 
449
            self.assertRaises(errors.PathsNotVersionedError,
 
450
                              shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
 
451
        finally:
 
452
            tree.unlock()
 
453
        # We should be able to lock/unlock the tree if ShelfCreator cleaned
 
454
        # after itself.
 
455
        wt = workingtree.WorkingTree.open('tree')
 
456
        wt.lock_tree_write()
 
457
        wt.unlock()
 
458
        # And a second tentative should raise the same error (no
 
459
        # limbo/pending_deletion leftovers).
 
460
        tree.lock_tree_write()
 
461
        try:
 
462
            self.assertRaises(errors.PathsNotVersionedError,
 
463
                              shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
 
464
        finally:
 
465
            tree.unlock()
 
466
 
 
467
    def test_shelve_skips_added_root(self):
 
468
        """Skip adds of the root when iterating through shelvable changes."""
 
469
        tree = self.make_branch_and_tree('tree')
 
470
        tree.lock_tree_write()
 
471
        self.addCleanup(tree.unlock)
 
472
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
473
        self.addCleanup(creator.finalize)
 
474
        self.assertEqual([], list(creator.iter_shelvable()))
 
475
 
 
476
    def test_shelve_skips_added_root(self):
 
477
        """Skip adds of the root when iterating through shelvable changes."""
 
478
        tree = self.make_branch_and_tree('tree')
 
479
        tree.lock_tree_write()
 
480
        self.addCleanup(tree.unlock)
 
481
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
482
        self.addCleanup(creator.finalize)
 
483
        self.assertEqual([], list(creator.iter_shelvable()))
 
484
 
 
485
 
 
486
class TestUnshelver(tests.TestCaseWithTransport):
 
487
 
 
488
    def test_make_merger(self):
 
489
        tree = self.make_branch_and_tree('tree')
 
490
        tree.commit('first commit')
 
491
        self.build_tree_contents([('tree/foo', 'bar')])
 
492
        tree.lock_write()
 
493
        self.addCleanup(tree.unlock)
 
494
        tree.add('foo', 'foo-id')
 
495
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
496
        self.addCleanup(creator.finalize)
 
497
        list(creator.iter_shelvable())
 
498
        creator.shelve_creation('foo-id')
 
499
        shelf_file = open('shelf-file', 'w+b')
 
500
        try:
 
501
            creator.write_shelf(shelf_file)
 
502
            creator.transform()
 
503
            shelf_file.seek(0)
 
504
            unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
 
505
            unshelver.make_merger().do_merge()
 
506
            self.addCleanup(unshelver.finalize)
 
507
            self.assertFileEqual('bar', 'tree/foo')
 
508
        finally:
 
509
            shelf_file.close()
 
510
 
 
511
    def test_unshelve_changed(self):
 
512
        tree = self.make_branch_and_tree('tree')
 
513
        tree.lock_write()
 
514
        self.addCleanup(tree.unlock)
 
515
        self.build_tree_contents([('tree/foo', 'a\nb\nc\n')])
 
516
        tree.add('foo', 'foo-id')
 
517
        tree.commit('first commit')
 
518
        self.build_tree_contents([('tree/foo', 'a\nb\nd\n')])
 
519
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
520
        self.addCleanup(creator.finalize)
 
521
        list(creator.iter_shelvable())
 
522
        creator.shelve_lines('foo-id', ['a\n', 'b\n', 'c\n'])
 
523
        shelf_file = open('shelf', 'w+b')
 
524
        self.addCleanup(shelf_file.close)
 
525
        creator.write_shelf(shelf_file)
 
526
        creator.transform()
 
527
        self.build_tree_contents([('tree/foo', 'z\na\nb\nc\n')])
 
528
        shelf_file.seek(0)
 
529
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
 
530
        self.addCleanup(unshelver.finalize)
 
531
        unshelver.make_merger().do_merge()
 
532
        self.assertFileEqual('z\na\nb\nd\n', 'tree/foo')
 
533
 
 
534
    def test_unshelve_deleted(self):
 
535
        tree = self.make_branch_and_tree('tree')
 
536
        tree.lock_write()
 
537
        self.addCleanup(tree.unlock)
 
538
        self.build_tree_contents([('tree/foo/',), ('tree/foo/bar', 'baz')])
 
539
        tree.add(['foo', 'foo/bar'], ['foo-id', 'bar-id'])
 
540
        tree.commit('Added file and directory')
 
541
        tree.unversion(['foo-id', 'bar-id'])
 
542
        os.unlink('tree/foo/bar')
 
543
        os.rmdir('tree/foo')
 
544
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
545
        list(creator.iter_shelvable())
 
546
        creator.shelve_deletion('foo-id')
 
547
        creator.shelve_deletion('bar-id')
 
548
        shelf_file = open('shelf', 'w+b')
 
549
        self.addCleanup(shelf_file.close)
 
550
        creator.write_shelf(shelf_file)
 
551
        creator.transform()
 
552
        creator.finalize()
 
553
        # validate the test setup
 
554
        self.assertTrue('foo-id' in tree)
 
555
        self.assertTrue('bar-id' in tree)
 
556
        self.assertFileEqual('baz', 'tree/foo/bar')
 
557
        shelf_file.seek(0)
 
558
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
 
559
        self.addCleanup(unshelver.finalize)
 
560
        unshelver.make_merger().do_merge()
 
561
        self.assertFalse('foo-id' in tree)
 
562
        self.assertFalse('bar-id' in tree)
 
563
 
 
564
    def test_unshelve_base(self):
 
565
        tree = self.make_branch_and_tree('tree')
 
566
        tree.lock_write()
 
567
        self.addCleanup(tree.unlock)
 
568
        tree.commit('rev1', rev_id='rev1')
 
569
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
570
        self.addCleanup(creator.finalize)
 
571
        manager = tree.get_shelf_manager()
 
572
        shelf_id, shelf_file = manager.new_shelf()
 
573
        try:
 
574
            creator.write_shelf(shelf_file)
 
575
        finally:
 
576
            shelf_file.close()
 
577
        tree.commit('rev2', rev_id='rev2')
 
578
        shelf_file = manager.read_shelf(1)
 
579
        self.addCleanup(shelf_file.close)
 
580
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
 
581
        self.addCleanup(unshelver.finalize)
 
582
        self.assertEqual('rev1', unshelver.base_tree.get_revision_id())
 
583
 
 
584
    def test_unshelve_serialization(self):
 
585
        tree = self.make_branch_and_tree('.')
 
586
        self.build_tree_contents([('shelf', EMPTY_SHELF)])
 
587
        shelf_file = open('shelf', 'rb')
 
588
        self.addCleanup(shelf_file.close)
 
589
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
 
590
        unshelver.finalize()
 
591
 
 
592
    def test_corrupt_shelf(self):
 
593
        tree = self.make_branch_and_tree('.')
 
594
        self.build_tree_contents([('shelf', EMPTY_SHELF.replace('metadata',
 
595
                                                                'foo'))])
 
596
        shelf_file = open('shelf', 'rb')
 
597
        self.addCleanup(shelf_file.close)
 
598
        e = self.assertRaises(errors.ShelfCorrupt,
 
599
                              shelf.Unshelver.from_tree_and_shelf, tree,
 
600
                              shelf_file)
 
601
        self.assertEqual('Shelf corrupt.', str(e))
 
602
 
 
603
 
 
604
class TestShelfManager(tests.TestCaseWithTransport):
 
605
 
 
606
    def test_get_shelf_manager(self):
 
607
        tree = self.make_branch_and_tree('.')
 
608
        manager = tree.get_shelf_manager()
 
609
        self.assertEqual(tree._transport.base + 'shelf/',
 
610
                         manager.transport.base)
 
611
 
 
612
    def get_manager(self):
 
613
        return self.make_branch_and_tree('.').get_shelf_manager()
 
614
 
 
615
    def test_get_shelf_filename(self):
 
616
        tree = self.make_branch_and_tree('.')
 
617
        manager = tree.get_shelf_manager()
 
618
        self.assertEqual('shelf-1', manager.get_shelf_filename(1))
 
619
 
 
620
    def test_get_shelf_ids(self):
 
621
        tree = self.make_branch_and_tree('.')
 
622
        manager = tree.get_shelf_manager()
 
623
        self.assertEqual([1, 3], manager.get_shelf_ids(
 
624
                         ['shelf-1', 'shelf-02', 'shelf-3']))
 
625
 
 
626
    def test_new_shelf(self):
 
627
        manager = self.get_manager()
 
628
        shelf_id, shelf_file = manager.new_shelf()
 
629
        shelf_file.close()
 
630
        self.assertEqual(1, shelf_id)
 
631
        shelf_id, shelf_file = manager.new_shelf()
 
632
        shelf_file.close()
 
633
        self.assertEqual(2, shelf_id)
 
634
        manager.delete_shelf(1)
 
635
        shelf_id, shelf_file = manager.new_shelf()
 
636
        shelf_file.close()
 
637
        self.assertEqual(3, shelf_id)
 
638
 
 
639
    def test_active_shelves(self):
 
640
        manager = self.get_manager()
 
641
        self.assertEqual([], manager.active_shelves())
 
642
        shelf_id, shelf_file = manager.new_shelf()
 
643
        shelf_file.close()
 
644
        self.assertEqual([1], manager.active_shelves())
 
645
 
 
646
    def test_delete_shelf(self):
 
647
        manager = self.get_manager()
 
648
        shelf_id, shelf_file = manager.new_shelf()
 
649
        shelf_file.close()
 
650
        self.assertEqual([1], manager.active_shelves())
 
651
        manager.delete_shelf(1)
 
652
        self.assertEqual([], manager.active_shelves())
 
653
 
 
654
    def test_last_shelf(self):
 
655
        manager = self.get_manager()
 
656
        self.assertIs(None, manager.last_shelf())
 
657
        shelf_id, shelf_file = manager.new_shelf()
 
658
        shelf_file.close()
 
659
        self.assertEqual(1, manager.last_shelf())
 
660
 
 
661
    def test_read_shelf(self):
 
662
        manager = self.get_manager()
 
663
        shelf_id, shelf_file = manager.new_shelf()
 
664
        try:
 
665
            shelf_file.write('foo')
 
666
        finally:
 
667
            shelf_file.close()
 
668
        shelf_id, shelf_file = manager.new_shelf()
 
669
        try:
 
670
            shelf_file.write('bar')
 
671
        finally:
 
672
            shelf_file.close()
 
673
        shelf_file = manager.read_shelf(1)
 
674
        try:
 
675
            self.assertEqual('foo', shelf_file.read())
 
676
        finally:
 
677
            shelf_file.close()
 
678
        shelf_file = manager.read_shelf(2)
 
679
        try:
 
680
            self.assertEqual('bar', shelf_file.read())
 
681
        finally:
 
682
            shelf_file.close()
 
683
 
 
684
    def test_read_non_existant(self):
 
685
        manager = self.get_manager()
 
686
        e = self.assertRaises(errors.NoSuchShelfId, manager.read_shelf, 1)
 
687
        self.assertEqual('No changes are shelved with id "1".', str(e))
 
688
 
 
689
    def test_shelve_changes(self):
 
690
        tree = self.make_branch_and_tree('tree')
 
691
        tree.commit('no-change commit')
 
692
        tree.lock_write()
 
693
        self.addCleanup(tree.unlock)
 
694
        self.build_tree_contents([('tree/foo', 'bar')])
 
695
        self.assertFileEqual('bar', 'tree/foo')
 
696
        tree.add('foo', 'foo-id')
 
697
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
698
        self.addCleanup(creator.finalize)
 
699
        list(creator.iter_shelvable())
 
700
        creator.shelve_creation('foo-id')
 
701
        shelf_manager = tree.get_shelf_manager()
 
702
        shelf_id = shelf_manager.shelve_changes(creator)
 
703
        self.failIfExists('tree/foo')
 
704
        unshelver = shelf_manager.get_unshelver(shelf_id)
 
705
        self.addCleanup(unshelver.finalize)
 
706
        unshelver.make_merger().do_merge()
 
707
        self.assertFileEqual('bar', 'tree/foo')
 
708
 
 
709
    def test_get_metadata(self):
 
710
        tree = self.make_branch_and_tree('.')
 
711
        tree.lock_tree_write()
 
712
        self.addCleanup(tree.unlock)
 
713
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
 
714
        self.addCleanup(creator.finalize)
 
715
        shelf_manager = tree.get_shelf_manager()
 
716
        shelf_id = shelf_manager.shelve_changes(creator, 'foo')
 
717
        metadata = shelf_manager.get_metadata(shelf_id)
 
718
        self.assertEqual('foo', metadata['message'])
 
719
        self.assertEqual('null:', metadata['revision_id'])