~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/objspace/std/test/test_multimethod.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from py.test import raises
 
2
 
 
3
from pypy.objspace.std import multimethod
 
4
from pypy.objspace.std.multimethod import FailedToImplement
 
5
 
 
6
 
 
7
class W_Root(object):
 
8
    pass
 
9
 
 
10
class W_IntObject(W_Root):
 
11
    pass
 
12
 
 
13
class W_BoolObject(W_Root):
 
14
    pass
 
15
 
 
16
class W_StringObject(W_Root):
 
17
    pass
 
18
 
 
19
def delegate_b2i(space, w_x):
 
20
    assert isinstance(w_x, W_BoolObject)
 
21
    return W_IntObject()
 
22
 
 
23
def add__Int_Int(space, w_x, w_y):
 
24
    assert space == 'space'
 
25
    assert isinstance(w_x, W_IntObject)
 
26
    assert isinstance(w_y, W_IntObject)
 
27
    return 'fine'
 
28
 
 
29
 
 
30
class TestMultiMethod1:
 
31
    Installer = multimethod.InstallerVersion1
 
32
 
 
33
    def setup_class(cls):
 
34
        cls.prev_installer = multimethod.Installer
 
35
        multimethod.Installer = cls.Installer
 
36
        add = multimethod.MultiMethodTable(2, root_class=W_Root,
 
37
                                           argnames_before=['space'])
 
38
        add.register(add__Int_Int, W_IntObject, W_IntObject)
 
39
        typeorder = {
 
40
            W_IntObject: [(W_IntObject, None), (W_Root, None)],
 
41
            W_BoolObject: [(W_BoolObject, None), (W_IntObject, delegate_b2i),
 
42
                           (W_Root, None)],
 
43
            W_StringObject: [(W_StringObject, None), (W_Root, None)],
 
44
            }
 
45
        cls.typeorder = typeorder
 
46
        cls.add = add
 
47
        cls.add1 = staticmethod(add.install('__add', [typeorder, typeorder]))
 
48
 
 
49
    def teardown_class(cls):
 
50
        multimethod.Installer = cls.prev_installer
 
51
 
 
52
    def test_simple(self):
 
53
        space = 'space'
 
54
        w_x = W_IntObject()
 
55
        w_y = W_IntObject()
 
56
        assert self.add1(space, w_x, w_y) == 'fine'
 
57
 
 
58
    def test_failtoimplement(self):
 
59
        space = 'space'
 
60
        w_x = W_IntObject()
 
61
        w_s = W_StringObject()
 
62
        raises(FailedToImplement, "self.add1(space, w_x, w_s)")
 
63
        raises(FailedToImplement, "self.add1(space, w_s, w_x)")
 
64
 
 
65
    def test_delegate(self):
 
66
        space = 'space'
 
67
        w_x = W_IntObject()
 
68
        w_s = W_StringObject()
 
69
        w_b = W_BoolObject()
 
70
        assert self.add1(space, w_x, w_b) == 'fine'
 
71
        assert self.add1(space, w_b, w_x) == 'fine'
 
72
        assert self.add1(space, w_b, w_b) == 'fine'
 
73
        raises(FailedToImplement, "self.add1(space, w_b, w_s)")
 
74
        raises(FailedToImplement, "self.add1(space, w_s, w_b)")
 
75
 
 
76
    def test_not_baked(self):
 
77
        typeorder = self.typeorder
 
78
        add2 = self.add.install('__add2', [typeorder, typeorder],
 
79
                                baked_perform_call=False)
 
80
        assert add2[0] == ['space', 'arg0', 'arg1']
 
81
        if multimethod.Installer is multimethod.InstallerVersion1:
 
82
            assert add2[1] == 'arg0.__add2(space, arg1)'
 
83
        assert isinstance(add2[2], dict)
 
84
        assert not add2[3]
 
85
 
 
86
    def test_empty(self):
 
87
        add3_installer = multimethod.Installer(self.add, '__add3', [{},{}])
 
88
        assert add3_installer.is_empty()
 
89
        if multimethod.Installer is multimethod.InstallerVersion1:
 
90
            assert len(add3_installer.to_install) == 1
 
91
            assert add3_installer.to_install[0][0] is None
 
92
 
 
93
    def test_empty_direct(self):
 
94
        assert not self.add.install_if_not_empty('__add4', [{},{}])
 
95
 
 
96
    def test_empty_not_baked(self):
 
97
        add5_installer = multimethod.Installer(self.add, '__add5', [{},{}],
 
98
                                               baked_perform_call=False)
 
99
        assert add5_installer.is_empty()
 
100
        if multimethod.Installer is multimethod.InstallerVersion1:
 
101
            assert len(add5_installer.to_install) == 0
 
102
        add5 = add5_installer.install()
 
103
        assert add5[0] == ['space', 'arg0', 'arg1']
 
104
        assert add5[1] == 'raiseFailedToImplement()'
 
105
        assert isinstance(add5[2], dict)
 
106
        assert add5[3]
 
107
 
 
108
    def test_mmdispatcher(self):
 
109
        typeorder = self.typeorder
 
110
        add2 = multimethod.MMDispatcher(self.add, [typeorder, typeorder])
 
111
        space = 'space'
 
112
        w_x = W_IntObject()
 
113
        w_s = W_StringObject()
 
114
        w_b1 = W_BoolObject()
 
115
        w_b2 = W_BoolObject()
 
116
        assert add2(space, w_x, w_b1) == 'fine'
 
117
        assert add2(space, w_b2, w_x) == 'fine'
 
118
        assert add2(space, w_b1, w_b2) == 'fine'
 
119
        raises(FailedToImplement, "add2(space, w_b2, w_s)")
 
120
        raises(FailedToImplement, "add2(space, w_s, w_b1)")
 
121
 
 
122
    def test_all_cases(self):
 
123
        import random
 
124
        space = 'space'
 
125
        w_x = W_IntObject()
 
126
        w_x.expected = [W_IntObject, W_Root]
 
127
        w_s = W_StringObject()
 
128
        w_s.expected = [W_StringObject, W_Root]
 
129
        w_b = W_BoolObject()
 
130
        w_b.expected = [W_BoolObject, W_IntObject, W_Root]
 
131
 
 
132
        def test(indices):
 
133
            sub = multimethod.MultiMethodTable(2, root_class=W_Root,
 
134
                                               argnames_before=['space'])
 
135
            def addimpl(cls1, cls2):
 
136
                token = random.random()
 
137
                def sub__cls1_cls2(space, w_x, w_y):
 
138
                    assert space == 'space'
 
139
                    assert isinstance(w_x, cls1)
 
140
                    assert isinstance(w_y, cls2)
 
141
                    return token
 
142
                sub.register(sub__cls1_cls2, cls1, cls2)
 
143
                return token
 
144
 
 
145
            def check(w1, w2):
 
146
                try:
 
147
                    res = sub1(space, w1, w2)
 
148
                except FailedToImplement:
 
149
                    res = FailedToImplement
 
150
                for cls1 in w1.expected:
 
151
                    for cls2 in w2.expected:
 
152
                        if (cls1, cls2) in expected:
 
153
                            assert res == expected[cls1, cls2]
 
154
                            return
 
155
                else:
 
156
                    assert res is FailedToImplement
 
157
 
 
158
            random.shuffle(indices)
 
159
            expected = {}
 
160
            for index in indices:
 
161
                cls1, cls2 = choices[index]
 
162
                token = addimpl(cls1, cls2)
 
163
                expected[cls1, cls2] = token
 
164
 
 
165
            typeorder = self.typeorder
 
166
            sub1 = sub.install('__sub', [typeorder, typeorder])
 
167
            for w1 in [w_x, w_s, w_b]:
 
168
                for w2 in [w_x, w_s, w_b]:
 
169
                    check(w1, w2)
 
170
 
 
171
        classes = [W_Root, W_StringObject, W_IntObject, W_BoolObject]
 
172
        choices = [(cls1, cls2) for cls1 in classes
 
173
                                for cls2 in classes]
 
174
        # each choice is a pair of classes which can be implemented or
 
175
        # not by the multimethod 'sub'.  Test all combinations that
 
176
        # involve at most three implemented choices.
 
177
        for i in range(len(choices)):
 
178
            test([i])
 
179
            for j in range(i+1, len(choices)):
 
180
                test([i, j])
 
181
                for k in range(j+1, len(choices)):
 
182
                    test([i, j, k])
 
183
                    #for l in range(k+1, len(choices)):  -- for a 4th choice
 
184
                    #    test([i, j, k, l])              -- (takes a while)
 
185
 
 
186
 
 
187
class TestMultiMethod2(TestMultiMethod1):
 
188
    Installer = multimethod.InstallerVersion2