[pypy-svn] r34672 - pypy/dist/pypy/objspace/std/test

arigo at codespeak.net arigo at codespeak.net
Thu Nov 16 15:39:15 CET 2006


Author: arigo
Date: Thu Nov 16 15:39:14 2006
New Revision: 34672

Modified:
   pypy/dist/pypy/objspace/std/test/test_multimethod.py
Log:
- reorganize the test to check both multimethod installer versions
- add a systematic test


Modified: pypy/dist/pypy/objspace/std/test/test_multimethod.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_multimethod.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_multimethod.py	Thu Nov 16 15:39:14 2006
@@ -1,7 +1,8 @@
 import autopath
 from py.test import raises
 
-from pypy.objspace.std.multimethod import *
+from pypy.objspace.std import multimethod
+from pypy.objspace.std.multimethod import FailedToImplement
 
 
 class W_Root(object):
@@ -20,90 +21,169 @@
     assert isinstance(w_x, W_BoolObject)
     return W_IntObject()
 
-add = MultiMethodTable(2, root_class=W_Root, argnames_before=['space'])
-
 def add__Int_Int(space, w_x, w_y):
     assert space == 'space'
     assert isinstance(w_x, W_IntObject)
     assert isinstance(w_y, W_IntObject)
     return 'fine'
 
