def test_globals(): stack = Stack() stack.add_global("a", List(Integer)) stack.add_variable("b", Real) g = stack.get_variable("a") assert g.type == List(Integer) assert g.number == -1 stack.add_variable("a", Bool) g = stack.get_variable("a") assert g.type == Bool assert g.number == 1
def test_frames(): stack = Stack() assert stack.add_variable("a", Integer) == 0 assert stack.add_variable("b", Real) == 1 stack.add_frame() assert stack.add_variable("b", List(Integer)) == 2 assert stack.add_variable("c", Bool) == 3 assert stack.get_variable("b").type == List(Integer) stack.pop_frame() assert stack.get_variable("b").type == Real assert stack.get_variable("c") is None assert stack.add_variable("c", List(Integer)) == 2
def test_no_body(self): expression = FunctionDeclarationExpression(0, "func2", "func2", List(Integer), [], []) stream = CodeStream() expression.generate(VariablesPool(), stream, CodeMap(), None) assert stream.get_contents() == "@runtime_function(\"func2\")\n" \ "def func2():\n return list()\n"
def test_invalid_argument_types(self): with pytest.raises(FunctionArgumentsError): stack = Stack() stack.add_variable("var", Set(Real)) stack.add_variable("func", Function((([Integer, List(Integer)]), Integer))) tree = tr("func_call", "func", tr("int_literal", "1"), tr("variable", "var")) parser.handle(tree, stack)
class TestOperators: @pytest.mark.parametrize("op1_type, op2_type, op_name, res_type, res_expr", [ ("int_literal", "int_literal", "op_5_0", Integer, "(1) + (2)"), ("float_literal", "int_literal", "op_5_0", Real, "(1.0) + (2)"), ("int_literal", "float_literal", "op_5_0", Real, "(1) + (2.0)"), ("int_literal", "int_literal", "op_6_1", Real, "(1) / (2)") ]) def test_operators(self, op1_type: str, op2_type: str, op_name: str, res_type: Type, res_expr: str): tree = tr(op_name, tr(op1_type, "1"), tr(op2_type, "2")) expr: Expression = parser.handle(tree, Stack()) assert expr.type == res_type assert expr.intermediates == [] assert "".join(expr.expression) == res_expr @pytest.mark.parametrize("operator, arg1, arg2", [ ("op_5_0", tr("float_literal", "1"), tr("bool_literal_true")), ("op_5_0", tr("bool_literal_true"), tr("float_literal", "2")) ]) def test_wrong_operand(self, operator, arg1, arg2): tree = tr(operator, arg1, arg2) with pytest.raises(CompileTimeError): parser.handle(tree, Stack()) @pytest.mark.parametrize("arg1, arg2", [ (Bool, Bool), (Integer, Integer), (List(Integer), List(Integer)) ]) def test_comparision_correct(self, arg1, arg2): tree = tr("op_3_0", tr("variable", "a"), tr("variable", "b")) stack = Stack() stack.add_global("a", arg1) stack.add_global("b", arg2) expr: Expression = parser.handle(tree, stack) assert expr.type == Bool @pytest.mark.parametrize("arg1, arg2", [ (Bool, Void), (Void, Integer), (Void, Void), (Integer, Real), (Real, Integer), (List(Bool), Set(Bool)), (List(Integer), Set(Integer)) ]) def test_comparision_incorrect(self, arg1, arg2): tree = tr("op_3_0", tr("variable", "a"), tr("variable", "b")) stack = Stack() stack.add_global("a", arg1) stack.add_global("b", arg2) with pytest.raises(CompileTimeError): parser.handle(tree, stack)
def test_list_type_error(self): stack = Stack() stack.add_global("a", List(Bool)) tree = tr("var_assignment", tr("collection_item", tr("variable", "a"), tr("int_literal", "2")), tr("int_literal", "42")) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def test_list(self): stack = Stack() stack.add_global("a", List(Real)) tree = tr("var_assignment", tr("collection_item", tr("variable", "a"), tr("int_literal", "2")), tr("int_literal", "42")) expression = parser.handle(tree, stack) assert expression.expression == ["(", "a", ")[", "2", "]", " = ", "42"]
def test_list_reference(): stack = Stack() stack.add_global("a", List(Bool)) tree = tr("collection_item", tr("variable", "a"), tr("int_literal", "12")) expression = parser.handle(tree, stack) assert expression.expression == ["(", "a", ")[", "12", "]"] assert expression.type == Bool
def test_function_call(self, is_global): stack = Stack() stack.add_variable("array", List(Integer)) func = Function(([Integer, Real, List(Integer)], Void)) if is_global: stack.add_global("func", func) else: stack.add_variable("func", func) tree = tr("func_call", "func", tr("int_literal", "1"), tr("int_literal", "2"), tr("variable", "array")) expression = parser.handle(tree, stack) assert expression.type == Void func_name = "func" if is_global else "var_1" assert expression.expression == [func_name, "(", "1", ", ", "2", ", ", "var_0", ")"]
def test_for_loop_wrong_iterator_type(): with pytest.raises(ValueTypeError): stack = Stack() stack.add_variable("var", Bool) stack.add_variable("range", List(Integer)) tree = tr("for_expression", "var", tr("variable", "range"), tr("int_literal", "1")) parser.handle(tree, stack)
def test_for_loop_existing_var(): stack = Stack() stack.add_variable("var", Real) stack.add_variable("range", List(Integer)) tree = tr("for_expression", "var", tr("variable", "range"), tr("int_literal", "1")) expression = parser.handle(tree, stack) assert isinstance(expression, ForLoopExpression) assert expression.iterator == "var_0" assert expression.range.expression == ["var_1"] assert expression.actions[0].expression == ["1"]
import typing import pytest from cubelang.compiler.types import Type, Integer, Real, Bool, List, Set, Function, Void, type_annotation_to_type, T, \ Color, Side @pytest.mark.parametrize("type_object, representation", [(Integer, "Integer"), (Real, "Real"), (Bool, "Bool"), (Void, "Void"), (List(Set(Integer)), "List(Set(Integer))"), (Set(Bool), "Set(Bool)"), (Function(([Integer, Real, List(Bool)], Void)), "Function(([Integer, Real, List(Bool)], Void))")]) def test_repr(type_object: Type, representation: str): assert repr(type_object) == representation @pytest.mark.parametrize("type_object, string", [(Integer, "int"), (Real, "real"), (Bool, "bool"), (Void, "void"), (List(Set(Integer)), "list of set of int"), (Set(Bool), "set of bool")]) def test_repr(type_object: Type, string: str): assert str(type_object) == string @pytest.mark.parametrize("type1, type2, result", [(Integer, Integer, True), (Integer, Real, False), (Real, Integer, True), (Bool, Bool, True), (Bool, Integer, False),
def test_list_reference_wrong_index_type(): stack = Stack() stack.add_global("a", List(Integer)) tree = tr("collection_item", tr("variable", "a"), tr("float_literal", "12.2")) with pytest.raises(ValueTypeError): parser.handle(tree, stack)
def test_type_error(self): stack = Stack() stack.add_global("var", List(Integer)) tree = tr("var_assignment", "var", tr("int_literal", "0")) with pytest.raises(CompileTimeError): parser.handle(tree, stack)
def test_function_arguments(args: typing.List[Type], return_type: Type): func = Function(([Integer, Integer], Integer), ([Integer, Real], Bool), ([Real, Real], Color), ([Real, List(Integer)], Real), ([Color, Real, ...], Side)) res = func.takes_arguments(args) assert res == return_type
def test_function_arguments_generic(args: typing.List[Type], return_type: Type): func = Function(([T, List(T)], Set(T)), ([Set(List(T))], Integer), ([Set(T), List(T)], T)) assert func.takes_arguments(args) == return_type
def test_undefined_variable(): tree = tr("variable", "a") with pytest.raises(UnresolvedReferenceError): parser.handle(tree, Stack()) @pytest.mark.parametrize("tree, expected", [ (tr("type_int"), Integer), (tr("type_real"), Real), (tr("type_bool"), Bool), (tr("type_side"), Side), (tr("type_color"), Color), (tr("type_pattern"), Pattern), (tr("type_list", tr("type_bool")), List(Bool)), (tr("type_set", tr("type_real")), Set(Real)), ]) def test_type_handle(tree: lark.Tree, expected: Type): assert parser.handle(tree, Stack()) == expected class TestVariableDeclaration: def test_var_declaration(self): tree = tr("var_decl", "a", "b", "c", tr("type_int")) stack = Stack() expressions = parser.handle(tree, stack) for i, value in enumerate(expressions): assert value.type == Void assert value.expression == ["var_" + str(i), " = ", "0"]