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