Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cdonovick committed Sep 24, 2019
1 parent 7bcdd4f commit c7dfa1b
Showing 1 changed file with 132 additions and 20 deletions.
152 changes: 132 additions & 20 deletions tests/test_adt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from hwtypes.adt import Product, Sum, Enum, Tuple
from hwtypes.adt import Product, Sum, Enum, Tuple, TaggedUnion
from hwtypes.adt_meta import RESERVED_ATTRS, ReservedNameError
from hwtypes.modifiers import new
from hwtypes.adt_util import rebind_bitvector
Expand All @@ -13,6 +13,7 @@ class En2(Enum):
c = 0
d = 1

Tu = Tuple[En1, En2]

class Pr(Product, cache=True):
x = En1
Expand All @@ -24,16 +25,27 @@ class Pr2(Product):
y = En2


class Pr3(Product):
class Pr3(Product, cache=True):
y = En2
x = En1


Su = Sum[En1, Pr]

class Ta(TaggedUnion, cache=True):
x = En1
y = En1
z = Pr

Tu = Tuple[En1, En2]
class Ta2(TaggedUnion):
x = En1
y = En1
z = Pr

class Ta3(TaggedUnion, cache=True):
y = En1
x = En1
z = Pr

def test_enum():
assert set(En1.enumerate()) == {
Expand Down Expand Up @@ -106,32 +118,26 @@ def test_product():
assert Pr[0] == Pr.x == En1
assert Pr[1] == Pr.y == En2

p = Pr(En1.a, En2.c)
assert p[0] == p.x == En1.a
assert p[1] == p.y == En2.c

assert Pr.field_dict == {'x' : En1, 'y' : En2 }
assert Pr(En1.b, En2.c).value_dict == {'x' : En1.b, 'y' : En2.c}

p = Pr(En1.a, En2.c)
with pytest.raises(TypeError):
Pr(En1.a, En1.a)

assert p[0] == p.x == En1.a
assert p[1] == p.y == En2.c
assert p.value_dict == {'x' : En1.a, 'y' : En2.c}

p.x = En1.b
assert p[0] == p.x == En1.b
assert p.value_dict == {'x' : En1.b, 'y' : En2.c}

p[0] = En1.a
assert p[0] == p.x == En1.a

with pytest.raises(TypeError):
Pr(En1.a, En1.a)

with pytest.raises(TypeError):
p[0] = En2.c

assert Pr != Pr2
assert Pr is Product.from_fields('Pr', {'x' : En1, 'y' : En2 }, cache=True)
assert Pr.field_dict == Pr2.field_dict
assert Pr.field_dict != Pr3.field_dict


def test_product_from_fields():
P = Product.from_fields('P', {'A' : int, 'B' : str})
Expand All @@ -154,6 +160,14 @@ def test_product_from_fields():
Pr.from_fields('P', {'A' : int, 'B' : str})


def test_product_caching():
assert Pr != Pr2
assert Pr != Pr3
assert Pr is Product.from_fields('Pr', {'x' : En1, 'y' : En2 }, cache=True)
assert Pr.field_dict == Pr2.field_dict
assert Pr.field_dict != Pr3.field_dict


def test_sum():
assert set(Su.enumerate()) == {
Su(En1.a),
Expand Down Expand Up @@ -195,7 +209,6 @@ def test_sum():
with pytest.raises(TypeError):
s[Pr].value


assert s.value_dict == {'En1' : En1.a, 'Pr' : None}

s[En1] = En1.b
Expand All @@ -215,6 +228,103 @@ def test_sum():
with pytest.raises(TypeError):
s[Pr] = En1.a

def test_tagged_union():
assert set(Ta.enumerate()) == {
Ta(x=En1.a),
Ta(x=En1.b),
Ta(y=En1.a),
Ta(y=En1.b),
Ta(z=Pr(En1.a, En2.c)),
Ta(z=Pr(En1.a, En2.d)),
Ta(z=Pr(En1.b, En2.c)),
Ta(z=Pr(En1.b, En2.d)),
}


assert Ta(x=En1.a)._value_ == En1.a

assert En1 in Ta
assert Pr in Ta
assert En2 not in Ta

assert issubclass(Ta, TaggedUnion)
assert isinstance(Ta(x=En1.a), TaggedUnion)
assert isinstance(Ta(x=En1.a), Ta)

assert Ta(x=En1.a) == Su(En1.a)
assert issubclass(Ta, Su)
assert issubclass(Ta, Sum)
assert isinstance(Ta(x=En1.a), Su)

assert Ta.x == Ta.y == Ta[En1] == Su[En1] == En1
assert Ta.z == Ta[Pr] == Su[Pr] == Pr

assert Ta.field_dict == {'x': En1, 'y': En1, 'z': Pr}

t = Ta(x=En1.a)
with pytest.raises(TypeError):
Ta(x=En2.c)

assert t[En1].match and t.x.match and not t.y.match and not t.z.match
assert t[En1].value == t.x.value == En1.a

with pytest.raises(TypeError):
t.y.value

with pytest.raises(TypeError):
t.z.value

assert t.value_dict == {'x': En1.a, 'y': None, 'z': None}

t.x = En1.b
assert t[En1].match and t.x.match and not t.y.match and not t.z.match
assert t[En1].value == t.x.value == En1.b

t.y = En1.a
assert t[En1].match and t.y.match and not t.x.match and not t.z.match
assert t[En1].value == t.y.value == En1.a

with pytest.raises(TypeError):
t[En1] = En1.a

with pytest.raises(TypeError):
t.z = En1.a

with pytest.raises(TypeError):
t.y = En2.c

assert Ta != Ta2
assert Ta.field_dict == Ta2.field_dict
assert Ta is TaggedUnion.from_fields('Ta', {'x': En1, 'y': En1, 'z': Pr}, cache=True)


def test_tagged_union_from_fields():
T = TaggedUnion.from_fields('T', {'A' : int, 'B' : str})
assert issubclass(T, TaggedUnion)
assert issubclass(T, Sum[int, str])
assert T.A == int
assert T.B == str
assert T.__module__ == TaggedUnion.__module__

assert T is TaggedUnion.from_fields('T', {'A' : int, 'B' : str})

T2 = TaggedUnion.from_fields('T', {'B' : str, 'A' : int})
assert T2 is T

T3 = TaggedUnion.from_fields('T', {'A' : int, 'B' : str}, cache=False)
assert T3 is not T

with pytest.raises(TypeError):
Ta.from_fields('T', {'A' : int, 'B' : str})


def test_tagged_union_caching():
assert Ta != Ta2
assert Ta != Ta3
assert Ta is TaggedUnion.from_fields('Ta', Ta3.field_dict, cache=True)
assert Ta.field_dict == Ta2.field_dict == Ta3.field_dict


def test_new():
t = new(Tuple)
s = new(Tuple)
Expand All @@ -233,7 +343,7 @@ def test_new():
assert t.__module__ == __name__


@pytest.mark.parametrize("T", [En1, Tu, Su, Pr])
@pytest.mark.parametrize("T", [En1, Tu, Su, Pr, Ta])
def test_repr(T):
s = repr(T)
assert isinstance(s, str)
Expand All @@ -244,7 +354,8 @@ def test_repr(T):
assert s != ''


@pytest.mark.parametrize("T_field", [(Enum, '0'), (Product, 'int')])
@pytest.mark.parametrize("T_field",
[(Enum, '0'), (Product, 'int'), (TaggedUnion, 'int')])
@pytest.mark.parametrize("field_name", list(RESERVED_ATTRS))
def test_reserved(T_field, field_name):
T, field = T_field
Expand All @@ -261,6 +372,7 @@ class _(T):
(Pr, Product),
(Su, Sum),
(Tu, Tuple),
(Ta, TaggedUnion),
])
def test_unbound_t(t, base):
assert t.unbound_t == base
Expand All @@ -269,7 +381,7 @@ class sub_t(t): pass
sub_t.unbound_t

@pytest.mark.parametrize("val", [
En1.a, Su(En1.a),
En1.a, Su(En1.a), Ta(x=En1.a),
Tu(En1.a, En2.c), Pr(En1.a, En2.c)])
def test_deprecated(val):
with pytest.warns(DeprecationWarning):
Expand Down

0 comments on commit c7dfa1b

Please sign in to comment.