~bzr-pqm/bzr/bzr.dev

0.14.26 by Aaron Bentley
Update copyright
1
# Copyright (C) 2008 Canonical Ltd
0.12.12 by Aaron Bentley
Implement shelf creator
2
#
0.12.80 by Aaron Bentley
Re-format GPL notifications
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0.12.12 by Aaron Bentley
Implement shelf creator
16
0.12.17 by Aaron Bentley
Handle creating symlinks
17
import os
18
3873.2.4 by Benoît Pierre
Add a test: test_shelve_unversioned; check if tree is in a clean state
19
from bzrlib import errors, pack, shelf, tests, transform, workingtree
0.12.12 by Aaron Bentley
Implement shelf creator
20
21
0.14.34 by Aaron Bentley
Factor out the empty shelf
22
EMPTY_SHELF = ("Bazaar pack format 1 (introduced in 0.18)\n"
0.15.39 by Aaron Bentley
Update empty shelf serialization
23
               "B23\n"
24
               "metadata\n\n"
25
               "d11:revision_id5:null:e"
0.14.34 by Aaron Bentley
Factor out the empty shelf
26
               "B159\n"
27
               "attribs\n\n"
28
               "d10:_id_numberi0e18:_new_executabilityde7:_new_idde"
29
               "9:_new_namede11:_new_parentde16:_non_present_idsde"
30
               "17:_removed_contentsle11:_removed_idle14:_tree_path_idsdeeE")
31
32
0.12.12 by Aaron Bentley
Implement shelf creator
33
class TestPrepareShelf(tests.TestCaseWithTransport):
34
35
    def test_shelve_rename(self):
36
        tree = self.make_branch_and_tree('.')
37
        self.build_tree(['foo'])
38
        tree.add(['foo'], ['foo-id'])
39
        tree.commit('foo')
40
        tree.rename_one('foo', 'bar')
0.14.7 by Aaron Bentley
Misc test cleanup
41
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.12 by Aaron Bentley
Implement shelf creator
42
        self.addCleanup(creator.finalize)
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
43
        self.assertEqual([('rename', 'foo-id', 'foo', 'bar')],
44
                          list(creator.iter_shelvable()))
0.12.12 by Aaron Bentley
Implement shelf creator
45
        creator.shelve_rename('foo-id')
46
        work_trans_id = creator.work_transform.trans_id_file_id('foo-id')
47
        self.assertEqual('foo', creator.work_transform.final_name(
48
                         work_trans_id))
49
        shelf_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
50
        self.assertEqual('bar', creator.shelf_transform.final_name(
51
                         shelf_trans_id))
52
53
    def test_shelve_move(self):
54
        tree = self.make_branch_and_tree('.')
55
        self.build_tree(['foo/', 'bar/', 'foo/baz'])
56
        tree.add(['foo', 'bar', 'foo/baz'], ['foo-id', 'bar-id', 'baz-id'])
57
        tree.commit('foo')
58
        tree.rename_one('foo/baz', 'bar/baz')
0.14.7 by Aaron Bentley
Misc test cleanup
59
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.12 by Aaron Bentley
Implement shelf creator
60
        self.addCleanup(creator.finalize)
