A program that checks itself
A test is a program whose exit status says whether your code does what you meant. It needs no framework.
fn round_score(first_die: int, second_die: int) -> int {
let sum = first_die + second_die;
if first_die == second_die { sum * 2 } else { sum }
}
fn failure_of(rule: bytes, holds: bool) -> int {
if holds { 0 } else {
print(concat3("FAIL ", rule, "\n"));
1
}
}
fn main() -> int {
failure_of("a double scores twice the sum", round_score(6, 6) == 24)
+ failure_of("any other roll scores the sum", round_score(2, 5) == 7)
}bootstrap/qdx run std/*.qdx check.qdx
echo $?0Each check is named after the rule it protects. A rule that does not hold is printed, and the exit status is the number of failures.
Keeping the code and its checks apart
Put round_score in its own file and give the compiler a different last file for each purpose: the one with the real main to build the program, and the one with the checking main to test it.
bootstrap/qdx run std/*.qdx dice.qdx game.qdx
bootstrap/qdx run std/*.qdx dice.qdx dice_check.qdxOnly one of the files given may declare main.
Checking that a program stops
To test that a program stops with the right message, run it as another process. run_program starts a program, sends its output and errors to files, and returns its exit status. A test can then read those files and compare. The repository’s own build program, build.qdx, tests the compiler this way.