18
18
"""Tests for decorator functions"""
20
from bzrlib.decorators import needs_read_lock
22
from bzrlib import decorators
23
from bzrlib.decorators import needs_read_lock, needs_write_lock
21
24
from bzrlib.tests import TestCase
24
27
class DecoratorSample(object):
25
28
"""Sample class that uses decorators.
27
This doesn't actually work because the class doesn't have the
28
requiste lock_read()/unlock() methods.
30
Log when requests go through lock_read()/unlock() or lock_write()/unlock.
37
self.actions.append('lock_read')
40
self.actions.append('lock_write')
43
self.actions.append('unlock')
33
47
"""Frob the sample object"""
48
self.actions.append('frob')
51
def bank(self, bar, biz=None):
52
"""Bank the sample, but using bar and biz."""
53
self.actions.append(('bank', bar, biz))
36
56
class TestDecoratorDocs(TestCase):
39
59
def test_read_lock_passthrough(self):
40
60
"""@needs_read_lock exposes underlying name and doc."""
41
61
sam = DecoratorSample()
42
self.assertEqual(sam.frob.__name__, 'frob')
43
self.assertEqual(sam.frob.__doc__,
44
'Frob the sample object')
62
self.assertEqual('frob', sam.frob.__name__)
63
self.assertEqual('Frob the sample object', sam.frob.__doc__)
65
def test_write_lock_passthrough(self):
66
"""@needs_write_lock exposes underlying name and doc."""
67
sam = DecoratorSample()
68
self.assertEqual('bank', sam.bank.__name__)
69
self.assertEqual('Bank the sample, but using bar and biz.',
72
def test_argument_passthrough(self):
73
"""Test that arguments get passed around properly."""
74
sam = DecoratorSample()
75
sam.bank('1', biz='2')
76
self.assertEqual(['lock_write',
82
class TestPrettyDecorators(TestCase):
83
"""Test that pretty decorators generate nice looking wrappers."""
85
def get_formatted_args(self, func):
86
"""Return a nicely formatted string for the arguments to a function.
88
This generates something like "(foo, bar=None)".
90
return inspect.formatargspec(*inspect.getargspec(func))
92
def test__pretty_needs_read_lock(self):
93
"""Test that _pretty_needs_read_lock generates a nice wrapper."""
95
@decorators._pretty_needs_read_lock
96
def my_function(foo, bar, baz=None, biz=1):
97
"""Just a function that supplies several arguments."""
99
self.assertEqual('my_function', my_function.__name__)
100
self.assertEqual('my_function_read_locked',
101
my_function.func_code.co_name)
102
self.assertEqual('(foo, bar, baz=None, biz=1)',
103
self.get_formatted_args(my_function))
104
self.assertEqual('Just a function that supplies several arguments.',
105
inspect.getdoc(my_function))
107
def test__fast_needs_read_lock(self):
108
"""Test the output of _fast_needs_read_lock."""
110
@decorators._fast_needs_read_lock
111
def my_function(foo, bar, baz=None, biz=1):
112
"""Just a function that supplies several arguments."""
114
self.assertEqual('my_function', my_function.__name__)
115
self.assertEqual('read_locked', my_function.func_code.co_name)
116
self.assertEqual('(self, *args, **kwargs)',
117
self.get_formatted_args(my_function))
118
self.assertEqual('Just a function that supplies several arguments.',
119
inspect.getdoc(my_function))
121
def test__pretty_needs_write_lock(self):
122
"""Test that _pretty_needs_write_lock generates a nice wrapper."""
124
@decorators._pretty_needs_write_lock
125
def my_function(foo, bar, baz=None, biz=1):
126
"""Just a function that supplies several arguments."""
128
self.assertEqual('my_function', my_function.__name__)
129
self.assertEqual('my_function_write_locked',
130
my_function.func_code.co_name)
131
self.assertEqual('(foo, bar, baz=None, biz=1)',
132
self.get_formatted_args(my_function))
133
self.assertEqual('Just a function that supplies several arguments.',
134
inspect.getdoc(my_function))
136
def test__fast_needs_write_lock(self):
137
"""Test the output of _fast_needs_write_lock."""
139
@decorators._fast_needs_write_lock
140
def my_function(foo, bar, baz=None, biz=1):
141
"""Just a function that supplies several arguments."""
143
self.assertEqual('my_function', my_function.__name__)
144
self.assertEqual('write_locked', my_function.func_code.co_name)
145
self.assertEqual('(self, *args, **kwargs)',
146
self.get_formatted_args(my_function))
147
self.assertEqual('Just a function that supplies several arguments.',
148
inspect.getdoc(my_function))
150
def test_use_decorators(self):
151
"""Test that you can switch the type of the decorators."""
152
cur_read = decorators.needs_read_lock
153
cur_write = decorators.needs_write_lock
155
decorators.use_fast_decorators()
156
self.assertIs(decorators._fast_needs_read_lock,
157
decorators.needs_read_lock)
158
self.assertIs(decorators._fast_needs_write_lock,
159
decorators.needs_write_lock)
161
decorators.use_pretty_decorators()
162
self.assertIs(decorators._pretty_needs_read_lock,
163
decorators.needs_read_lock)
164
self.assertIs(decorators._pretty_needs_write_lock,
165
decorators.needs_write_lock)
167
# One more switch to make sure it wasn't just good luck that the
168
# functions pointed to the correct version
169
decorators.use_fast_decorators()
170
self.assertIs(decorators._fast_needs_read_lock,
171
decorators.needs_read_lock)
172
self.assertIs(decorators._fast_needs_write_lock,
173
decorators.needs_write_lock)
175
decorators.needs_read_lock = cur_read
176
decorators.needs_write_lock = cur_write