1from unittest import TestCase
2
3from testfixtures import Replacer, ShouldRaise
4
5
6class TestReplacer(TestCase):
7
8    def test_function(self):
9        from testfixtures.tests import sample1
10        assert sample1.z() == 'original z'
11
12        def test_z():
13          return 'replacement z'
14
15        r = Replacer()
16        r.replace('testfixtures.tests.sample1.z',test_z)
17
18        assert sample1.z() == 'replacement z'
19
20        r.restore()
21
22        assert sample1.z() == 'original z'
23
24    def test_class(self):
25        from testfixtures.tests import sample1
26        x = sample1.X()
27        assert x.__class__.__name__ == 'X'
28
29        class XReplacement(sample1.X): pass
30
31        r = Replacer()
32        r.replace('testfixtures.tests.sample1.X', XReplacement)
33
34        x = sample1.X()
35        assert x.__class__.__name__ == 'XReplacement'
36        assert sample1.X().y() == 'original y'
37
38        r.restore()
39
40        x = sample1.X()
41        assert x.__class__.__name__ == 'X'
42
43    def test_method(self):
44        from testfixtures.tests import sample1
45        assert sample1.X().y() == 'original y'
46
47        def test_y(self):
48          return 'replacement y'
49
50        r = Replacer()
51        r.replace('testfixtures.tests.sample1.X.y',test_y)
52
53        assert sample1.X().y()[:38] == 'replacement y'
54
55        r.restore()
56
57        assert sample1.X().y() == 'original y'
58
59    def test_class_method(self):
60        from testfixtures.tests import sample1
61        c = sample1.X
62        assert sample1.X.aMethod() is c
63
64        def rMethod(cls):
65          return cls, 1
66
67        r = Replacer()
68        r.replace('testfixtures.tests.sample1.X.aMethod',rMethod)
69
70        sample1.X.aMethod()
71        assert sample1.X.aMethod() == (c, 1)
72
73        r.restore()
74
75        sample1.X.aMethod()
76        assert sample1.X.aMethod() is c
77
78    def test_multiple_replace(self):
79        from testfixtures.tests import sample1
80        assert sample1.z() == 'original z'
81        assert sample1.X().y() == 'original y'
82
83        def test_y(self):
84          return self.__class__.__name__
85        def test_z():
86          return 'replacement z'
87
88        r = Replacer()
89        r.replace('testfixtures.tests.sample1.z',test_z)
90        r.replace('testfixtures.tests.sample1.X.y',test_y)
91
92        assert sample1.z() == 'replacement z'
93        assert sample1.X().y() == 'X'
94
95        r.restore()
96
97        assert sample1.z() == 'original z'
98        assert sample1.X().y() == 'original y'
99
100    def test_gotcha(self):
101        # Just because you replace an object in one context:
102
103        from testfixtures.tests import sample1
104        from testfixtures.tests import sample2
105        assert sample1.z() == 'original z'
106
107        def test_z():
108          return 'replacement z'
109
110        r = Replacer()
111        r.replace('testfixtures.tests.sample1.z',test_z)
112
113        assert sample1.z() == 'replacement z'
114
115        # Doesn't meant that it's replaced in all contexts:
116
117        assert sample2.z() == 'original z'
118
119        r.restore()
120
121    def test_remove_called_twice(self):
122        from testfixtures.tests import sample1
123
124        def test_z(): pass
125
126        r = Replacer()
127        r.replace('testfixtures.tests.sample1.z',test_z)
128
129        r.restore()
130        assert sample1.z() == 'original z'
131
132        r.restore()
133        assert sample1.z() == 'original z'
134
135    def test_with_statement(self):
136        from testfixtures.tests import sample1
137        assert sample1.z() == 'original z'
138
139        def test_z():
140          return 'replacement z'
141
142        with Replacer() as r:
143            r.replace('testfixtures.tests.sample1.z',test_z)
144            assert sample1.z() == 'replacement z'
145
146        assert sample1.z() == 'original z'
147
148    def test_not_there(self):
149        def test_bad(): pass
150
151        with Replacer() as r:
152            with ShouldRaise(AttributeError("Original 'bad' not found")):
153                r.replace('testfixtures.tests.sample1.bad', test_bad)
154