Files @ fe0efc81bd4e
Branch filter:

Location: CSY/reowolf/src/protocol/tests/eval_binding.rs - annotation

fe0efc81bd4e 4.8 KiB application/rls-services+xml Show Source Show as Raw Download as Raw
MH
Implement binding evaluation and tests
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
fe0efc81bd4e
use super::*;

#[test]
fn test_binding_from_struct() {
    Tester::new_single_source_expect_ok("top level", "
        struct Foo{ u32 field }
        func foo() -> u32 {
            if (let Foo{ field: thing } = Foo{ field: 1337 }) { return thing; }
            return 0;
        }
    ").for_function("foo", |f| {
        f.call_ok(Some(Value::UInt32(1337)));
    });

    Tester::new_single_source_expect_ok("nested", "
        struct Nested<T>{ T inner }
        struct Foo{ u32 field }
        func make<T>(T val) -> Nested<T> {
            return Nested{ inner: val };
        }
        func foo() -> u32 {
            if (let Nested{ inner: Nested { inner: to_get } } = make(make(Foo{ field: 42 }))) {
                return to_get.field;
            }
            return 0;
        }
    ").for_function("foo", |f| {
        f.call_ok(Some(Value::UInt32(42)));
    });
}

#[test]
fn test_binding_from_array() {
    Tester::new_single_source_expect_ok("top level", "
        func foo() -> bool {
            // Mismatches in length
            bool failure1 = false;
            u32[] vals = { 1, 2, 3 };
            if (let {1, a} = vals) { failure1 = true; }

            bool failure2 = false;
            if (let {} = vals) { failure2 = true; }

            bool failure3 = false;
            if (let {1, 2, 3, 4} = vals) { failure3 = true; }

            // Mismatches in known values
            bool failure4 = false;
            if (let {1, 3, a} = vals) { failure4 = true; }

            // Matching with known variables
            auto constant_one = 1;
            auto constant_two = 2;
            auto constant_three = 3;
            bool success1 = false;
            if (
                let {binding_one, constant_two, constant_three} = vals &&
                let {constant_one, binding_two, constant_three} = vals &&
                let {constant_one, constant_two, binding_three} = vals
            ) {
                success1 = binding_one == 1 && binding_two == 2 && binding_three == 3;
            }

            // Matching with literals
            bool success2 = false;
            if (let {binding_one, 2, 3} = vals && let {1, binding_two, 3} = vals && let {1, 2, binding_three} = vals) {
                success2 = binding_one == 1 && binding_two == 2 && binding_three == 3;
            }

            // Matching all
            bool success3 = false;
            if (let {binding_one, binding_two, binding_three} = vals && let {1, 2, 3} = vals) {
                success3 = true;
            }

            return
                !failure1 && !failure2 && !failure3 && !failure4 &&
                success1 && success2 && success3;
        }
    ").for_function("foo", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });
}

#[test]
fn test_binding_fizz_buzz() {
    Tester::new_single_source_expect_ok("am I employable?", "
        union Fizzable { Number(u32), FizzBuzz, Fizz, Buzz }

        func construct_fizz_buzz(u32 num) -> Fizzable[] {
            u32 counter = 1;
            auto result = {};
            while (counter <= num) {
                auto value = Fizzable::Number(counter);
                if (counter % 5 == 0) {
                    if (counter % 3 == 0) {
                        value = Fizzable::FizzBuzz;
                    } else {
                        value = Fizzable::Buzz;
                    }
                } else if (counter % 3 == 0) {
                    value = Fizzable::Fizz;
                }

                result = result @ { value }; // woohoo, no array builtins!
                counter += 1;
            }

            return result;
        }

        func test_fizz_buzz(Fizzable[] fizzoid) -> bool {
            u32 idx = 0;
            bool valid = true;
            while (idx < length(fizzoid)) {
                auto number = idx + 1;
                auto is_div3 = number % 3 == 0;
                auto is_div5 = number % 5 == 0;

                if (let Fizzable::Number(got) = fizzoid[idx]) {
                    valid = valid && got == number && !is_div3 && !is_div5;
                } else if (let Fizzable::FizzBuzz = fizzoid[idx]) {
                    valid = valid && is_div3 && is_div5;
                } else if (let Fizzable::Fizz = fizzoid[idx]) {
                    valid = valid && is_div3 && !is_div5;
                } else if (let Fizzable::Buzz = fizzoid[idx]) {
                    valid = valid && !is_div3 && is_div5;
                } else {
                    // Impossibruuu!
                    valid = false;
                }

                idx += 1;
            }

            return valid;
        }

        func fizz_buzz() -> bool {
            auto fizz = construct_fizz_buzz(100);
            return test_fizz_buzz(fizz);
        }
    ").for_function("fizz_buzz", |f| { f
        .call_ok(Some(Value::Bool(true)));
    });
}