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.
134 lines
3.3 KiB
Python
134 lines
3.3 KiB
Python
import pytest
|
|
import wasmtime
|
|
|
|
from phasm.type3.entry import Type3Exception
|
|
|
|
from ..helpers import Suite
|
|
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, )', (45, 46), 45, ),
|
|
('u8[2]', (45, 46), 45, ),
|
|
('bytes', b'This is a test', 84)
|
|
])
|
|
def test_subscript_0(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u8:
|
|
return f[0]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(in_put)
|
|
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, u8, )', (45, 46, 47), 47, ),
|
|
('u8[5]', (45, 46, 47, 48, 49), 47, ),
|
|
('bytes', b'This is a test', 105)
|
|
])
|
|
def test_subscript_2(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u8:
|
|
return f[2]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(in_put)
|
|
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put, exp_result', [
|
|
('(u8, u8, )', (45, 46), 45, ),
|
|
('u8[2]', (45, 46), 45, ),
|
|
('bytes', b'This is a test', 84)
|
|
])
|
|
def test_subscript_invalid_type(type_, in_put, exp_result):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(f: {type_}) -> u32:
|
|
return f[0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='u32 must be u8 instead'):
|
|
Suite(code_py).run_code(in_put)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_tuple_must_be_literal():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64), y: u8) -> u64:
|
|
return x[y]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Must index with literal'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_tuple_must_be_int():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64)) -> u64:
|
|
return x[0.0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Must index with integer literal'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put', [
|
|
('(u8, u8, )', (45, 46), ),
|
|
('u8[2]', (45, 46), ),
|
|
# bytes isn't known at runtime so works like normal
|
|
])
|
|
def test_subscript_oob_constant_low(type_, in_put):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(x: {type_}) -> u8:
|
|
return x[-1]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Tuple index out of range'):
|
|
Suite(code_py).run_code(in_put)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_oob_constant_high():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: (u8, u32, u64)) -> u64:
|
|
return x[4]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='Tuple index out of range'):
|
|
Suite(code_py).run_code()
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_, in_put', [
|
|
# Cannot Subscript tuple without a constant
|
|
('u8[2]', (45, 46), ),
|
|
('bytes', b'This is a test', ),
|
|
])
|
|
def test_subscript_oob_normal(type_, in_put):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(x: {type_}, y: u32) -> u8:
|
|
return x[y]
|
|
"""
|
|
|
|
with pytest.raises(wasmtime.Trap):
|
|
Suite(code_py).run_code(in_put, 255)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_subscript_not_subscriptable():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(x: u8) -> u8:
|
|
return x[0]
|
|
"""
|
|
|
|
with pytest.raises(Type3Exception, match='u8 cannot be subscripted'):
|
|
Suite(code_py).run_code()
|