-add.register(add__Int_Int, W_IntObject, W_IntObject)
+
+class TestMultiMethod1:
+    Installer = multimethod.InstallerVersion1
+
+    def setup_class(cls):
+        cls.prev_installer = multimethod.Installer
+        multimethod.Installer = cls.Installer
+        add = multimethod.MultiMethodTable(2, root_class=W_Root,
+                                           argnames_before=['space'])
+        add.register(add__Int_Int, W_IntObject, W_IntObject)
+        typeorder = {
+            W_IntObject: [(W_IntObject, None), (W_Root, None)],
+            W_BoolObject: [(W_BoolObject, None), (W_IntObject, delegate_b2i),
+                           (W_Root, None)],
+            W_StringObject: [(W_StringObject, None), (W_Root, None)],
+            }
+        cls.typeorder = typeorder
+        cls.add = add
+        cls.add1 = staticmethod(add.install('__add', [typeorder, typeorder]))
+
+    def teardown_class(cls):
+        multimethod.Installer = cls.prev_installer
+
+    def test_simple(self):
+        space = 'space'
+        w_x = W_IntObject()
+        w_y = W_IntObject()
+        assert self.add1(space, w_x, w_y) == 'fine'
+
+    def test_failtoimplement(self):
+        space = 'space'
+        w_x = W_IntObject()
+        w_s = W_StringObject()
+        raises(FailedToImplement, "self.add1(space, w_x, w_s)")
+        raises(FailedToImplement, "self.add1(space, w_s, w_x)")
+
+    def test_delegate(self):
+        space = 'space'
+        w_x = W_IntObject()
+        w_s = W_StringObject()
+        w_b = W_BoolObject()
+        assert self.add1(space, w_x, w_b) == 'fine'
+        assert self.add1(space, w_b, w_x) == 'fine'
+        assert self.add1(space, w_b, w_b) == 'fine'
+        raises(FailedToImplement, "self.add1(space, w_b, w_s)")
+        raises(FailedToImplement, "self.add1(space, w_s, w_b)")
+
+    def test_not_baked(self):
+        typeorder = self.typeorder
+        add2 = self.add.install('__add2', [typeorder, typeorder],
+                                baked_perform_call=False)
+        assert add2[0] == ['space', 'arg0', 'arg1']
+        if multimethod.Installer is multimethod.InstallerVersion1:
+            assert add2[1] == 'arg0.__add2(space, arg1)'
+        assert isinstance(add2[2], dict)
+        assert not add2[3]
+
+    def test_empty(self):
+        add3_installer = multimethod.Installer(self.add, '__add3', [{},{}])
+        assert add3_installer.is_empty()
+        if multimethod.Installer is multimethod.InstallerVersion1:
+            assert len(add3_installer.to_install) == 1
+            assert add3_installer.to_install[0][0] is None
+
+    def test_empty_direct(self):
+        assert not self.add.install_if_not_empty('__add4', [{},{}])
+
+    def test_empty_not_baked(self):
+        add5_installer = multimethod.Installer(self.add, '__add5', [{},{}],
+                                               baked_perform_call=False)
+        assert add5_installer.is_empty()
+        if multimethod.Installer is multimethod.InstallerVersion1:
+            assert len(add5_installer.to_install) == 0
+        add5 = add5_installer.install()
+        assert add5[0] == ['space', 'arg0', 'arg1']
+        assert add5[1] == 'raiseFailedToImplement()'
+        assert isinstance(add5[2], dict)
+        assert add5[3]
+
+    def test_mmdispatcher(self):
+        typeorder = self.typeorder
+        add2 = multimethod.MMDispatcher(self.add, [typeorder, typeorder])
+        space = 'space'
+        w_x = W_IntObject()
+        w_s = W_StringObject()
+        w_b1 = W_BoolObject()
+        w_b2 = W_BoolObject()
+        assert add2(space, w_x, w_b1) == 'fine'
+        assert add2(space, w_b2, w_x) == 'fine'
+        assert add2(space, w_b1, w_b2) == 'fine'
+        raises(FailedToImplement, "add2(space, w_b2, w_s)")
+        raises(FailedToImplement, "add2(space, w_s, w_b1)")
+
+    def test_all_cases(self):
+        import random
+        space = 'space'
+        w_x = W_IntObject()
+        w_x.expected = [W_IntObject, W_Root]
+        w_s = W_StringObject()
+        w_s.expected = [W_StringObject, W_Root]
+        w_b = W_BoolObject()
+        w_b.expected = [W_BoolObject, W_IntObject, W_Root]
+
+        def test(indices):
+            sub = multimethod.MultiMethodTable(2, root_class=W_Root,
+                                               argnames_before=['space'])
+            def addimpl(cls1, cls2):
+                token = random.random()
+                def sub__cls1_cls2(space, w_x, w_y):
+                    assert space == 'space'
+                    assert isinstance(w_x, cls1)
+                    assert isinstance(w_y, cls2)
+                    return token
+                sub.register(sub__cls1_cls2, cls1, cls2)
+                return token
+
+            def check(w1, w2):
+                try:
+                    res = sub1(space, w1, w2)
+                except FailedToImplement:
+                    res = FailedToImplement
+                for cls1 in w1.expected:
+                    for cls2 in w2.expected:
+                        if (cls1, cls2) in expected:
+                            assert res == expected[cls1, cls2]
+                            return
+                else:
+                    assert res is FailedToImplement
+
+            random.shuffle(indices)
+            expected = {}
+            for index in indices:
+                cls1, cls2 = choices[index]
+                token = addimpl(cls1, cls2)
+                expected[cls1, cls2] = token
+
+            typeorder = self.typeorder
+            sub1 = sub.install('__sub', [typeorder, typeorder])
+            for w1 in [w_x, w_s, w_b]:
+                for w2 in [w_x, w_s, w_b]:
+                    check(w1, w2)
+
+        classes = [W_Root, W_StringObject, W_IntObject, W_BoolObject]
+        choices = [(cls1, cls2) for cls1 in classes
+                                for cls2 in classes]
+        # each choice is a pair of classes which can be implemented or
+        # not by the multimethod 'sub'.  Test all combinations that
+        # involve at most three implemented choices.
+        for i in range(len(choices)):
+            test([i])
+            for j in range(i+1, len(choices)):
+                test([i, j])
+                for k in range(j+1, len(choices)):
+                    test([i, j, k])
+                    #for l in range(k+1, len(choices)):  -- for a 4th choice
+                    #    test([i, j, k, l])              -- (takes a while)
 
 
-def setup_module(mod):
-    typeorder = {
-        W_IntObject: [(W_IntObject, None)],
-        W_BoolObject: [(W_BoolObject, None), (W_IntObject, delegate_b2i)],
-        W_StringObject: [(W_StringObject, None)],
-        }
-    mod.typeorder = typeorder
-    mod.add1 = add.install('__add', [typeorder, typeorder])
-
-
-def test_simple():
-    space = 'space'
-    w_x = W_IntObject()
-    w_y = W_IntObject()
-    assert add1(space, w_x, w_y) == 'fine'
-
-def test_failtoimplement():
-    space = 'space'
-    w_x = W_IntObject()
-    w_s = W_StringObject()
-    raises(FailedToImplement, "add1(space, w_x, w_s)")
-    raises(FailedToImplement, "add1(space, w_s, w_x)")
-
-def test_delegate():
-    space = 'space'
-    w_x = W_IntObject()
-    w_s = W_StringObject()
-    w_b = W_BoolObject()
-    assert add1(space, w_x, w_b) == 'fine'
-    assert add1(space, w_b, w_x) == 'fine'
-    assert add1(space, w_b, w_b) == 'fine'
-    raises(FailedToImplement, "add1(space, w_b, w_s)")
-    raises(FailedToImplement, "add1(space, w_s, w_b)")
-
-def test_not_baked():
-    add2 = add.install('__add2', [typeorder, typeorder],baked_perform_call=False)
-    assert add2[0] == ['space', 'arg0', 'arg1']
-    if Installer is InstallerVersion1:
-        assert add2[1] == 'arg0.__add2(space, arg1)'
-    assert isinstance(add2[2], dict)
-    assert not add2[3]
-
-def test_empty():
-    add3_installer = Installer(add, '__add3', [{},{}])
-    assert add3_installer.is_empty()
-    if Installer is InstallerVersion1:
-        assert len(add3_installer.to_install) == 1
-        assert add3_installer.to_install[0][0] is None
-
-def test_empty_direct():
-    assert not add.install_if_not_empty('__add4', [{},{}])
-
-
-def test_empty_not_baked():
-    add5_installer = Installer(add, '__add5', [{},{}], baked_perform_call=False)
-    assert add5_installer.is_empty()
-    if Installer is InstallerVersion1:
-        assert len(add5_installer.to_install) == 0
-    add5 = add5_installer.install()
-    assert add5[0] == ['space', 'arg0', 'arg1']
-    assert add5[1] == 'raiseFailedToImplement()'
-    assert isinstance(add5[2], dict)
-    assert add5[3]
-    
-def test_mmdispatcher():
-    add2 = MMDispatcher(add, [typeorder, typeorder])
-    space = 'space'
-    w_x = W_IntObject()
-    w_s = W_StringObject()
-    w_b1 = W_BoolObject()
-    w_b2 = W_BoolObject()
-    assert add2(space, w_x, w_b1) == 'fine'
-    assert add2(space, w_b2, w_x) == 'fine'
-    assert add2(space, w_b1, w_b2) == 'fine'
-    raises(FailedToImplement, "add2(space, w_b2, w_s)")
-    raises(FailedToImplement, "add2(space, w_s, w_b1)")
+class TestMultiMethod2(TestMultiMethod1):
+    Installer = multimethod.InstallerVersion2



More information about the Pypy-commit mailing list