Files @ fb814548c7d5
Branch filter:

Location: CSY/reowolf/src/protocol/tests/eval_operators.rs

fb814548c7d5 6.4 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
mh
Add tcp component to standard library
use super::*;

#[test]
fn test_assignment_operators() {
    fn construct_source(value_type: &str, value_initial: &str, value_op: &str) -> String {
        return format!(
            "func foo() -> {} {{
                {} value = {};
                value {};
                return value;
            }}",
            value_type, value_type, value_initial, value_op
        );
    }

    fn perform_test(name: &str, source: String, expected_value: Value) {
        Tester::new_single_source_expect_ok(name, source)
            .for_function("foo", move |f| {
                f.call_ok(Some(expected_value));
            });
    }

    perform_test(
        "set",
        construct_source("u32", "1", "= 5"),
        Value::UInt32(5)
    );

    perform_test(
        "multiplied",
        construct_source("u32", "2", "*= 4"),
        Value::UInt32(8)
    );

    perform_test(
        "divided",
        construct_source("u32", "8", "/= 4"),
        Value::UInt32(2)
    );

    perform_test(
        "remained",
        construct_source("u32", "8", "%= 3"),
        Value::UInt32(2)
    );

    perform_test(
        "added",
        construct_source("u32", "2", "+= 4"),
        Value::UInt32(6)
    );

    perform_test(
        "subtracted",
        construct_source("u32", "6", "-= 4"),
        Value::UInt32(2)
    );

    perform_test(
        "shifted left",
        construct_source("u32", "2", "<<= 2"),
        Value::UInt32(8)
    );

    perform_test(
        "shifted right",
        construct_source("u32", "8", ">>= 2"),
        Value::UInt32(2)
    );

    perform_test(
        "bitwise and",
        construct_source("u32", "15", "&= 35"),
        Value::UInt32(3)
    );

    perform_test(
        "bitwise xor",
        construct_source("u32", "3", "^= 7"),
        Value::UInt32(4)
    );

    perform_test(
        "bitwise or",
        construct_source("u32", "12", "|= 3"),
        Value::UInt32(15)
    );
}

#[test]
fn test_binary_integer_operators() {
    fn construct_source(value_type: &str, code: &str) -> String {
        format!("
        func foo() -> {} {{
            {}
        }}
        ", value_type, code)
    }

    fn perform_test(test_name: &str, value_type: &str, code: &str, expected_value: Value) {
        Tester::new_single_source_expect_ok(test_name, construct_source(value_type, code))
            .for_function("foo", move |f| {
                f.call_ok(Some(expected_value));
            });
    }

    perform_test(
        "bitwise_or", "u16",
        "auto a = 3; return a | 4;", Value::UInt16(7)
    );
    perform_test(
        "bitwise_xor", "u16",
        "auto a = 3; return a ^ 7;", Value::UInt16(4)
    );
    perform_test(
        "bitwise and", "u16",
        "auto a = 0b110011; return a & 0b011110;", Value::UInt16(0b010010)
    );
    perform_test(
        "shift left", "u16",
        "auto a = 0x0F; return a << 4;", Value::UInt16(0xF0)
    );
    perform_test(
        "shift right", "u64",
        "auto a = 0xF0; return a >> 4;", Value::UInt64(0x0F)
    );
    perform_test(
        "add", "u32",
        "auto a = 5; return a + 5;", Value::UInt32(10)
    );
    perform_test(
        "subtract", "u32",
        "auto a = 3; return a - 3;", Value::UInt32(0)
    );
    perform_test(
        "multiply", "u8",
        "auto a = 2 * 2; return a * 2 * 2;", Value::UInt8(16)
    );
    perform_test(
        "divide", "u8",
        "auto a = 32 / 2; return a / 2 / 2;", Value::UInt8(4)
    );
    perform_test(
        "remainder", "u16",
        "auto a = 29; return a % 3;", Value::UInt16(2)
    );
}

#[test]
fn test_tuple_comparison_operators() {
    Tester::new_single_source_expect_ok("tuple equality", "
    func test_func() -> bool {
        auto a1 = (8, 16, 32);
        (u8, u16, u32) a2 = (8, 16, 32);
        auto b1 = ();
        () b2 = ();

        return a1 == a2 && a2 == (8, 16, 32) && b1 == b2 && b2 == ();
    }
    ").for_function("test_func", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });

    Tester::new_single_source_expect_ok("tuple inequality", "
    func test_func() -> bool {
        auto a = (8, 16, 32);
        (u8, u16, u32) a_same = (8, 16, 32);
        auto a_diff = (0b111, 0b1111, 0b11111);
        auto b = ();
        return
            !(a != a_same) &&
            a != a_diff &&
            a != (8, 16, 320) &&
            !(b != ());
    }
    ").for_function("test_func", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });
}

#[test]
fn test_tuple_select_operator() {
    Tester::new_single_source_expect_ok("tuple member assignment", "
    func test() -> bool {
        auto tuple = (0, 1, 0, 1);
        tuple.0 = cast<u8>(1);
        tuple.1 = cast<u16>(2);
        tuple.2 = cast<u32>(3);
        tuple.3 = cast<u64>(4);
        return cast(tuple.0) + cast(tuple.1) + tuple.2 + cast(tuple.3) == 10;
    }
    ").for_function("test", |f| { f
        .for_variable("tuple", |v| { v.assert_concrete_type("(u8,u16,u32,u64)"); })
        .call_ok(Some(Value::Bool(true)));
    });

    Tester::new_single_source_expect_ok("tuple polymorph member access", "
    func sum_variant_a<A,B,C,D>((A,B,C,D) v) -> C {
        return cast(v.0) + cast(v.1) + v.2 + cast(v.3);
    }
    func sum_variant_b<A,B,C,D>((A,B,C,D) i) -> B {
        (A,B,C,D) c = (0,0,0,0);
        c.0 = i.0; c.1 = i.1; c.2 = i.2; c.3 = i.3;
        return cast(c.0) + c.1 + cast(c.2) + cast(c.3);
    }
    func test() -> bool {
        (u8,u16,u32,u64) tuple = (1, 2, 3, 4);
        return sum_variant_a(tuple) == 10 && sum_variant_b(tuple) == 10;
    }
    ").for_function("test", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });
}

#[test]
fn test_string_operators() {
    Tester::new_single_source_expect_ok("string concatenation", "
func create_concatenated(string left, string right) -> string {
    return left @ \", but also \" @ right;
}
func perform_concatenate(string left, string right) -> string {
    left @= \", but also \";
    left @= right;
    return left;
}
func foo() -> bool {
    auto left = \"Darth Vader\";
    auto right = \"Anakin Skywalker\";
    auto res1 = create_concatenated(left, right);
    auto res2 = perform_concatenate(left, right);
    auto expected = \"Darth Vader, but also Anakin Skywalker\";

    return
        res1 == expected &&
        res2 == \"Darth Vader, but also Anakin Skywalker\" &&
        res1 != \"This kind of thing\" && res2 != \"Another likewise kind of thing\";
}
    ").for_function("foo", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });
}