It was using an AST argument, and I'd rather not have those in the typing system (except the generator).
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 integer 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()
|