All checks were successful
go-test / go test (push) Successful in 56s
- Add dsl/matcher_test.go covering ExactMatcher, ContainsMatcher,
RegexMatcher, NumericEpsMatcher, AnyOrderMatcher and NoMatcher —
previously 0% — including epsilon, count mismatch, unparsable
numbers, invalid regex, and splitLines edge cases.
- Add dsl/ast_test.go for the new Test.SetInputFile / SetStdin /
SetOutputFile / SetStdout helpers and Pattern.IsDirMode.
- Add dsl/build_string_test.go covering BuildProfile.String,
WarningLevel.String and BuildConfig.MergeFrom (wrapper, defines
into nil map, defines override existing, nil src).
- Add dsl/merge_test.go driving mergeFiles to 100%: legacy build
fields, duplicate toolchain/build/group from include, binary /
sources / normalize_crlf / trim_trailing_ws propagation, local
overrides of timeout and memory_limit.
- Add dsl/parser_features_test.go for parseTest / parseGroup happy
paths that were missing: file/outFile, env, wrapper, per-test
timeout/memory overrides, non-zero exitCode, scoring partial /
all_or_none and unknown scoring.
- Add dsl/parser_errors_test.go, a 54-case table-driven test that
hits every `expect(...)` error branch in parseGroup and parseTest
(missing LPAREN/RPAREN/LBRACE/RBRACE/ASSIGN, wrong token types on
weight/timeout/memory_limit/scoring/env/wrapper/file/outFile, and
unclosed blocks).
- Add dsl/parser_misc_test.go covering parsePattern dir-mode with
args, unknown pattern field, non-ident in pattern, top-level
binary / sources / normalize_crlf / trim_trailing_ws / bare-int
memory_limit, parseBool invalid ident and non-ident, matcher
without an operator, validateBuilds legacy+structured conflict.
- Add dsl/build_parser_test.go covering every BuildConfig field
(sources, includes, sanitize, link, extra, platforms, compilers,
defines), OS overrides on named builds, nested / duplicate OS
override errors, unknown build / profile / warnings / platform,
missing = on assign-string and assign-string-list, define(...)
error cases, and parseToolchainsBlock (duplicate name, missing
platforms, bad name token, unknown field, unknown compiler class,
binary and class propagation).
- Add dsl/lexer_test.go for Token.String, TokenType.String UNKNOWN
branch, line comments, unterminated string and heredoc, unknown
escape sequence, escape decoding, unexpected character, every
K/M/G/KiB/MiB/GiB size suffix, ms/s/m duration suffixes, negative
integer lexing and float literals.
- Extend runner/result_test.go with Status.String and
TestResult.addFailure (both previously 0%).
- Add .gitea/workflows/go-test.yml running `go vet` and
`go test -race -coverprofile=coverage.out ./...` on push,
pull_request and manual dispatch, uploading coverage.out as an
artifact.
Coverage: dsl 60.5% -> 85%+, runner 29.0% -> 30.5%.
300 lines
7.9 KiB
Go
300 lines
7.9 KiB
Go
package dsl
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParserErrorCases(t *testing.T) {
|
|
const prefix = `build "go build ."` + "\n"
|
|
cases := []struct {
|
|
name string
|
|
body string
|
|
want string
|
|
}{
|
|
{
|
|
name: "group missing lparen",
|
|
body: `group "g" { weight = 1.0 test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group name not string",
|
|
body: `group(foo) { weight = 1.0 test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group missing rparen",
|
|
body: `group("g" { weight = 1.0 test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group missing lbrace",
|
|
body: `group("g") weight = 1.0`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group non-ident in body",
|
|
body: `group("g") { 42 }`,
|
|
want: "unexpected token",
|
|
},
|
|
{
|
|
name: "group weight missing assign",
|
|
body: `group("g") { weight 1.0 test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group weight non-number",
|
|
body: `group("g") { weight = "bad" test("t") { stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "group timeout missing assign",
|
|
body: `group("g") { weight = 1.0 timeout 5s test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group timeout non-duration",
|
|
body: `group("g") { weight = 1.0 timeout = "5s" test("t") { stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "group memory_limit missing assign",
|
|
body: `group("g") { weight = 1.0 memory_limit 64MB test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group memory_limit non-size",
|
|
body: `group("g") { weight = 1.0 memory_limit = "64MB" test("t") { stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "group scoring missing assign",
|
|
body: `group("g") { weight = 1.0 scoring partial test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group scoring non-ident",
|
|
body: `group("g") { weight = 1.0 scoring = "partial" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group env missing lparen",
|
|
body: `group("g") { weight = 1.0 env "K" = "v" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group env key not string",
|
|
body: `group("g") { weight = 1.0 env(K) = "v" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group env missing rparen",
|
|
body: `group("g") { weight = 1.0 env("K" = "v" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group env missing assign",
|
|
body: `group("g") { weight = 1.0 env("K") "v" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group env value not string",
|
|
body: `group("g") { weight = 1.0 env("K") = K test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group wrapper missing assign",
|
|
body: `group("g") { weight = 1.0 wrapper "x" test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group wrapper not string",
|
|
body: `group("g") { weight = 1.0 wrapper = X test("t") { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "group unclosed",
|
|
body: `group("g") { weight = 1.0 test("t") { stdout = "" }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "group pattern error",
|
|
body: `group("g") { weight = 1.0 pattern { bogus = 1 } }`,
|
|
want: "",
|
|
},
|
|
|
|
{
|
|
name: "test missing lparen",
|
|
body: `group("g") { weight = 1.0 test "t" { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test name not string",
|
|
body: `group("g") { weight = 1.0 test(t) { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test missing rparen",
|
|
body: `group("g") { weight = 1.0 test("t" { stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test missing lbrace",
|
|
body: `group("g") { weight = 1.0 test("t") stdout = "" }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test non-ident in body",
|
|
body: `group("g") { weight = 1.0 test("t") { 42 } }`,
|
|
want: "unexpected token",
|
|
},
|
|
{
|
|
name: "test stdin missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { stdin "x" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test stdin not string",
|
|
body: `group("g") { weight = 1.0 test("t") { stdin = 1 stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test args missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { args "x" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test exitCode missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { exitCode 0 stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test exitCode not int",
|
|
body: `group("g") { weight = 1.0 test("t") { exitCode = "x" stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "test timeout missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { timeout 2s stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test timeout not duration",
|
|
body: `group("g") { weight = 1.0 test("t") { timeout = "2s" stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "test memory_limit missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { memory_limit 64MB stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test memory_limit not size",
|
|
body: `group("g") { weight = 1.0 test("t") { memory_limit = "64MB" stdout = "" } }`,
|
|
want: "",
|
|
},
|
|
{
|
|
name: "test wrapper missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { wrapper "x" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test wrapper not string",
|
|
body: `group("g") { weight = 1.0 test("t") { wrapper = X stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test env missing lparen",
|
|
body: `group("g") { weight = 1.0 test("t") { env "K" = "v" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test env key not string",
|
|
body: `group("g") { weight = 1.0 test("t") { env(K) = "v" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test env missing rparen",
|
|
body: `group("g") { weight = 1.0 test("t") { env("K" = "v" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test env missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { env("K") "v" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test env value not string",
|
|
body: `group("g") { weight = 1.0 test("t") { env("K") = K stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test file missing lparen",
|
|
body: `group("g") { weight = 1.0 test("t") { file "x" = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test file key not string",
|
|
body: `group("g") { weight = 1.0 test("t") { file(x) = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test file missing rparen",
|
|
body: `group("g") { weight = 1.0 test("t") { file("x" = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test file missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { file("x") "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test file value not string",
|
|
body: `group("g") { weight = 1.0 test("t") { file("x") = y stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test outFile missing lparen",
|
|
body: `group("g") { weight = 1.0 test("t") { outFile "x" = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test outFile key not string",
|
|
body: `group("g") { weight = 1.0 test("t") { outFile(x) = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test outFile missing rparen",
|
|
body: `group("g") { weight = 1.0 test("t") { outFile("x" = "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test outFile missing assign",
|
|
body: `group("g") { weight = 1.0 test("t") { outFile("x") "y" stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test outFile value not string",
|
|
body: `group("g") { weight = 1.0 test("t") { outFile("x") = y stdout = "" } }`,
|
|
want: "expected",
|
|
},
|
|
{
|
|
name: "test unclosed",
|
|
body: `group("g") { weight = 1.0 test("t") { stdout = ""`,
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
_, _, err := Parse(prefix + c.body)
|
|
if err == nil {
|
|
t.Fatalf("expected error, got nil")
|
|
}
|
|
if c.want != "" && !strings.Contains(err.Error(), c.want) {
|
|
t.Errorf("error = %q, want substring %q", err.Error(), c.want)
|
|
}
|
|
})
|
|
}
|
|
}
|