CCCPaste

d5b0ec17ed54a

class TestFutures:

    # тут вопросов нет
    def test_future_task_construction(self):
        program = RplTestProgram(
            test_actor_contents="""\
            """,
            main_body="""\
            const A = shell: int { yield 42; };            /// A: task[int]
            const B = shell: int? { yield nil; };          /// B: task[int?]
            const C = shell: bool? { yield nil; };         /// C: task[bool?]
            const D = shell: bool { yield true; };         /// D: task[bool]
            const E = shell { yield; };                    /// E: task

            discard B;
            discard C;
            discard D;
            discard E;


            const Y = shell: int? {
                if ((wait A) % 2 == 0)
                    yield 2025; /// task gets to the Ready state with the value = 2025
                else
                    yield nil;  /// task gets to the Ready state with the value = nil
            };

            // Testing.message(f"Y's state is {Y}");
            // Testing.message(f"Y's value is {wait Y}");     /// Y is in Ready state here

            Testing.complete();
            """
        )
        check_compile_success(program)
        check_run_result(program)

    def test_future_task_internal_compiler_error(self):
        # FUTURE: Почему InternalError, а не успешная компиляция?
        """В этом тесте я хочу собрать task и task[int?] и вернуть его результатом функции."""

        program_typeless_task = RplTestProgram(
            test_actor_contents="""\
            def compute(): task {
                return shell { yield; };
            }
            """,
            main_body="""\
            discard compute();
            Testing.complete();
            """
        )
        check_compile_issues(program_typeless_task, IssueCode.E_InternalError)

        program_typed_task = RplTestProgram(
            test_actor_contents="""\
            def compute(condition: bool): task[int?] {
                return shell: int? {
                    if (condition)
                        yield 42;
                    else
                        yield nil;
                };
            }
            """,
            main_body="""\
            discard compute(true);
            Testing.complete();
            """
        )
        check_compile_issues(program_typed_task, IssueCode.E_InternalError)

    # тут вопросов нет
    def test_future_task_automatic_type_cast_failed(self):
        program = RplTestProgram(
            test_actor_contents="""\
            def compute(condition: bool): int? {
                return wait shell: int? {
                    if (condition)
                        yield 42;
                    else
                        yield nil;
                };
            }
            """,
            main_body="""\
            discard compute(true);
            Testing.complete();
            """
        )
        check_compile_success(program)

    def test_standard_future_library(self):
        # FUTURE:  Как у task получить статус Failed?
        """Правильно ли, что при панике из под шелла должен крашиться весь рантайм?
        В чем тогда смысл изоляции? Как достигается атомарность?
        """
        program = RplTestProgram(
            main_body="""\
                // Task A status: Pending
                const A = shell: int { yield 42; };

                assert pending(A) == true, "Task should be Pending";
                assert ready(A) == false, "Task should be Pending, not Ready";
                assert failed(A) == false, "Task should be Pending, not Failed";


                // Task B status: Failed?
                const B = shell {
                    assert false, "panic in the shell";  // runtime is dead
                    yield;
                };

                Testing.complete();
                """
        )
        check_compile_success(program)
        check_run_result(program)