~bzr-pqm/bzr/bzr.dev

2297.1.2 by Martin Pool
Cleanup imports
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
2
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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.
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
7
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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.
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
12
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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
16
17
"""Tests for the Branch facility that are not interface  tests.
18
1534.4.39 by Robert Collins
Basic BzrDir support.
19
For interface tests see tests/branch_implementations/*.py.
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
20
21
For concrete class tests see this file, and for meta-branch tests
22
also see this file.
23
"""
24
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
25
from StringIO import StringIO
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
26
2230.3.3 by Aaron Bentley
Add more config testing
27
from bzrlib import (
28
    branch as _mod_branch,
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
29
    bzrdir,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
30
    config,
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
31
    errors,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
32
    trace,
2230.3.3 by Aaron Bentley
Add more config testing
33
    urlutils,
34
    )
2297.1.2 by Martin Pool
Cleanup imports
35
from bzrlib.branch import (
36
    Branch,
37
    BranchHooks,
38
    BranchFormat,
39
    BranchReferenceFormat,
40
    BzrBranch5,
41
    BzrBranchFormat5,
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
42
    BzrBranchFormat6,
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
43
    PullResult,
2297.1.2 by Martin Pool
Cleanup imports
44
    )
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
45
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
46
                           BzrDir, BzrDirFormat)
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
47
from bzrlib.errors import (NotBranchError,
48
                           UnknownFormatError,
2245.1.3 by Robert Collins
Add install_hook to the BranchHooks class as the official means for installing a hook.
49
                           UnknownHook,
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
50
                           UnsupportedFormatError,
51
                           )
52
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
53
from bzrlib.tests import TestCase, TestCaseWithTransport
1534.4.4 by Robert Collins
Make BzrBranchFormat.find_format take a transport not a url for efficiency.
54
from bzrlib.transport import get_transport
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
55
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
56
class TestDefaultFormat(TestCase):
57
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
58
    def test_default_format(self):
59
        # update this if you change the default branch format
60
        self.assertIsInstance(BranchFormat.get_default_format(),
61
                BzrBranchFormat6)
62
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
63
    def test_default_format_is_same_as_bzrdir_default(self):
64
        # XXX: it might be nice if there was only one place the default was
65
        # set, but at the moment that's not true -- mbp 20070814 -- 
2696.3.8 by Martin Pool
doc
66
        # https://bugs.launchpad.net/bzr/+bug/132376
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
67
        self.assertEqual(BranchFormat.get_default_format(),
68
                BzrDirFormat.get_default_format().get_branch_format())
69
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
70
    def test_get_set_default_format(self):
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
71
        # set the format and then set it back again
2297.1.2 by Martin Pool
Cleanup imports
72
        old_format = BranchFormat.get_default_format()
73
        BranchFormat.set_default_format(SampleBranchFormat())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
74
        try:
75
            # the default branch format is used by the meta dir format
76
            # which is not the default bzrdir format at this point
1685.1.42 by John Arbash Meinel
A couple more fixes to make sure memory:/// works correctly.
77
            dir = BzrDirMetaFormat1().initialize('memory:///')
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
78
            result = dir.create_branch()
79
            self.assertEqual(result, 'A branch')
80
        finally:
2297.1.2 by Martin Pool
Cleanup imports
81
            BranchFormat.set_default_format(old_format)
82
        self.assertEqual(old_format, BranchFormat.get_default_format())
1508.1.25 by Robert Collins
Update per review comments.
83
84
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
85
class TestBranchFormat5(TestCaseWithTransport):
86
    """Tests specific to branch format 5"""
87
88
    def test_branch_format_5_uses_lockdir(self):
89
        url = self.get_url()
1553.5.72 by Martin Pool
Clean up test for Branch5 lockdirs
90
        bzrdir = BzrDirMetaFormat1().initialize(url)
91
        bzrdir.create_repository()
92
        branch = bzrdir.create_branch()
93
        t = self.get_transport()
94
        self.log("branch instance is %r" % branch)
95
        self.assert_(isinstance(branch, BzrBranch5))
96
        self.assertIsDirectory('.', t)
