1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
23
23
from bzrlib.tests import TestCase
26
class SampleUnlockError(Exception):
30
def create_decorator_sample(style, unlock_error=None):
26
def create_decorator_sample(style, except_in_unlock=False):
31
27
"""Create a DecoratorSample object, using specific lock operators.
33
29
:param style: The type of lock decorators to use (fast/pretty/None)
34
:param unlock_error: If specified, an error to raise from unlock.
30
:param except_in_unlock: If True, raise an exception during unlock
35
31
:return: An instantiated DecoratorSample object.
62
58
def lock_write(self):
63
59
self.actions.append('lock_write')
65
@decorators.only_raises(SampleUnlockError)
68
63
self.actions.append('unlock_fail')
64
raise KeyError('during unlock')
71
66
self.actions.append('unlock')
125
120
def test_read_lock_raises_original_error(self):
126
121
sam = create_decorator_sample(self._decorator_style,
127
unlock_error=SampleUnlockError())
122
except_in_unlock=True)
128
123
self.assertRaises(TypeError, sam.fail_during_read)
129
124
self.assertEqual(['lock_read', 'fail_during_read', 'unlock_fail'],
132
127
def test_write_lock_raises_original_error(self):
133
128
sam = create_decorator_sample(self._decorator_style,
134
unlock_error=SampleUnlockError())
129
except_in_unlock=True)
135
130
self.assertRaises(TypeError, sam.fail_during_write)
136
131
self.assertEqual(['lock_write', 'fail_during_write', 'unlock_fail'],
139
134
def test_read_lock_raises_unlock_error(self):
140
135
sam = create_decorator_sample(self._decorator_style,
141
unlock_error=SampleUnlockError())
142
self.assertRaises(SampleUnlockError, sam.frob)
136
except_in_unlock=True)
137
self.assertRaises(KeyError, sam.frob)
143
138
self.assertEqual(['lock_read', 'frob', 'unlock_fail'], sam.actions)
145
140
def test_write_lock_raises_unlock_error(self):
146
141
sam = create_decorator_sample(self._decorator_style,
147
unlock_error=SampleUnlockError())
148
self.assertRaises(SampleUnlockError, sam.bank, 'bar', biz='bing')
142
except_in_unlock=True)
143
self.assertRaises(KeyError, sam.bank, 'bar', biz='bing')
149
144
self.assertEqual(['lock_write', ('bank', 'bar', 'bing'),
150
145
'unlock_fail'], sam.actions)
167
162
"""@needs_read_lock exposes underlying name and doc."""
168
163
sam = create_decorator_sample(None)
169
164
self.assertEqual('frob', sam.frob.__name__)
170
self.assertDocstring('Frob the sample object', sam.frob)
165
self.assertEqual('Frob the sample object', sam.frob.__doc__)
172
167
def test_write_lock_passthrough(self):
173
168
"""@needs_write_lock exposes underlying name and doc."""
174
169
sam = create_decorator_sample(None)
175
170
self.assertEqual('bank', sam.bank.__name__)
176
self.assertDocstring('Bank the sample, but using bar and biz.',
171
self.assertEqual('Bank the sample, but using bar and biz.',
179
174
def test_argument_passthrough(self):
180
175
"""Test that arguments get passed around properly."""
208
203
my_function.func_code.co_name)
209
204
self.assertEqual('(foo, bar, baz=None, biz=1)',
210
205
self.get_formatted_args(my_function))
211
self.assertDocstring(
212
'Just a function that supplies several arguments.', my_function)
206
self.assertEqual('Just a function that supplies several arguments.',
207
inspect.getdoc(my_function))
214
209
def test__fast_needs_read_lock(self):
215
210
"""Test the output of _fast_needs_read_lock."""
222
217
self.assertEqual('read_locked', my_function.func_code.co_name)
223
218
self.assertEqual('(self, *args, **kwargs)',
224
219
self.get_formatted_args(my_function))
225
self.assertDocstring(
226
'Just a function that supplies several arguments.', my_function)
220
self.assertEqual('Just a function that supplies several arguments.',
221
inspect.getdoc(my_function))
228
223
def test__pretty_needs_write_lock(self):
229
224
"""Test that _pretty_needs_write_lock generates a nice wrapper."""
237
232
my_function.func_code.co_name)
238
233
self.assertEqual('(foo, bar, baz=None, biz=1)',
239
234
self.get_formatted_args(my_function))
240
self.assertDocstring(
241
'Just a function that supplies several arguments.', my_function)
235
self.assertEqual('Just a function that supplies several arguments.',
236
inspect.getdoc(my_function))
243
238
def test__fast_needs_write_lock(self):
244
239
"""Test the output of _fast_needs_write_lock."""
251
246
self.assertEqual('write_locked', my_function.func_code.co_name)
252
247
self.assertEqual('(self, *args, **kwargs)',
253
248
self.get_formatted_args(my_function))
254
self.assertDocstring(
255
'Just a function that supplies several arguments.', my_function)
249
self.assertEqual('Just a function that supplies several arguments.',
250
inspect.getdoc(my_function))
257
252
def test_use_decorators(self):
258
253
"""Test that you can switch the type of the decorators."""
282
277
decorators.needs_read_lock = cur_read
283
278
decorators.needs_write_lock = cur_write
286
class TestOnlyRaisesDecorator(TestCase):
288
def raise_ZeroDivisionError(self):
291
def test_raises_approved_error(self):
292
decorator = decorators.only_raises(ZeroDivisionError)
293
decorated_meth = decorator(self.raise_ZeroDivisionError)
294
self.assertRaises(ZeroDivisionError, decorated_meth)
296
def test_quietly_logs_unapproved_errors(self):
297
decorator = decorators.only_raises(IOError)
298
decorated_meth = decorator(self.raise_ZeroDivisionError)
299
self.assertLogsError(ZeroDivisionError, decorated_meth)