Doesn't give right answer yet and out of bound check fails. No constructor yet for static arrays, but module constants work. Which don't work yet for tuples and structs. Also, u32 for indexing please. Also, more module constant types.
572 lines
12 KiB
Python
572 lines
12 KiB
Python
import pytest
|
|
|
|
from .helpers import Suite
|
|
|
|
TYPE_MAP = {
|
|
'u8': int,
|
|
'u32': int,
|
|
'u64': int,
|
|
'i32': int,
|
|
'i64': int,
|
|
'f32': float,
|
|
'f64': float,
|
|
}
|
|
|
|
COMPLETE_SIMPLE_TYPES = [
|
|
'u32', 'u64',
|
|
'i32', 'i64',
|
|
'f32', 'f64',
|
|
]
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', TYPE_MAP.keys())
|
|
def test_return(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 13
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 13 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', COMPLETE_SIMPLE_TYPES)
|
|
def test_addition(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 + 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 13 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', COMPLETE_SIMPLE_TYPES)
|
|
def test_subtraction(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 - 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 7 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['u32', 'u64']) # FIXME: Support u8, requires an extra AND operation
|
|
def test_logical_left_shift(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 << 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 80 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
|
def test_logical_right_shift(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 >> 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 1 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
|
def test_bitwise_or(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 | 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 11 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
|
def test_bitwise_xor(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 ^ 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 9 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64'])
|
|
def test_bitwise_and(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return 10 & 3
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 2 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', ['f32', 'f64'])
|
|
def test_buildins_sqrt(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return sqrt(25)
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 5 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', TYPE_MAP.keys())
|
|
def test_arg(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry(a: {type_}) -> {type_}:
|
|
return a
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(125)
|
|
|
|
assert 125 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Do we want it to work like this?')
|
|
def test_i32_to_i64():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: i32) -> i64:
|
|
return a
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(125)
|
|
|
|
assert 125 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Do we want it to work like this?')
|
|
def test_i32_plus_i64():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: i32, b: i64) -> i64:
|
|
return a + b
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(125, 100)
|
|
|
|
assert 225 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Do we want it to work like this?')
|
|
def test_f32_to_f64():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: f32) -> f64:
|
|
return a
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(125.5)
|
|
|
|
assert 125.5 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Do we want it to work like this?')
|
|
def test_f32_plus_f64():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: f32, b: f64) -> f64:
|
|
return a + b
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(125.5, 100.25)
|
|
|
|
assert 225.75 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('TODO')
|
|
def test_uadd():
|
|
code_py = """
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return +523
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 523 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('TODO')
|
|
def test_usub():
|
|
code_py = """
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return -19
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert -19 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('inp', [9, 10, 11, 12])
|
|
def test_if_simple(inp):
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: i32) -> i32:
|
|
if a > 10:
|
|
return 15
|
|
|
|
return 3
|
|
"""
|
|
exp_result = 15 if inp > 10 else 3
|
|
|
|
suite = Suite(code_py)
|
|
|
|
result = suite.run_code(inp)
|
|
assert exp_result == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Such a return is not how things should be')
|
|
def test_if_complex():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: i32) -> i32:
|
|
if a > 10:
|
|
return 10
|
|
elif a > 0:
|
|
return a
|
|
else:
|
|
return 0
|
|
|
|
return -1 # Required due to function type
|
|
"""
|
|
|
|
suite = Suite(code_py)
|
|
|
|
assert 10 == suite.run_code(20).returned_value
|
|
assert 10 == suite.run_code(10).returned_value
|
|
|
|
assert 8 == suite.run_code(8).returned_value
|
|
|
|
assert 0 == suite.run_code(0).returned_value
|
|
assert 0 == suite.run_code(-1).returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_if_nested():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(a: i32, b: i32) -> i32:
|
|
if a > 11:
|
|
if b > 11:
|
|
return 3
|
|
|
|
return 2
|
|
|
|
if b > 11:
|
|
return 1
|
|
|
|
return 0
|
|
"""
|
|
|
|
suite = Suite(code_py)
|
|
|
|
assert 3 == suite.run_code(20, 20).returned_value
|
|
assert 2 == suite.run_code(20, 10).returned_value
|
|
assert 1 == suite.run_code(10, 20).returned_value
|
|
assert 0 == suite.run_code(10, 10).returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_call_pre_defined():
|
|
code_py = """
|
|
def helper(left: i32, right: i32) -> i32:
|
|
return left + right
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(10, 3)
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 13 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_call_post_defined():
|
|
code_py = """
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(10, 3)
|
|
|
|
def helper(left: i32, right: i32) -> i32:
|
|
return left - right
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 7 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', COMPLETE_SIMPLE_TYPES)
|
|
def test_call_with_expression(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return helper(10 + 20, 3 + 5)
|
|
|
|
def helper(left: {type_}, right: {type_}) -> {type_}:
|
|
return left - right
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 22 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('Not yet implemented')
|
|
def test_assign():
|
|
code_py = """
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
a: i32 = 8947
|
|
return a
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 8947 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', TYPE_MAP.keys())
|
|
def test_struct_0(type_):
|
|
code_py = f"""
|
|
class CheckedValue:
|
|
value: {type_}
|
|
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return helper(CheckedValue(23))
|
|
|
|
def helper(cv: CheckedValue) -> {type_}:
|
|
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_', COMPLETE_SIMPLE_TYPES)
|
|
def test_tuple_simple_constructor(type_):
|
|
code_py = f"""
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return helper((24, 57, 80, ))
|
|
|
|
def helper(vector: ({type_}, {type_}, {type_}, )) -> {type_}:
|
|
return vector[0] + vector[1] + vector[2]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 161 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_tuple_float():
|
|
code_py = """
|
|
@exported
|
|
def testEntry() -> f32:
|
|
return helper((1.0, 2.0, 3.0, ))
|
|
|
|
def helper(v: (f32, f32, f32, )) -> f32:
|
|
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 3.74 < result.returned_value < 3.75
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', COMPLETE_SIMPLE_TYPES)
|
|
def test_static_array_module_constant(type_):
|
|
code_py = f"""
|
|
CONSTANT: {type_}[3] = (24, 57, 80, )
|
|
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return helper(CONSTANT)
|
|
|
|
def helper(array: {type_}[3]) -> {type_}:
|
|
return array[0] + array[1] + array[2]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 161 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.parametrize('type_', COMPLETE_SIMPLE_TYPES)
|
|
def test_static_array_indexed(type_):
|
|
code_py = f"""
|
|
CONSTANT: {type_}[3] = (24, 57, 80, )
|
|
|
|
@exported
|
|
def testEntry() -> {type_}:
|
|
return helper(CONSTANT, 0, 1, 2)
|
|
|
|
def helper(array: {type_}[3], i0: u32, i1: u32, i2: u32) -> {type_}:
|
|
return array[i0] + array[i1] + array[i2]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert 161 == result.returned_value
|
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
|
|
|
@pytest.mark.integration_test
|
|
def test_bytes_address():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(f: bytes) -> bytes:
|
|
return f
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(b'This is a test')
|
|
|
|
# THIS DEPENDS ON THE ALLOCATOR
|
|
# A different allocator will return a different value
|
|
assert 20 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_bytes_length():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(f: bytes) -> i32:
|
|
return len(f)
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(b'This is another test')
|
|
|
|
assert 20 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_bytes_index():
|
|
code_py = """
|
|
@exported
|
|
def testEntry(f: bytes) -> u8:
|
|
return f[8]
|
|
"""
|
|
|
|
result = Suite(code_py).run_code(b'This is another test')
|
|
|
|
assert 0x61 == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
@pytest.mark.skip('SIMD support is but a dream')
|
|
def test_tuple_i32x4():
|
|
code_py = """
|
|
@exported
|
|
def testEntry() -> i32x4:
|
|
return (51, 153, 204, 0, )
|
|
"""
|
|
|
|
result = Suite(code_py).run_code()
|
|
|
|
assert (1, 2, 3, 0) == result.returned_value
|
|
|
|
@pytest.mark.integration_test
|
|
def test_imported():
|
|
code_py = """
|
|
@imported
|
|
def helper(mul: i32) -> i32:
|
|
pass
|
|
|
|
@exported
|
|
def testEntry() -> i32:
|
|
return helper(2)
|
|
"""
|
|
|
|
def helper(mul: int) -> int:
|
|
return 4238 * mul
|
|
|
|
result = Suite(code_py).run_code(
|
|
runtime='wasmer',
|
|
imports={
|
|
'helper': helper,
|
|
}
|
|
)
|
|
|
|
assert 8476 == result.returned_value
|