generic/tests/test_multimethod.py
2022-11-20 03:12:27 +00:00

139 lines
3.2 KiB
Python

import pytest
from generic.multimethod import has_multimethods, multimethod
def test_multimethod():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@foo.register(str) # type: ignore[no-redef]
def foo(self, x):
return f"{x}1"
assert Dummy().foo(1) == 2
assert Dummy().foo("1") == "11"
with pytest.raises(TypeError):
Dummy().foo([])
def test_multimethod_with_two_arguments():
@has_multimethods
class Dummy:
@multimethod(int, int)
def foo(self, x, y):
return x * y
@foo.register(str, int) # type: ignore[no-redef]
def foo(self, s, x):
return s * x
assert Dummy().foo(1, 1) == 1
assert Dummy().foo("1", 2) == "11"
with pytest.raises(TypeError):
Dummy().foo([])
def test_multimethod_otherwise_clause():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@foo.otherwise # type: ignore[no-redef]
def foo(self, x):
return type(x)
assert Dummy().foo(1) == 2
assert Dummy().foo("") is str
assert Dummy().foo([]) is list
def test_multimethod_otherwise_clausewith_two_arguments():
@has_multimethods
class Dummy:
@multimethod(int, int)
def foo(self, x, y):
return x * y
@foo.otherwise # type: ignore[no-redef]
def foo(self, s, x):
return f"{s} {x}"
assert Dummy().foo(1, 2) == 2
assert Dummy().foo("a", []) == "a []"
def test_inheritance():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@foo.register(float) # type: ignore[no-redef]
def foo(self, x):
return x + 1.5
@has_multimethods
class DummySub(Dummy):
@Dummy.foo.register(str)
def foo(self, x):
return f"{x}1"
@foo.register(tuple) # type: ignore[no-redef]
def foo(self, x):
return x + (1,)
@Dummy.foo.register(bool) # type: ignore[no-redef]
def foo(self, x):
return not x
assert Dummy().foo(1) == 2
assert Dummy().foo(1.5) == 3.0
with pytest.raises(TypeError):
Dummy().foo("1")
assert DummySub().foo(1) == 2
assert DummySub().foo(1.5) == 3.0
assert DummySub().foo("1") == "11"
assert DummySub().foo((1, 2)) == (1, 2, 1)
assert DummySub().foo(True) is False
with pytest.raises(TypeError):
DummySub().foo([])
def test_override_in_same_class_not_allowed():
with pytest.raises(ValueError):
@has_multimethods
class Dummy:
@multimethod(str, str)
def foo(self, x, y):
return x + y
@foo.register(str, str) # type: ignore[no-redef]
def foo(self, x, y):
return y + x
def test_inheritance_override():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@has_multimethods
class DummySub(Dummy):
@Dummy.foo.register(int)
def foo(self, x):
return x + 3
assert Dummy().foo(1) == 2
assert DummySub().foo(1) == 4