97
        self.assertIsDirectory('.bzr/branch', t)
98
        self.assertIsDirectory('.bzr/branch/lock', t)
1553.5.73 by Martin Pool
Additional test that Branch5 uses lockdir properly
99
        branch.lock_write()
1658.1.5 by Martin Pool
Release more locks taken during test suite
100
        try:
101
            self.assertIsDirectory('.bzr/branch/lock/held', t)
102
        finally:
103
            branch.unlock()
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
104
2230.3.3 by Aaron Bentley
Add more config testing
105
    def test_set_push_location(self):
106
        from bzrlib.config import (locations_config_filename,
107
                                   ensure_config_dir_exists)
108
        ensure_config_dir_exists()
109
        fn = locations_config_filename()
2839.3.1 by Alexander Belchenko
provide non-empty locations.conf for test_branch.TestBranchFormat5.test_set_push_location
110
        # write correct newlines to locations.conf
111
        # by default ConfigObj uses native line-endings for new files
112
        # but uses already existing line-endings if file is not empty
113
        f = open(fn, 'wb')
114
        try:
115
            f.write('# comment\n')
116
        finally:
117
            f.close()
118
2230.3.3 by Aaron Bentley
Add more config testing
119
        branch = self.make_branch('.', format='knit')
120
        branch.set_push_location('foo')
121
        local_path = urlutils.local_path_from_url(branch.base[:-1])
2839.3.1 by Alexander Belchenko
provide non-empty locations.conf for test_branch.TestBranchFormat5.test_set_push_location
122
        self.assertFileEqual("# comment\n"
123
                             "[%s]\n"
2230.3.3 by Aaron Bentley
Add more config testing
124
                             "push_location = foo\n"
125
                             "push_location:policy = norecurse" % local_path,
126
                             fn)
127
2230.3.12 by Aaron Bentley
Clean up trailing whitespace
128
    # TODO RBC 20051029 test getting a push location from a branch in a
2230.3.3 by Aaron Bentley
Add more config testing
129
    # recursive section - that is, it appends the branch name.
130
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
131
2297.1.2 by Martin Pool
Cleanup imports
132
class SampleBranchFormat(BranchFormat):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
133
    """A sample format
134
135
    this format is initializable, unsupported to aid in testing the 
136
    open and open_downlevel routines.
137
    """
138
139
    def get_format_string(self):
140
        """See BzrBranchFormat.get_format_string()."""
141
        return "Sample branch format."
142
143
    def initialize(self, a_bzrdir):
144
        """Format 4 branches cannot be created."""
145
        t = a_bzrdir.get_branch_transport(self)
1955.3.9 by John Arbash Meinel
Find more occurrances of put() and replace with put_file or put_bytes
146
        t.put_bytes('format', self.get_format_string())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
147
        return 'A branch'
148
149
    def is_supported(self):
150
        return False
151
152
    def open(self, transport, _found=False):
153
        return "opened branch."
154
155
156
class TestBzrBranchFormat(TestCaseWithTransport):
157
    """Tests for the BzrBranchFormat facility."""
158
159
    def test_find_format(self):
160
        # is the right format object found for a branch?
161
        # create a branch with a few known format objects.
162
        # this is not quite the same as 
163
        self.build_tree(["foo/", "bar/"])
164
        def check_format(format, url):
165
            dir = format._matchingbzrdir.initialize(url)
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
166
            dir.create_repository()
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
167
            format.initialize(dir)
2297.1.2 by Martin Pool
Cleanup imports
168
            found_format = BranchFormat.find_format(dir)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
169
            self.failUnless(isinstance(found_format, format.__class__))
2297.1.2 by Martin Pool
Cleanup imports
170
        check_format(BzrBranchFormat5(), "bar")
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
171
        
172
    def test_find_format_not_branch(self):
173
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
174
        self.assertRaises(NotBranchError,
2297.1.2 by Martin Pool
Cleanup imports
175
                          BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
176
                          dir)
177
178
    def test_find_format_unknown_format(self):
179
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
180
        SampleBranchFormat().initialize(dir)
