By annotating types with the constructor application that was used to create them. Later on we can use the router to replace compiler's INSTANCES or for user defined types.
147 lines
3.0 KiB
Python
147 lines
3.0 KiB
Python
import pytest
|
|
|
|
from phasm.exceptions import StaticError
|
|
from phasm.type3.entry import Type3Exception
|
|
|
|
from ..helpers import Suite
|
|
|
|
|
|
@pytest.mark.integration_test
|
|
def test_struct_0():
|
|
code_py = """
|
|
class CheckedValue:
|
|
value: i32
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(CheckedValue(23))
|
|
|
|
def helper(cv: CheckedValue) -> i32:
|
|
return cv.value
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 23 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_struct_1():
|
|
code_py = """
|
|
class Rectangle:
|
|
height: i32
|
|
width: i32
|
|
border: i32
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(Rectangle(100, 150, 2))
|
|
|
|
def helper(shape: Rectangle) -> i32:
|
|
return shape.height + shape.width + shape.border
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 252 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_struct_2():
|
|
code_py = """
|
|
class Rectangle:
|
|
height: i32
|
|
width: i32
|
|
border: i32
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(Rectangle(100, 150, 2), Rectangle(200, 90, 3))
|
|
|
|
def helper(shape1: Rectangle, shape2: Rectangle) -> i32:
|
|
return shape1.height + shape1.width + shape1.border + shape2.height + shape2.width + shape2.border
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 545 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['i32', 'i64', 'f32', 'f64'])
|
|
def test_type_mismatch_struct_member(type_):
|
|
code_py = f"""
|
|
class Struct:
|
|
param: {type_}
|
|
|
|
def testEntry(arg: Struct) -> (i32, i32, ):
|
|
return arg.param
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match=type_ + r' must be \(i32, i32, \) instead'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
def test_name_already_use_struct():
|
|
code_py = """
|
|
class Struct:
|
|
param: i32
|
|
|
|
class Struct:
|
|
param: i64
|
|
"""
|
|
|
|
with pytest.raises(StaticError, match='Struct already defined as type'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
def test_name_already_use_type():
|
|
code_py = """
|
|
class f32:
|
|
param: i32
|
|
"""
|
|
|
|
with pytest.raises(StaticError, match='f32 already defined as type'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip(reason='FIXME: See constraintgenerator.py for AccessStructMember')
|
|
def test_struct_not_accessible():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: u8) -> u8:
|
|
return x.y
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='u8 is not struct'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
def test_struct_export_constant():
|
|
code_py = """
|
|
class CheckedValue:
|
|
value: i32
|
|
|
|
CONSTANT: CheckedValue = CheckedValue(32)
|
|
|
|
@exported
|
|
def testEntry() -> CheckedValue:
|
|
return CONSTANT
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert {"value": 32} == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_struct_export_instantiation():
|
|
code_py = """
|
|
class CheckedValue:
|
|
value: i32
|
|
|
|
@exported
|
|
def testEntry() -> CheckedValue:
|
|
return CheckedValue(32)
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert {"value": 32} == result.returned_value
|