async runStatements()

in packages/sqrl/src/testing/SqrlTest.ts [85:160]


  async runStatements(
    ctx: Context,
    statements: StatementAst[]
  ): Promise<{
    codedErrors: any[];
    executions: SqrlExecutionState[];
  }> {
    let assertions = [];
    const codedErrors = [];
    const executions: SqrlExecutionState[] = [];

    const prevStatements = [...this.statements];

    const execute = async (wait = false) => {
      try {
        const state = await this.executeStatements(ctx, assertions, wait);
        executions.push(state);
        codedErrors.push(...state.loggedCodedErrors);
        assertions = [];
        return state;
      } catch (err) {
        // If we hit an error, don't save the statements that caused the error.
        this.statements = prevStatements;
        throw err;
      }
    };

    for (const statement of statements) {
      if (statement.type === "assert") {
        assertions.push(statement);
      } else if (statement.type === "execute") {
        for (let idx = 0; idx < statement.repeat; idx++) {
          const state = await execute(true);
          if (this.mutate) {
            await this.mutate(state, {
              skipWait: statement.skipWait,
              repeat: statement.repeat || 1,
            });
          } else if (state.manipulator) {
            await state.manipulator.mutate(ctx);
          } else {
            ctx.warn({}, "Mutation function / manipulator is not injected");
          }
        }
      } else {
        if (assertions.length) {
          await execute();
        }

        // Allow overrides of previous let statements but keep order
        if (
          statement.type === "let" &&
          SqrlAst.isConstantTrue(statement.where)
        ) {
          const replace = this.statements.findIndex(
            (s) => s.type === "let" && s.feature === statement.feature
          );
          if (replace >= 0) {
            this.statements[replace] = statement;
            continue;
          }
        }

        this.statements.push(statement);
      }
    }

    if (assertions.length || !executions.length) {
      await execute();
    }

    return {
      codedErrors,
      executions,
    };
  }