61
        self.assertEqual([('rename', 'baz-id', 'foo/baz', 'bar/baz')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
62
                         list(creator.iter_shelvable()))
0.12.12 by Aaron Bentley
Implement shelf creator
63
        creator.shelve_rename('baz-id')
64
        work_trans_id = creator.work_transform.trans_id_file_id('baz-id')
65
        work_foo = creator.work_transform.trans_id_file_id('foo-id')
66
        self.assertEqual(work_foo, creator.work_transform.final_parent(
67
                         work_trans_id))
68
        shelf_trans_id = creator.shelf_transform.trans_id_file_id('baz-id')
69
        shelf_bar = creator.shelf_transform.trans_id_file_id('bar-id')
70
        self.assertEqual(shelf_bar, creator.shelf_transform.final_parent(
71
                         shelf_trans_id))
0.12.13 by Aaron Bentley
Implement shelving content
72
        creator.transform()
73
        self.assertEqual('foo/baz', tree.id2path('baz-id'))
74
0.12.14 by Aaron Bentley
Add shelving of created files
75
    def assertShelvedFileEqual(self, expected_content, creator, file_id):
76
        s_trans_id = creator.shelf_transform.trans_id_file_id(file_id)
77
        shelf_file = creator.shelf_transform._limbo_name(s_trans_id)
78
        self.assertFileEqual(expected_content, shelf_file)
79
0.12.13 by Aaron Bentley
Implement shelving content
80
    def test_shelve_content_change(self):
81
        tree = self.make_branch_and_tree('.')
82
        tree.lock_write()
83
        self.addCleanup(tree.unlock)
84
        self.build_tree_contents([('foo', 'a\n')])
85
        tree.add('foo', 'foo-id')
86
        tree.commit('Committed foo')
87
        self.build_tree_contents([('foo', 'b\na\nc\n')])
0.14.7 by Aaron Bentley
Misc test cleanup
88
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.13 by Aaron Bentley
Implement shelving content
89
        self.addCleanup(creator.finalize)
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
90
        self.assertEqual([('modify text', 'foo-id')],
91
                         list(creator.iter_shelvable()))
0.14.14 by Aaron Bentley
Change shelf_text to shelve_lines
92
        creator.shelve_lines('foo-id', ['a\n', 'c\n'])
0.12.13 by Aaron Bentley
Implement shelving content
93
        creator.transform()
94
        self.assertFileEqual('a\nc\n', 'foo')
0.12.14 by Aaron Bentley
Add shelving of created files
95
        self.assertShelvedFileEqual('b\na\n', creator, 'foo-id')
96
97
    def test_shelve_creation(self):
98
        tree = self.make_branch_and_tree('.')
99
        tree.lock_write()
100
        self.addCleanup(tree.unlock)
101
        tree.commit('Empty tree')
0.12.16 by Aaron Bentley
Handle shelving directory creation
102
        self.build_tree_contents([('foo', 'a\n'), ('bar/',)])
103
        tree.add(['foo', 'bar'], ['foo-id', 'bar-id'])
0.14.7 by Aaron Bentley
Misc test cleanup
104
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.14 by Aaron Bentley
Add shelving of created files
105
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
106
        self.assertEqual([('add file', 'bar-id', 'directory', 'bar'),
107
                          ('add file', 'foo-id', 'file', 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
108
                          sorted(list(creator.iter_shelvable())))
0.14.2 by Aaron Bentley
Somewhat clean up shelving
109
        creator.shelve_creation('foo-id')
110
        creator.shelve_creation('bar-id')
0.12.14 by Aaron Bentley
Add shelving of created files
111
        creator.transform()
0.12.15 by Aaron Bentley
Handle file-id when shelving creation
112
        self.assertRaises(StopIteration,
113
                          tree.iter_entries_by_dir(['foo-id']).next)
114
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
115
        self.assertEqual('foo-id',
116
                         creator.shelf_transform.final_file_id(s_trans_id))
0.12.14 by Aaron Bentley
Add shelving of created files
117
        self.failIfExists('foo')
0.12.16 by Aaron Bentley
Handle shelving directory creation
118
        self.failIfExists('bar')
0.12.14 by Aaron Bentley
Add shelving of created files
119
        self.assertShelvedFileEqual('a\n', creator, 'foo-id')
0.12.16 by Aaron Bentley
Handle shelving directory creation
120
        s_bar_trans_id = creator.shelf_transform.trans_id_file_id('bar-id')
121
        self.assertEqual('directory',
122
            creator.shelf_transform.final_kind(s_bar_trans_id))
0.12.17 by Aaron Bentley
Handle creating symlinks
123
124
    def test_shelve_symlink_creation(self):
125
        self.requireFeature(tests.SymlinkFeature)
126
        tree = self.make_branch_and_tree('.')
127
        tree.lock_write()
128
        self.addCleanup(tree.unlock)
129
        tree.commit('Empty tree')
130
        os.symlink('bar', 'foo')
131
        tree.add('foo', 'foo-id')
0.14.7 by Aaron Bentley
Misc test cleanup
132
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.17 by Aaron Bentley
Handle creating symlinks
133
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
134
        self.assertEqual([('add file', 'foo-id', 'symlink', 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
135
                         list(creator.iter_shelvable()))
0.14.2 by Aaron Bentley
Somewhat clean up shelving
136
        creator.shelve_creation('foo-id')
0.12.17 by Aaron Bentley
Handle creating symlinks
137
        creator.transform()
138
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
139
        self.failIfExists('foo')
140
        limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
141
        self.assertEqual('bar', os.readlink(limbo_name))
0.12.19 by Aaron Bentley
Add support for writing shelves
142
4119.5.1 by James Westby
Shelve can now shelve changes to a symlink's target.
143
    def test_shelve_symlink_target_change(self):
144
        self.requireFeature(tests.SymlinkFeature)
145
        tree = self.make_branch_and_tree('.')
146
        tree.lock_write()
147
        self.addCleanup(tree.unlock)
148
        os.symlink('bar', 'foo')
149
        tree.add('foo', 'foo-id')
150
        tree.commit("commit symlink")
151
        os.unlink("foo")
152
        os.symlink('baz', 'foo')
153
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
154
        self.addCleanup(creator.finalize)
155
        self.assertEqual([('modify target', 'foo-id', 'foo', 'bar', 'baz')],
156
                         list(creator.iter_shelvable()))
157
        creator.shelve_modify_target('foo-id')
158
        creator.transform()
159
        self.assertEqual('bar', os.readlink('foo'))
160
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
161
        limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
162
        self.assertEqual('baz', os.readlink(limbo_name))
163
0.14.12 by Aaron Bentley
Handle new dangling ids
164
    def test_shelve_creation_no_contents(self):
165
        tree = self.make_branch_and_tree('.')
166
        tree.lock_write()
167
        self.addCleanup(tree.unlock)
168
        tree.commit('Empty tree')
169
        self.build_tree(['foo'])
170
        tree.add('foo', 'foo-id')
171
        os.unlink('foo')
172
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
173
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
174
        self.assertEqual([('add file', 'foo-id', None, 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
175
                         sorted(list(creator.iter_shelvable())))
0.14.12 by Aaron Bentley
Handle new dangling ids
176
        creator.shelve_creation('foo-id')
177
        creator.transform()
178
        self.assertRaises(StopIteration,
179
                          tree.iter_entries_by_dir(['foo-id']).next)
180
        self.assertShelvedFileEqual('', creator, 'foo-id')
181
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
182
        self.assertEqual('foo-id',
183
                         creator.shelf_transform.final_file_id(s_trans_id))
184
        self.failIfExists('foo')
185
0.14.4 by Aaron Bentley
Implement shelving deletion
186
    def test_shelve_deletion(self):
187
        tree = self.make_branch_and_tree('tree')
0.14.11 by Aaron Bentley
Fix re-versioning
188
        tree.lock_write()
189
        self.addCleanup(tree.unlock)
0.14.4 by Aaron Bentley
Implement shelving deletion
190
        self.build_tree_contents([('tree/foo/',), ('tree/foo/bar', 'baz')])
191
        tree.add(['foo', 'foo/bar'], ['foo-id', 'bar-id'])
192
        tree.commit('Added file and directory')
0.14.9 by Aaron Bentley
Shelve deleted files properly
193
        tree.unversion(['foo-id', 'bar-id'])
0.14.4 by Aaron Bentley
Implement shelving deletion
194
        os.unlink('tree/foo/bar')
195
        os.rmdir('tree/foo')
0.14.7 by Aaron Bentley
Misc test cleanup
196
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.14.4 by Aaron Bentley
Implement shelving deletion
197
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
198
        self.assertEqual([('delete file', 'bar-id', 'file', 'foo/bar'),
199
                          ('delete file', 'foo-id', 'directory', 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
200
                          sorted(list(creator.iter_shelvable())))
0.14.4 by Aaron Bentley
Implement shelving deletion
201
        creator.shelve_deletion('foo-id')
202
        creator.shelve_deletion('bar-id')
0.14.6 by Aaron Bentley
Fix deletion test
203
        creator.transform()
0.14.11 by Aaron Bentley
Fix re-versioning
204
        self.assertTrue('foo-id' in tree)
205
        self.assertTrue('bar-id' in tree)
0.14.4 by Aaron Bentley
Implement shelving deletion
206
        self.assertFileEqual('baz', 'tree/foo/bar')
207
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
208
    def test_shelve_delete_contents(self):
209
        tree = self.make_branch_and_tree('tree')
210
        self.build_tree(['tree/foo',])
211
        tree.add('foo', 'foo-id')
212
        tree.commit('Added file and directory')
213
        os.unlink('tree/foo')
214
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
215
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
216
        self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
217
                         sorted(list(creator.iter_shelvable())))
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
218
        creator.shelve_deletion('foo-id')
219
        creator.transform()
220
        self.failUnlessExists('tree/foo')
221
0.14.23 by Aaron Bentley
Allow shelving kind change
222
    def test_shelve_change_kind(self):
223
        tree = self.make_branch_and_tree('tree')
224
        self.build_tree_contents([('tree/foo', 'bar')])
225
        tree.add('foo', 'foo-id')
226
        tree.commit('Added file and directory')
227
        os.unlink('tree/foo')
228
        os.mkdir('tree/foo')
229
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
230
        self.addCleanup(creator.finalize)
231
        self.assertEqual([('change kind', 'foo-id', 'file', 'directory',
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
232
                           'foo')], sorted(list(creator.iter_shelvable())))
0.14.23 by Aaron Bentley
Allow shelving kind change
233
        creator.shelve_content_change('foo-id')
234
        creator.transform()
235
        self.assertFileEqual('bar', 'tree/foo')
236
        s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
237
        self.assertEqual('directory',
238
                         creator.shelf_transform._new_contents[s_trans_id])
239
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
240
    def test_shelve_unversion(self):
241
        tree = self.make_branch_and_tree('tree')
242
        self.build_tree(['tree/foo',])
243
        tree.add('foo', 'foo-id')
244
        tree.commit('Added file and directory')
245
        tree.unversion(['foo-id'])
246
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
247
        self.addCleanup(creator.finalize)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
248
        self.assertEqual([('delete file', 'foo-id', 'file', 'foo')],
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
249
                         sorted(list(creator.iter_shelvable())))
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
250
        creator.shelve_deletion('foo-id')
251
        creator.transform()
252
        self.failUnlessExists('tree/foo')
253
0.14.33 by Aaron Bentley
Add explicit test of shelf on-disk format
254
    def test_shelve_serialization(self):
255
        tree = self.make_branch_and_tree('.')
256
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
257
        self.addCleanup(creator.finalize)
0.12.76 by Aaron Bentley
Convert failing tests
258
        shelf_file = open('shelf', 'wb')
259
        self.addCleanup(shelf_file.close)
260
        try:
261
            creator.write_shelf(shelf_file)
262
        finally:
263
            shelf_file.close()
264
        self.assertFileEqual(EMPTY_SHELF, 'shelf')
0.14.33 by Aaron Bentley
Add explicit test of shelf on-disk format
265
0.12.19 by Aaron Bentley
Add support for writing shelves
266
    def test_write_shelf(self):
267
        tree = self.make_branch_and_tree('tree')
268
        self.build_tree(['tree/foo'])
269
        tree.add('foo', 'foo-id')
0.14.7 by Aaron Bentley
Misc test cleanup
270
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
271
        self.addCleanup(creator.finalize)
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
272
        list(creator.iter_shelvable())
0.14.2 by Aaron Bentley
Somewhat clean up shelving
273
        creator.shelve_creation('foo-id')
0.12.29 by Aaron Bentley
Update failing tests
274
        shelf_file = open('shelf', 'wb')
275
        try:
0.12.61 by Aaron Bentley
Stop assigning result of write_shelf
276
            creator.write_shelf(shelf_file)
0.12.29 by Aaron Bentley
Update failing tests
277
        finally:
278
            shelf_file.close()
0.12.19 by Aaron Bentley
Add support for writing shelves
279
        parser = pack.ContainerPushParser()
0.12.29 by Aaron Bentley
Update failing tests
280
        shelf_file = open('shelf', 'rb')
0.12.19 by Aaron Bentley
Add support for writing shelves
281
        try:
282
            parser.accept_bytes(shelf_file.read())
283
        finally:
284
            shelf_file.close()
285
        tt = transform.TransformPreview(tree)
0.14.7 by Aaron Bentley
Misc test cleanup
286
        self.addCleanup(tt.finalize)
0.12.29 by Aaron Bentley
Update failing tests
287
        records = iter(parser.read_pending_records())
288
        #skip revision-id
289
        records.next()
0.15.26 by Aaron Bentley
Merge with prepare-shelf
290
        tt.deserialize(records)
0.12.21 by Aaron Bentley
Add failing test of unshelver
291
3873.2.4 by Benoît Pierre
Add a test: test_shelve_unversioned; check if tree is in a clean state
292
    def test_shelve_unversioned(self):
293
        tree = self.make_branch_and_tree('tree')
294
        self.assertRaises(errors.PathsNotVersionedError,
295
                          shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
296
        # We should be able to lock/unlock the tree if ShelfCreator cleaned
297
        # after itself.
298
        wt = workingtree.WorkingTree.open('tree')
299
        wt.lock_tree_write()
300
        wt.unlock()
301
        # And a second tentative should raise the same error (no
302
        # limbo/pending_deletion leftovers).
303
        self.assertRaises(errors.PathsNotVersionedError,
304
                          shelf.ShelfCreator, tree, tree.basis_tree(), ['foo'])
305
0.12.21 by Aaron Bentley
Add failing test of unshelver
306
307
class TestUnshelver(tests.TestCaseWithTransport):
308
0.15.31 by Aaron Bentley
Remove 'unshelve' method, test make_merger
309
    def test_make_merger(self):
0.12.21 by Aaron Bentley
Add failing test of unshelver
310
        tree = self.make_branch_and_tree('tree')
0.12.30 by Aaron Bentley
Fix test by using non NULL base tree
311
        tree.commit('first commit')
0.12.21 by Aaron Bentley
Add failing test of unshelver
312
        self.build_tree_contents([('tree/foo', 'bar')])
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
313
        tree.lock_write()
314
        self.addCleanup(tree.unlock)
0.12.21 by Aaron Bentley
Add failing test of unshelver
315
        tree.add('foo', 'foo-id')
0.15.5 by Aaron Bentley
Rename to shelf
316
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
317
        self.addCleanup(creator.finalize)
0.12.73 by Aaron Bentley
Merge unshelve into shelf-manager
318
        list(creator.iter_shelvable())
0.12.23 by Aaron Bentley
Fix up unshelve some more
319
        creator.shelve_creation('foo-id')
0.12.29 by Aaron Bentley
Update failing tests
320
        shelf_file = open('shelf-file', 'w+b')
321
        try:
0.12.61 by Aaron Bentley
Stop assigning result of write_shelf
322
            creator.write_shelf(shelf_file)
0.12.29 by Aaron Bentley
Update failing tests
323
            creator.transform()
324
            shelf_file.seek(0)
0.12.34 by Aaron Bentley
merge with unshelve
325
            unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
0.12.66 by Aaron Bentley
Merge with unshelve
326
            unshelver.make_merger().do_merge()
0.12.29 by Aaron Bentley
Update failing tests
327
            self.assertFileEqual('bar', 'tree/foo')
328
        finally:
329
            shelf_file.close()
0.12.26 by Aaron Bentley
Use correct base for shelving
330
0.15.23 by Aaron Bentley
Use correct tree for desrializing transform
331
    def test_unshelve_changed(self):
332
        tree = self.make_branch_and_tree('tree')
333
        tree.lock_write()
334
        self.addCleanup(tree.unlock)
335
        self.build_tree_contents([('tree/foo', 'a\nb\nc\n')])
336
        tree.add('foo', 'foo-id')
337
        tree.commit('first commit')
338
        self.build_tree_contents([('tree/foo', 'a\nb\nd\n')])
339
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
340
        self.addCleanup(creator.finalize)
0.12.73 by Aaron Bentley
Merge unshelve into shelf-manager
341
        list(creator.iter_shelvable())
0.15.23 by Aaron Bentley
Use correct tree for desrializing transform
342
        creator.shelve_lines('foo-id', ['a\n', 'b\n', 'c\n'])
0.12.57 by Aaron Bentley
Update for new Shelf API
343
        shelf_file = open('shelf', 'w+b')
344
        self.addCleanup(shelf_file.close)
345
        creator.write_shelf(shelf_file)
0.15.23 by Aaron Bentley
Use correct tree for desrializing transform
346
        creator.transform()
347
        self.build_tree_contents([('tree/foo', 'z\na\nb\nc\n')])
0.12.57 by Aaron Bentley
Update for new Shelf API
348
        shelf_file.seek(0)
349
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
0.15.31 by Aaron Bentley
Remove 'unshelve' method, test make_merger
350
        unshelver.make_merger().do_merge()
0.15.23 by Aaron Bentley
Use correct tree for desrializing transform
351
        self.assertFileEqual('z\na\nb\nd\n', 'tree/foo')
352
3981.1.1 by Robert Collins
Fix bug 319790 - unshelve of deleted paths failing.
353
    def test_unshelve_deleted(self):
354
        tree = self.make_branch_and_tree('tree')
355
        tree.lock_write()
356
        self.addCleanup(tree.unlock)
357
        self.build_tree_contents([('tree/foo/',), ('tree/foo/bar', 'baz')])
358
        tree.add(['foo', 'foo/bar'], ['foo-id', 'bar-id'])
359
        tree.commit('Added file and directory')
360
        tree.unversion(['foo-id', 'bar-id'])
361
        os.unlink('tree/foo/bar')
362
        os.rmdir('tree/foo')
363
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
364
        list(creator.iter_shelvable())
365
        creator.shelve_deletion('foo-id')
366
        creator.shelve_deletion('bar-id')
367
        shelf_file = open('shelf', 'w+b')
368
        self.addCleanup(shelf_file.close)
369
        creator.write_shelf(shelf_file)
370
        creator.transform()
371
        creator.finalize()
372
        # validate the test setup
373
        self.assertTrue('foo-id' in tree)
374
        self.assertTrue('bar-id' in tree)
375
        self.assertFileEqual('baz', 'tree/foo/bar')
376
        shelf_file.seek(0)
377
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
378
        unshelver.make_merger().do_merge()
379
        self.assertFalse('foo-id' in tree)
380
        self.assertFalse('bar-id' in tree)
381
0.12.26 by Aaron Bentley
Use correct base for shelving
382
    def test_unshelve_base(self):
383
        tree = self.make_branch_and_tree('tree')
384
        tree.lock_write()
385
        self.addCleanup(tree.unlock)
386
        tree.commit('rev1', rev_id='rev1')
0.15.5 by Aaron Bentley
Rename to shelf
387
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
0.12.59 by Aaron Bentley
Fix locking bugs in tests
388
        self.addCleanup(creator.finalize)
0.12.42 by Aaron Bentley
Get shelf from tree
389
        manager = tree.get_shelf_manager()
0.12.29 by Aaron Bentley
Update failing tests
390
        shelf_id, shelf_file = manager.new_shelf()
391
        try:
0.12.61 by Aaron Bentley
Stop assigning result of write_shelf
392
            creator.write_shelf(shelf_file)
0.12.29 by Aaron Bentley
Update failing tests
393
        finally:
394
            shelf_file.close()
0.12.26 by Aaron Bentley
Use correct base for shelving
395
        tree.commit('rev2', rev_id='rev2')
0.12.29 by Aaron Bentley
Update failing tests
396
        shelf_file = manager.read_shelf(1)
0.12.59 by Aaron Bentley
Fix locking bugs in tests
397
        self.addCleanup(shelf_file.close)
398
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
399
        self.addCleanup(unshelver.finalize)
0.12.26 by Aaron Bentley
Use correct base for shelving
400
        self.assertEqual('rev1', unshelver.base_tree.get_revision_id())
0.12.27 by Aaron Bentley
Implement shelf manager
401
0.15.41 by Aaron Bentley
Replace assert with proper error handling
402
    def test_unshelve_serialization(self):
403
        tree = self.make_branch_and_tree('.')
404
        self.build_tree_contents([('shelf', EMPTY_SHELF)])
0.12.76 by Aaron Bentley
Convert failing tests
405
        shelf_file = open('shelf', 'rb')
406
        self.addCleanup(shelf_file.close)
407
        unshelver = shelf.Unshelver.from_tree_and_shelf(tree, shelf_file)
0.15.41 by Aaron Bentley
Replace assert with proper error handling
408
409
    def test_corrupt_shelf(self):
410
        tree = self.make_branch_and_tree('.')
411
        self.build_tree_contents([('shelf', EMPTY_SHELF.replace('metadata',
412
                                                                'foo'))])
0.12.76 by Aaron Bentley
Convert failing tests
413
        shelf_file = open('shelf', 'rb')
414
        self.addCleanup(shelf_file.close)
0.15.41 by Aaron Bentley
Replace assert with proper error handling
415
        e = self.assertRaises(errors.ShelfCorrupt,
416
                              shelf.Unshelver.from_tree_and_shelf, tree,
0.12.76 by Aaron Bentley
Convert failing tests
417
                              shelf_file)
0.15.41 by Aaron Bentley
Replace assert with proper error handling
418
        self.assertEqual('Shelf corrupt.', str(e))
0.12.75 by Aaron Bentley
Merge unshelve into shelf-manager
419
0.12.27 by Aaron Bentley
Implement shelf manager
420
421
class TestShelfManager(tests.TestCaseWithTransport):
422
0.12.42 by Aaron Bentley
Get shelf from tree
423
    def test_get_shelf_manager(self):
0.12.27 by Aaron Bentley
Implement shelf manager
424
        tree = self.make_branch_and_tree('.')
0.12.42 by Aaron Bentley
Get shelf from tree
425
        manager = tree.get_shelf_manager()
0.12.41 by Aaron Bentley
Change shelf to use WT control dir for shelves
426
        self.assertEqual(tree._transport.base + 'shelf/',
0.12.27 by Aaron Bentley
Implement shelf manager
427
                         manager.transport.base)
428
429
    def get_manager(self):
0.12.42 by Aaron Bentley
Get shelf from tree
430
        return self.make_branch_and_tree('.').get_shelf_manager()
0.12.27 by Aaron Bentley
Implement shelf manager
431
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
432
    def test_get_shelf_filename(self):
433
        tree = self.make_branch_and_tree('.')
434
        manager = tree.get_shelf_manager()
435
        self.assertEqual('shelf-1', manager.get_shelf_filename(1))
436
437
    def test_get_shelf_ids(self):
438
        tree = self.make_branch_and_tree('.')
439
        manager = tree.get_shelf_manager()
440
        self.assertEqual([1, 3], manager.get_shelf_ids(
441
                         ['shelf-1', 'shelf-02', 'shelf-3']))
442
0.12.27 by Aaron Bentley
Implement shelf manager
443
    def test_new_shelf(self):
444
        manager = self.get_manager()
445
        shelf_id, shelf_file = manager.new_shelf()
446
        shelf_file.close()
447
        self.assertEqual(1, shelf_id)
448
        shelf_id, shelf_file = manager.new_shelf()
449
        shelf_file.close()
450
        self.assertEqual(2, shelf_id)
451
        manager.delete_shelf(1)
452
        shelf_id, shelf_file = manager.new_shelf()
453
        shelf_file.close()
454
        self.assertEqual(3, shelf_id)
455
456
    def test_active_shelves(self):
457
        manager = self.get_manager()
458
        self.assertEqual([], manager.active_shelves())
459
        shelf_id, shelf_file = manager.new_shelf()
460
        shelf_file.close()
461
        self.assertEqual([1], manager.active_shelves())
462
463
    def test_delete_shelf(self):
464
        manager = self.get_manager()
465
        shelf_id, shelf_file = manager.new_shelf()
466
        shelf_file.close()
467
        self.assertEqual([1], manager.active_shelves())
468
        manager.delete_shelf(1)
469
        self.assertEqual([], manager.active_shelves())
470
471
    def test_last_shelf(self):
472
        manager = self.get_manager()
473
        self.assertIs(None, manager.last_shelf())
474
        shelf_id, shelf_file = manager.new_shelf()
475
        shelf_file.close()
476
        self.assertEqual(1, manager.last_shelf())
477
478
    def test_read_shelf(self):
479
        manager = self.get_manager()
480
        shelf_id, shelf_file = manager.new_shelf()
481
        try:
482
            shelf_file.write('foo')
483
        finally:
484
            shelf_file.close()
485
        shelf_id, shelf_file = manager.new_shelf()
486
        try:
487
            shelf_file.write('bar')
488
        finally:
489
            shelf_file.close()
490
        shelf_file = manager.read_shelf(1)
491
        try:
492
            self.assertEqual('foo', shelf_file.read())
493
        finally:
494
            shelf_file.close()
495
        shelf_file = manager.read_shelf(2)
496
        try:
497
            self.assertEqual('bar', shelf_file.read())
498
        finally:
499
            shelf_file.close()
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
500
0.12.50 by Aaron Bentley
Improve error handling for non-existant shelf-ids
501
    def test_read_non_existant(self):
502
        manager = self.get_manager()
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
503
        e = self.assertRaises(errors.NoSuchShelfId, manager.read_shelf, 1)
0.12.50 by Aaron Bentley
Improve error handling for non-existant shelf-ids
504
        self.assertEqual('No changes are shelved with id "1".', str(e))
505
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
506
    def test_shelve_changes(self):
507
        tree = self.make_branch_and_tree('tree')
0.12.44 by Aaron Bentley
Give manager responsibility for applying transform
508
        tree.commit('no-change commit')
509
        tree.lock_write()
510
        self.addCleanup(tree.unlock)
511
        self.build_tree_contents([('tree/foo', 'bar')])
512
        self.assertFileEqual('bar', 'tree/foo')
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
513
        tree.add('foo', 'foo-id')
514
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
515
        self.addCleanup(creator.finalize)
0.12.74 by Aaron Bentley
Update to use iter_shelvable
516
        list(creator.iter_shelvable())
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
517
        creator.shelve_creation('foo-id')
518
        shelf_manager = tree.get_shelf_manager()
519
        shelf_id = shelf_manager.shelve_changes(creator)
0.12.44 by Aaron Bentley
Give manager responsibility for applying transform
520
        self.failIfExists('tree/foo')
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
521
        unshelver = shelf_manager.get_unshelver(shelf_id)
0.12.67 by Aaron Bentley
Update for new Unshelver API
522
        unshelver.make_merger().do_merge()
0.12.44 by Aaron Bentley
Give manager responsibility for applying transform
523
        self.assertFileEqual('bar', 'tree/foo')
0.16.112 by Aaron Bentley
Add tests
524
525
    def test_get_metadata(self):
526
        tree = self.make_branch_and_tree('.')
527
        creator = shelf.ShelfCreator(tree, tree.basis_tree())
528
        shelf_manager = tree.get_shelf_manager()
529
        shelf_id = shelf_manager.shelve_changes(creator, 'foo')
530
        metadata = shelf_manager.get_metadata(shelf_id)
531
        self.assertEqual('foo', metadata['message'])
532
        self.assertEqual('null:', metadata['revision_id'])