181
        self.assertRaises(UnknownFormatError,
2297.1.2 by Martin Pool
Cleanup imports
182
                          BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
183
                          dir)
184
185
    def test_register_unregister_format(self):
186
        format = SampleBranchFormat()
187
        # make a control dir
188
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
189
        # make a branch
190
        format.initialize(dir)
191
        # register a format for it.
2297.1.2 by Martin Pool
Cleanup imports
192
        BranchFormat.register_format(format)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
193
        # which branch.Open will refuse (not supported)
2297.1.2 by Martin Pool
Cleanup imports
194
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
195
        self.make_branch_and_tree('foo')
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
196
        # but open_downlevel will work
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
197
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
198
        # unregister the format
2297.1.2 by Martin Pool
Cleanup imports
199
        BranchFormat.unregister_format(format)
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
200
        self.make_branch_and_tree('bar')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
201
202
2230.3.1 by Aaron Bentley
Get branch6 creation working
203
class TestBranch6(TestCaseWithTransport):
204
205
    def test_creation(self):
206
        format = BzrDirMetaFormat1()
2230.3.55 by Aaron Bentley
Updates from review
207
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
2230.3.1 by Aaron Bentley
Get branch6 creation working
208
        branch = self.make_branch('a', format=format)
209
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
210
        branch = self.make_branch('b', format='dirstate-tags')
2230.3.1 by Aaron Bentley
Get branch6 creation working
211
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
212
        branch = _mod_branch.Branch.open('a')
213
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
214
215
    def test_layout(self):
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
216
        branch = self.make_branch('a', format='dirstate-tags')
2230.3.1 by Aaron Bentley
Get branch6 creation working
217
        self.failUnlessExists('a/.bzr/branch/last-revision')
218
        self.failIfExists('a/.bzr/branch/revision-history')
219
2230.3.3 by Aaron Bentley
Add more config testing
220
    def test_config(self):
221
        """Ensure that all configuration data is stored in the branch"""
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
222
        branch = self.make_branch('a', format='dirstate-tags')
2230.3.3 by Aaron Bentley
Add more config testing
223
        branch.set_parent('http://bazaar-vcs.org')
224
        self.failIfExists('a/.bzr/branch/parent')
225
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
226
        branch.set_push_location('sftp://bazaar-vcs.org')
227
        config = branch.get_config()._get_branch_data_config()
2230.3.12 by Aaron Bentley
Clean up trailing whitespace
228
        self.assertEqual('sftp://bazaar-vcs.org',
2230.3.3 by Aaron Bentley
Add more config testing
229
                         config.get_user_option('push_location'))
230
        branch.set_bound_location('ftp://bazaar-vcs.org')
231
        self.failIfExists('a/.bzr/branch/bound')
232
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
233
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
234
    def test_set_revision_history(self):
235
        tree = self.make_branch_and_memory_tree('.',
1551.13.1 by Aaron Bentley
Introduce dirstate-tags format
236
            format='dirstate-tags')
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
237
        tree.lock_write()
238
        try:
239
            tree.add('.')
240
            tree.commit('foo', rev_id='foo')
241
            tree.commit('bar', rev_id='bar')
242
            tree.branch.set_revision_history(['foo', 'bar'])
243
            tree.branch.set_revision_history(['foo'])
244
            self.assertRaises(errors.NotLefthandHistory,
245
                              tree.branch.set_revision_history, ['bar'])
246
        finally:
247
            tree.unlock()
248
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
249
    def do_checkout_test(self, lightweight=False):
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
250
        tree = self.make_branch_and_tree('source', format='dirstate-with-subtree')
251
        subtree = self.make_branch_and_tree('source/subtree',
252
            format='dirstate-with-subtree')
2100.3.25 by Aaron Bentley
add subsubtree to test
253
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
254
            format='dirstate-with-subtree')
2100.3.25 by Aaron Bentley
add subsubtree to test
255
        self.build_tree(['source/subtree/file',
256
                         'source/subtree/subsubtree/file'])
257
        subsubtree.add('file')
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
258
        subtree.add('file')
