phasm/tests/integration/test_lang/test_struct.py
Johan B.W. de Vries f8d107f4fa Replaces did_construct with a proper router
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.
2025-05-10 16:49:10 +02:00

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