feat(test): ludic test <dir>, each test block in a process of its own
A directory stands for its *_test.ludic files and the files straight inside any tests/ under it. The runner answers --list and runs one test by name, and ludic test runs every block in a child process, so tests no longer share globals. A failed expect names the file it is written in (the path the compiler was given) and its line. Reseed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8075892e0e
commit
9faaa2094d
8 changed files with 19724 additions and 19278 deletions
|
|
@ -23,6 +23,12 @@ function emit_expect_fail(cond1: pointer, msgsym: pointer, got: pointer, want: p
|
|||
emit(`{lok}:\n`)
|
||||
}
|
||||
|
||||
# an assertion names the file it is written in, as the compiler was given it, and its line
|
||||
function expect_where(e: Node) -> pointer {
|
||||
if e.file != null { return `{e.file}:{itoa(e.line)}` }
|
||||
return `{g_src_name}:{itoa(e.line)}`
|
||||
}
|
||||
|
||||
# lowercase an ASCII identifier (for #62 package-namespace aliasing: Foo -> foo)
|
||||
function ns_lower(s: pointer) -> pointer {
|
||||
let n = cstr_len(s)
|
||||
|
|
@ -673,7 +679,7 @@ function emit_call(e: Node) -> Val {
|
|||
g_uses_expect = true
|
||||
let a = emit_expr(e.kids[0])
|
||||
let c = emit_bind(`icmp ne i32 {a.code}, 0`)
|
||||
let msg = emit_str_const(`{g_src_name}:{itoa(e.line)}: expect failed`)
|
||||
let msg = emit_str_const(`{expect_where(e)}: expect failed`)
|
||||
emit_expect_fail(c, msg, "", "")
|
||||
return val("0", "void")
|
||||
}
|
||||
|
|
@ -681,7 +687,7 @@ function emit_call(e: Node) -> Val {
|
|||
g_uses_expect = true
|
||||
let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1])
|
||||
let c = emit_bind(`icmp eq i32 {a.code}, {b.code}`)
|
||||
let msg = emit_str_const(`{g_src_name}:{itoa(e.line)}: expect_eq failed`)
|
||||
let msg = emit_str_const(`{expect_where(e)}: expect_eq failed`)
|
||||
emit_expect_fail(c, msg, a.code, b.code)
|
||||
return val("0", "void")
|
||||
}
|
||||
|
|
@ -693,7 +699,7 @@ function emit_call(e: Node) -> Val {
|
|||
let isneg = emit_bind(`icmp slt i32 {d}, 0`)
|
||||
let ad = emit_bind(`select i1 {isneg}, i32 {neg}, i32 {d}`)
|
||||
let c = emit_bind(`icmp sle i32 {ad}, {tol.code}`)
|
||||
let msg = emit_str_const(`{g_src_name}:{itoa(e.line)}: expect_near failed`)
|
||||
let msg = emit_str_const(`{expect_where(e)}: expect_near failed`)
|
||||
emit_expect_fail(c, msg, a.code, b.code)
|
||||
return val("0", "void")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,26 @@ function emit_test_runner() -> void {
|
|||
emit(` store ptr {fval}, ptr %filter\n`)
|
||||
emit(` br label %{lstart}\n`)
|
||||
emit(`{lstart}:\n`)
|
||||
# `--list` names every test, one a line: `ludic test` runs each in a process of its own
|
||||
let llist = lbl("tlist"); let lrun0 = lbl("trun0")
|
||||
let fl0 = emit_bind("load ptr, ptr %filter")
|
||||
let hasf0 = emit_bind(`icmp ne ptr {fl0}, null`)
|
||||
let lcmp0 = lbl("tlcmp")
|
||||
emit(` br i1 {hasf0}, label %{lcmp0}, label %{lrun0}\n`)
|
||||
emit(`{lcmp0}:\n`)
|
||||
let listflag = emit_str_const("--list")
|
||||
let lc = emit_bind(`call i32 @strcmp(ptr {fl0}, ptr {listflag})`)
|
||||
let islist = emit_bind(`icmp eq i32 {lc}, 0`)
|
||||
emit(` br i1 {islist}, label %{llist}, label %{lrun0}\n`)
|
||||
emit(`{llist}:\n`)
|
||||
var li = 0
|
||||
while li < len(g_tests) {
|
||||
let nm = emit_str_const(g_tests[li].s)
|
||||
emit(` call i32 (ptr, ...) @printf(ptr @.fmt_line, ptr {nm})\n`)
|
||||
li += 1
|
||||
}
|
||||
emit(" ret i32 0\n")
|
||||
emit(`{lrun0}:\n`)
|
||||
if has_ecs() { emit(" call void @rt_init()\n") }
|
||||
emit(" call void @L_init_globals()\n")
|
||||
i = 0
|
||||
|
|
|
|||
19413
selfhost/ludicc.seed.ll
19413
selfhost/ludicc.seed.ll
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue