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,
};
}