Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / test / test_monkey.py
1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """
5 Tests for L{twisted.python.monkey}.
6 """
7
8 from twisted.trial import unittest
9 from twisted.python.monkey import MonkeyPatcher
10
11
12 class TestObj:
13     def __init__(self):
14         self.foo = 'foo value'
15         self.bar = 'bar value'
16         self.baz = 'baz value'
17
18
19 class MonkeyPatcherTest(unittest.TestCase):
20     """
21     Tests for L{MonkeyPatcher} monkey-patching class.
22     """
23
24     def setUp(self):
25         self.testObject = TestObj()
26         self.originalObject = TestObj()
27         self.monkeyPatcher = MonkeyPatcher()
28
29
30     def test_empty(self):
31         """
32         A monkey patcher without patches shouldn't change a thing.
33         """
34         self.monkeyPatcher.patch()
35
36         # We can't assert that all state is unchanged, but at least we can
37         # check our test object.
38         self.assertEqual(self.originalObject.foo, self.testObject.foo)
39         self.assertEqual(self.originalObject.bar, self.testObject.bar)
40         self.assertEqual(self.originalObject.baz, self.testObject.baz)
41
42
43     def test_constructWithPatches(self):
44         """
45         Constructing a L{MonkeyPatcher} with patches should add all of the
46         given patches to the patch list.
47         """
48         patcher = MonkeyPatcher((self.testObject, 'foo', 'haha'),
49                                 (self.testObject, 'bar', 'hehe'))
50         patcher.patch()
51         self.assertEqual('haha', self.testObject.foo)
52         self.assertEqual('hehe', self.testObject.bar)
53         self.assertEqual(self.originalObject.baz, self.testObject.baz)
54
55
56     def test_patchExisting(self):
57         """
58         Patching an attribute that exists sets it to the value defined in the
59         patch.
60         """
61         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
62         self.monkeyPatcher.patch()
63         self.assertEqual(self.testObject.foo, 'haha')
64
65
66     def test_patchNonExisting(self):
67         """
68         Patching a non-existing attribute fails with an C{AttributeError}.
69         """
70         self.monkeyPatcher.addPatch(self.testObject, 'nowhere',
71                                     'blow up please')
72         self.assertRaises(AttributeError, self.monkeyPatcher.patch)
73
74
75     def test_patchAlreadyPatched(self):
76         """
77         Adding a patch for an object and attribute that already have a patch
78         overrides the existing patch.
79         """
80         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
81         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'BLAH')
82         self.monkeyPatcher.patch()
83         self.assertEqual(self.testObject.foo, 'BLAH')
84         self.monkeyPatcher.restore()
85         self.assertEqual(self.testObject.foo, self.originalObject.foo)
86
87
88     def test_restoreTwiceIsANoOp(self):
89         """
90         Restoring an already-restored monkey patch is a no-op.
91         """
92         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
93         self.monkeyPatcher.patch()
94         self.monkeyPatcher.restore()
95         self.assertEqual(self.testObject.foo, self.originalObject.foo)
96         self.monkeyPatcher.restore()
97         self.assertEqual(self.testObject.foo, self.originalObject.foo)
98
99
100     def test_runWithPatchesDecoration(self):
101         """
102         runWithPatches should run the given callable, passing in all arguments
103         and keyword arguments, and return the return value of the callable.
104         """
105         log = []
106
107         def f(a, b, c=None):
108             log.append((a, b, c))
109             return 'foo'
110
111         result = self.monkeyPatcher.runWithPatches(f, 1, 2, c=10)
112         self.assertEqual('foo', result)
113         self.assertEqual([(1, 2, 10)], log)
114
115
116     def test_repeatedRunWithPatches(self):
117         """
118         We should be able to call the same function with runWithPatches more
119         than once. All patches should apply for each call.
120         """
121         def f():
122             return (self.testObject.foo, self.testObject.bar,
123                     self.testObject.baz)
124
125         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
126         result = self.monkeyPatcher.runWithPatches(f)
127         self.assertEqual(
128             ('haha', self.originalObject.bar, self.originalObject.baz), result)
129         result = self.monkeyPatcher.runWithPatches(f)
130         self.assertEqual(
131             ('haha', self.originalObject.bar, self.originalObject.baz),
132             result)
133
134
135     def test_runWithPatchesRestores(self):
136         """
137         C{runWithPatches} should restore the original values after the function
138         has executed.
139         """
140         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
141         self.assertEqual(self.originalObject.foo, self.testObject.foo)
142         self.monkeyPatcher.runWithPatches(lambda: None)
143         self.assertEqual(self.originalObject.foo, self.testObject.foo)
144
145
146     def test_runWithPatchesRestoresOnException(self):
147         """
148         Test runWithPatches restores the original values even when the function
149         raises an exception.
150         """
151         def _():
152             self.assertEqual(self.testObject.foo, 'haha')
153             self.assertEqual(self.testObject.bar, 'blahblah')
154             raise RuntimeError, "Something went wrong!"
155
156         self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
157         self.monkeyPatcher.addPatch(self.testObject, 'bar', 'blahblah')
158
159         self.assertRaises(RuntimeError, self.monkeyPatcher.runWithPatches, _)
160         self.assertEqual(self.testObject.foo, self.originalObject.foo)
161         self.assertEqual(self.testObject.bar, self.originalObject.bar)