package dsl import ( "strings" "testing" "time" ) func parseOrFatal(t *testing.T, src string) *File { t.Helper() f, _, err := Parse(src) if err != nil { t.Fatalf("parse error: %v", err) } return f } func parseExpectError(t *testing.T, src, wantSubstr string) { t.Helper() _, _, err := Parse(src) if err == nil { t.Fatalf("expected error containing %q, got nil", wantSubstr) } if !strings.Contains(err.Error(), wantSubstr) { t.Errorf("error = %q, want substring %q", err.Error(), wantSubstr) } } func TestParseTestFileAndOutFile(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 test("files") { file("input.txt") = "1 2 3\n" outFile("result.txt") = "6\n" stdout = "" } } ` f := parseOrFatal(t, src) tst := f.Groups[0].Tests[0] if tst.InFiles["input.txt"] != "1 2 3\n" { t.Errorf("InFiles[input.txt] = %q", tst.InFiles["input.txt"]) } if tst.OutFiles["result.txt"] != "6\n" { t.Errorf("OutFiles[result.txt] = %q", tst.OutFiles["result.txt"]) } } func TestParseTestEnvAndWrapper(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 test("env") { env("FOO") = "bar" env("BAZ") = "qux" wrapper = "valgrind" stdout = "" } } ` f := parseOrFatal(t, src) tst := f.Groups[0].Tests[0] if tst.Env["FOO"] != "bar" || tst.Env["BAZ"] != "qux" { t.Errorf("Env = %v", tst.Env) } if tst.Wrapper != "valgrind" { t.Errorf("Wrapper = %q", tst.Wrapper) } } func TestParseTestTimeoutAndMemoryOverride(t *testing.T) { src := ` build "go build ." timeout 10s group("g") { weight = 1.0 memory_limit = 256MB test("override") { timeout = 2s memory_limit = 64MB stdout = "" } } ` f := parseOrFatal(t, src) tst := f.Groups[0].Tests[0] if tst.Timeout != 2*time.Second { t.Errorf("Timeout = %v, want 2s", tst.Timeout) } if tst.MemoryLimit != 64*1024*1024 { t.Errorf("MemoryLimit = %d, want %d", tst.MemoryLimit, 64*1024*1024) } } func TestParseTestExitCodeNonZero(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 test("fail") { exitCode = 42 stdout = "" } } ` f := parseOrFatal(t, src) tst := f.Groups[0].Tests[0] if tst.ExitCode == nil || *tst.ExitCode != 42 { t.Errorf("ExitCode = %v, want 42", tst.ExitCode) } } func TestParseTestUnknownKeyword(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 test("bad") { bogus = "x" } } ` parseExpectError(t, src, `"bogus"`) } func TestParseGroupScoringPartial(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 scoring = partial test("t") { stdout = "" } } ` f := parseOrFatal(t, src) if f.Groups[0].Scoring != ScoringPartial { t.Errorf("Scoring = %v, want partial", f.Groups[0].Scoring) } } func TestParseGroupScoringAllOrNone(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 scoring = all_or_none test("t") { stdout = "" } } ` f := parseOrFatal(t, src) if f.Groups[0].Scoring != ScoringAllOrNone { t.Errorf("Scoring = %v, want all_or_none", f.Groups[0].Scoring) } } func TestParseGroupScoringUnknown(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 scoring = magic test("t") { stdout = "" } } ` parseExpectError(t, src, "unknown scoring mode") } func TestParseGroupEnvAndWrapper(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 env("LANG") = "C" env("DEBUG") = "1" wrapper = "strace" test("t") { stdout = "" } } ` f := parseOrFatal(t, src) g := f.Groups[0] if g.Env["LANG"] != "C" || g.Env["DEBUG"] != "1" { t.Errorf("group Env = %v", g.Env) } if g.Wrapper != "strace" { t.Errorf("group Wrapper = %q", g.Wrapper) } } func TestParseGroupMemoryLimit(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 memory_limit = 128MB test("t") { stdout = "" } } ` f := parseOrFatal(t, src) if f.Groups[0].MemoryLimit != 128*1024*1024 { t.Errorf("group MemoryLimit = %d", f.Groups[0].MemoryLimit) } } func TestParseGroupUnknownKeyword(t *testing.T) { src := ` build "go build ." group("g") { weight = 1.0 foobar = 1 test("t") { stdout = "" } } ` parseExpectError(t, src, `"foobar"`) } func TestParseGroupMissingWeight(t *testing.T) { src := ` build "go build ." group("g") { test("t") { stdout = "" } } ` _, warns, err := Parse(src) if err != nil && !strings.Contains(err.Error(), "weight") { return } if err == nil && len(warns) == 0 { t.Error("expected error or warning about missing weight") } }