test: expand dsl/runner coverage and add go-test CI workflow
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%.
This commit is contained in:
2026-04-16 00:59:09 +03:00
parent 5e0effc6fe
commit 7f14f8c236
11 changed files with 1914 additions and 1 deletions

75
dsl/ast_test.go Normal file
View File

@@ -0,0 +1,75 @@
package dsl
import "testing"
func newTest() *Test {
return &Test{
InFiles: map[string]string{},
OutFiles: map[string]string{},
}
}
func TestSetInputFile(t *testing.T) {
tst := newTest()
tst.SetInputFile("input.txt", []byte("hello"))
if got := tst.InFiles["input.txt"]; got != "hello" {
t.Errorf("InFiles[input.txt] = %q, want %q", got, "hello")
}
if tst.Stdin != nil {
t.Errorf("Stdin should remain nil, got %v", *tst.Stdin)
}
}
func TestSetStdin(t *testing.T) {
tst := newTest()
tst.SetStdin([]byte("data\n"))
if tst.Stdin == nil {
t.Fatal("Stdin is nil")
}
if *tst.Stdin != "data\n" {
t.Errorf("Stdin = %q, want %q", *tst.Stdin, "data\n")
}
if len(tst.InFiles) != 0 {
t.Errorf("InFiles should be empty, got %v", tst.InFiles)
}
}
func TestSetOutputFileSetsNoMatcher(t *testing.T) {
tst := newTest()
tst.SetOutputFile("out.txt", []byte("result"))
if got := tst.OutFiles["out.txt"]; got != "result" {
t.Errorf("OutFiles[out.txt] = %q, want %q", got, "result")
}
if _, ok := tst.Stdout.(NoMatcher); !ok {
t.Errorf("Stdout = %T, want NoMatcher", tst.Stdout)
}
}
func TestSetStdoutSetsExactMatcher(t *testing.T) {
tst := newTest()
tst.SetStdout([]byte("expected\n"))
m, ok := tst.Stdout.(ExactMatcher)
if !ok {
t.Fatalf("Stdout = %T, want ExactMatcher", tst.Stdout)
}
if m.Value != "expected\n" {
t.Errorf("ExactMatcher.Value = %q, want %q", m.Value, "expected\n")
}
if len(tst.OutFiles) != 0 {
t.Errorf("OutFiles should be empty, got %v", tst.OutFiles)
}
}
func TestIsDirModeTrue(t *testing.T) {
p := &Pattern{DirsGlob: "tests/*"}
if !p.IsDirMode() {
t.Error("IsDirMode() = false, want true")
}
}
func TestIsDirModeFalse(t *testing.T) {
p := &Pattern{InputGlob: "tests/*.in"}
if p.IsDirMode() {
t.Error("IsDirMode() = true, want false")
}
}