All checks were successful
build-dsl-smoke / Build judge (push) Successful in 13s
build-dsl-smoke / debug / clang / linux (push) Successful in 6s
build-dsl-smoke / debug / gcc / linux (push) Successful in 8s
build-dsl-smoke / release / clang / linux (push) Successful in 9s
build-dsl-smoke / release / gcc / linux (push) Successful in 7s
build-dsl-smoke / sanitized / clang / linux (push) Successful in 8s
build-dsl-smoke / sanitized / gcc / linux (push) Successful in 7s
build-dsl-smoke / debug / clang / windows (push) Successful in 16s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / clang / windows (push) Successful in 17s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 5s
211 lines
4.5 KiB
Go
211 lines
4.5 KiB
Go
package dsl
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func writeTempJdg(t *testing.T, dir, name, content string) string {
|
|
t.Helper()
|
|
path := filepath.Join(dir, name)
|
|
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func TestIncludeBasicMerge(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
writeTempJdg(t, dir, "common.jdg", `
|
|
toolchains {
|
|
gcc { platforms = "linux" }
|
|
}
|
|
|
|
build_defaults {
|
|
language = "c"
|
|
standard = "c11"
|
|
sources = "*.c"
|
|
output = "solution"
|
|
warnings = strict
|
|
}
|
|
`)
|
|
|
|
mainPath := writeTempJdg(t, dir, "main.jdg", `
|
|
include "common.jdg"
|
|
|
|
build "release" { profile = release }
|
|
|
|
group("g") {
|
|
weight = 1.0
|
|
test("t") { stdout = "ok\n" }
|
|
}
|
|
`)
|
|
|
|
f, _, err := ParseFile(mainPath)
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
|
|
if len(f.Toolchains) != 1 || f.Toolchains[0].Name != "gcc" {
|
|
t.Errorf("toolchains not merged: %+v", f.Toolchains)
|
|
}
|
|
if f.BuildDefaults == nil || f.BuildDefaults.Language != "c" {
|
|
t.Errorf("build_defaults not merged: %+v", f.BuildDefaults)
|
|
}
|
|
if len(f.Builds) != 1 || f.Builds[0].Name != "release" {
|
|
t.Errorf("local build lost: %+v", f.Builds)
|
|
}
|
|
}
|
|
|
|
func TestIncludeLocalOverridesIncluded(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
writeTempJdg(t, dir, "common.jdg", `
|
|
build_defaults {
|
|
language = "c"
|
|
standard = "c11"
|
|
warnings = strict
|
|
}
|
|
`)
|
|
|
|
mainPath := writeTempJdg(t, dir, "main.jdg", `
|
|
include "common.jdg"
|
|
|
|
build_defaults {
|
|
standard = "c17"
|
|
}
|
|
|
|
group("g") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`)
|
|
|
|
f, _, err := ParseFile(mainPath)
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if f.BuildDefaults.Standard != "c17" {
|
|
t.Errorf("local should override included standard: got %q", f.BuildDefaults.Standard)
|
|
}
|
|
if f.BuildDefaults.Language != "c" {
|
|
t.Errorf("language should survive from include: got %q", f.BuildDefaults.Language)
|
|
}
|
|
if f.BuildDefaults.Warnings != WarningsStrict {
|
|
t.Errorf("warnings should survive from include: got %v", f.BuildDefaults.Warnings)
|
|
}
|
|
}
|
|
|
|
func TestIncludeRelativePathResolution(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
writeTempJdg(t, dir, "shared/tools.jdg", `
|
|
toolchains {
|
|
gcc { platforms = "linux" }
|
|
}
|
|
`)
|
|
|
|
mainPath := writeTempJdg(t, dir, "suite/main.jdg", `
|
|
include "../shared/tools.jdg"
|
|
|
|
build "release" {
|
|
language = "c"
|
|
sources = "solution.c"
|
|
output = "solution"
|
|
profile = release
|
|
}
|
|
|
|
group("g") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`)
|
|
|
|
f, _, err := ParseFile(mainPath)
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if len(f.Toolchains) != 1 {
|
|
t.Errorf("relative include failed to resolve: %+v", f.Toolchains)
|
|
}
|
|
}
|
|
|
|
func TestIncludeDuplicateToolchainErrors(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
writeTempJdg(t, dir, "common.jdg", `
|
|
toolchains {
|
|
gcc { platforms = "linux" }
|
|
}
|
|
`)
|
|
|
|
mainPath := writeTempJdg(t, dir, "main.jdg", `
|
|
include "common.jdg"
|
|
|
|
toolchains {
|
|
gcc { platforms = "linux" }
|
|
}
|
|
|
|
group("g") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`)
|
|
|
|
_, _, err := ParseFile(mainPath)
|
|
if err == nil {
|
|
t.Fatal("expected duplicate toolchain error")
|
|
}
|
|
if !strings.Contains(err.Error(), "duplicate toolchain") {
|
|
t.Errorf("error %q does not mention duplicate toolchain", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestIncludeCircularDetection(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
aPath := writeTempJdg(t, dir, "a.jdg", `
|
|
include "b.jdg"
|
|
group("ga") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`)
|
|
writeTempJdg(t, dir, "b.jdg", `
|
|
include "a.jdg"
|
|
`)
|
|
|
|
_, _, err := ParseFile(aPath)
|
|
if err == nil {
|
|
t.Fatal("expected circular include error")
|
|
}
|
|
if !strings.Contains(err.Error(), "circular include") {
|
|
t.Errorf("error %q does not mention circular include", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestIncludeMissingFileErrors(t *testing.T) {
|
|
dir := t.TempDir()
|
|
|
|
mainPath := writeTempJdg(t, dir, "main.jdg", `
|
|
include "nonexistent.jdg"
|
|
group("g") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`)
|
|
|
|
_, _, err := ParseFile(mainPath)
|
|
if err == nil {
|
|
t.Fatal("expected missing include error")
|
|
}
|
|
if !strings.Contains(err.Error(), "nonexistent.jdg") {
|
|
t.Errorf("error %q does not reference the missing path", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestParseRejectsIncludeWithoutFileContext(t *testing.T) {
|
|
src := `
|
|
include "common.jdg"
|
|
group("g") { weight = 1.0 test("t") { stdout = "ok\n" } }
|
|
`
|
|
_, _, err := Parse(src)
|
|
if err == nil {
|
|
t.Fatal("expected error: include without file context")
|
|
}
|
|
if !strings.Contains(err.Error(), "file context") {
|
|
t.Errorf("error %q does not mention file context", err.Error())
|
|
}
|
|
}
|