2100.3.25 by Aaron Bentley
add subsubtree to test
259
        subtree.add_reference(subsubtree)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
260
        tree.add_reference(subtree)
261
        tree.commit('a revision')
2100.3.23 by Aaron Bentley
Nested checkouts kinda work
262
        subtree.commit('a subtree file')
2100.3.25 by Aaron Bentley
add subsubtree to test
263
        subsubtree.commit('a subsubtree file')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
264
        tree.branch.create_checkout('target', lightweight=lightweight)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
265
        self.failUnlessExists('target')
266
        self.failUnlessExists('target/subtree')
267
        self.failUnlessExists('target/subtree/file')
2100.3.25 by Aaron Bentley
add subsubtree to test
268
        self.failUnlessExists('target/subtree/subsubtree/file')
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
269
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
270
        if lightweight:
271
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
272
        else:
273
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
274
275
    def test_checkout_with_references(self):
276
        self.do_checkout_test()
277
278
    def test_light_checkout_with_references(self):
279
        self.do_checkout_test(lightweight=True)
2230.3.51 by Aaron Bentley
Store revno for Branch6, set_last_revision -> set_last_revision_info
280
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
281
    def test_set_push(self):
282
        branch = self.make_branch('source', format='dirstate-tags')
283
        branch.get_config().set_user_option('push_location', 'old',
284
            store=config.STORE_LOCATION)
285
        warnings = []
286
        def warning(*args):
287
            warnings.append(args[0] % args[1:])
288
        _warning = trace.warning
289
        trace.warning = warning
290
        try:
291
            branch.set_push_location('new')
292
        finally:
293
            trace.warning = _warning
294
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
295
                         'locations.conf')
296
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
297
class TestBranchReference(TestCaseWithTransport):
298
    """Tests for the branch reference facility."""
299
300
    def test_create_open_reference(self):
301
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
302
        t = get_transport(self.get_url('.'))
303
        t.mkdir('repo')
304
        dir = bzrdirformat.initialize(self.get_url('repo'))
305
        dir.create_repository()
306
        target_branch = dir.create_branch()
307
        t.mkdir('branch')
308
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
2297.1.2 by Martin Pool
Cleanup imports
309
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
310
        self.assertEqual(made_branch.base, target_branch.base)
311
        opened_branch = branch_dir.open_branch()
312
        self.assertEqual(opened_branch.base, target_branch.base)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
313
314
    def test_get_reference(self):
315
        """For a BranchReference, get_reference should reutrn the location."""
316
        branch = self.make_branch('target')
317
        checkout = branch.create_checkout('checkout', lightweight=True)
318
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
319
        # if the api for create_checkout changes to return different checkout types
320
        # then this file read will fail.
321
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
322
        self.assertEqual(reference_url,
2018.5.97 by Andrew Bennetts
Fix more tests.
323
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
2018.5.45 by Andrew Bennetts
Merge from bzr.dev
324
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
325
326
class TestHooks(TestCase):
327
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
328
    def test_constructor(self):
329
        """Check that creating a BranchHooks instance has the right defaults."""
2297.1.2 by Martin Pool
Cleanup imports
330
        hooks = BranchHooks()
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
331
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
332
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
333
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
334
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
335
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
336
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
337
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
338
    def test_installed_hooks_are_BranchHooks(self):
339
        """The installed hooks object should be a BranchHooks."""
340
        # the installed hooks are saved in self._preserved_hooks.
2376.3.5 by Robert Collins
Fix Branch hook tests for the new eans of preserving hooks by the test suite.
341
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
2245.1.3 by Robert Collins
Add install_hook to the BranchHooks class as the official means for installing a hook.
342
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
343
344
class TestPullResult(TestCase):
345
346
    def test_pull_result_to_int(self):
347
        # to support old code, the pull result can be used as an int
348
        r = PullResult()
349
        r.old_revno = 10
350
        r.new_revno = 20
351
        # this usage of results is not recommended for new code (because it
352
        # doesn't describe very well what happened), but for api stability
353
        # it's still supported
354
        a = "%d revisions pulled" % r
355
        self.assertEqual(a, "10 revisions pulled")