~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_decorators.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
"""Tests for decorator functions"""
19
19
 
20
 
from bzrlib.decorators import needs_read_lock
 
20
import inspect
 
21
 
 
22
from bzrlib import decorators
 
23
from bzrlib.decorators import needs_read_lock, needs_write_lock
21
24
from bzrlib.tests import TestCase
22
25
 
23
26
 
24
27
class DecoratorSample(object):
25
28
    """Sample class that uses decorators.
26
29
 
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.
29
31
    """
30
32
 
 
33
    def __init__(self):
 
34
        self.actions = []
 
35
 
 
36
    def lock_read(self):
 
37
        self.actions.append('lock_read')
 
38
 
 
39
    def lock_write(self):
 
40
        self.actions.append('lock_write')
 
41
 
 
42
    def unlock(self):
 
43
        self.actions.append('unlock')
 
44
 
31
45
    @needs_read_lock
32
46
    def frob(self):
33
47
        """Frob the sample object"""
 
48
        self.actions.append('frob')
 
49
 
 
50
    @needs_write_lock
 
51
    def bank(self, bar, biz=None):
 
52
        """Bank the sample, but using bar and biz."""
 
53
        self.actions.append(('bank', bar, biz))
34
54
 
35
55
 
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__)
 
64
 
 
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.',
 
70
                         sam.bank.__doc__)
 
71
 
 
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',
 
77
                          ('bank', '1', '2'),
 
78
                          'unlock',
 
79
                         ], sam.actions)
 
80
 
 
81
 
 
82
class TestPrettyDecorators(TestCase):
 
83
    """Test that pretty decorators generate nice looking wrappers."""
 
84
 
 
85
    def get_formatted_args(self, func):
 
86
        """Return a nicely formatted string for the arguments to a function.
 
87
 
 
88
        This generates something like "(foo, bar=None)".
 
89
        """
 
90
        return inspect.formatargspec(*inspect.getargspec(func))
 
91
 
 
92
    def test__pretty_needs_read_lock(self):
 
93
        """Test that _pretty_needs_read_lock generates a nice wrapper."""
 
94
 
 
95
        @decorators._pretty_needs_read_lock
 
96
        def my_function(foo, bar, baz=None, biz=1):
 
97
            """Just a function that supplies several arguments."""
 
98
 
 
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))
 
106
 
 
107
    def test__fast_needs_read_lock(self):
 
108
        """Test the output of _fast_needs_read_lock."""
 
109
 
 
110
        @decorators._fast_needs_read_lock
 
111
        def my_function(foo, bar, baz=None, biz=1):
 
112
            """Just a function that supplies several arguments."""
 
113
 
 
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))
 
120
 
 
121
    def test__pretty_needs_write_lock(self):
 
122
        """Test that _pretty_needs_write_lock generates a nice wrapper."""
 
123
 
 
124
        @decorators._pretty_needs_write_lock
 
125
        def my_function(foo, bar, baz=None, biz=1):
 
126
            """Just a function that supplies several arguments."""
 
127
 
 
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))
 
135
 
 
136
    def test__fast_needs_write_lock(self):
 
137
        """Test the output of _fast_needs_write_lock."""
 
138
 
 
139
        @decorators._fast_needs_write_lock
 
140
        def my_function(foo, bar, baz=None, biz=1):
 
141
            """Just a function that supplies several arguments."""
 
142
 
 
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))
 
149
 
 
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
 
154
        try:
 
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)
 
160
 
 
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)
 
166
 
 
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)
 
174
        finally:
 
175
            decorators.needs_read_lock = cur_read
 
176
            decorators.needs_write_lock = cur_write