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()