1. New build system
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
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 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
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 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
All checks were successful
build-dsl-smoke / Build judge (push) Successful in 12s
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 8s
build-dsl-smoke / release / gcc / linux (push) Successful in 6s
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 13s
build-dsl-smoke / debug-valgrind / gcc / linux (push) Successful in 14s
build-dsl-smoke / release / clang / windows (push) Successful in 16s
build-dsl-smoke / debug / msvc / windows (push) Successful in 18s
build-dsl-smoke / release / msvc / windows (push) Successful in 17s
build-dsl-smoke / SUMMARY (push) Successful in 4s
Release / Build & publish (push) Successful in 48s
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
23
example/showcase/01-minimal.jdg
Normal file
23
example/showcase/01-minimal.jdg
Normal file
@@ -0,0 +1,23 @@
|
||||
// Минимальный рабочий suite на structured DSL.
|
||||
// Декларируем один toolchain, один build, одну группу с одним тестом.
|
||||
// С этого можно копипастить для новых задач.
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
}
|
||||
|
||||
build "release" {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
profile = release
|
||||
}
|
||||
|
||||
group("basic") {
|
||||
weight = 1.0
|
||||
|
||||
test("hello") {
|
||||
stdout = "Hello, World!\n"
|
||||
}
|
||||
}
|
||||
72
example/showcase/02-structured-build.jdg
Normal file
72
example/showcase/02-structured-build.jdg
Normal file
@@ -0,0 +1,72 @@
|
||||
// Полный showcase возможностей build-блока.
|
||||
// Показывает: toolchains c платформами / переопределением binary / явным class,
|
||||
// build_defaults как общая основа, три профиля (release/debug/sanitized),
|
||||
// фильтры platforms и compilers, OS-оверрайды, wrapper, sanitize, define,
|
||||
// includes, link, extra, а также build-level `wrapper` для valgrind.
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
clang {
|
||||
platforms = "linux" "windows"
|
||||
binary = "clang-17" // конкретная версия в PATH
|
||||
class = gnu // явный class если имя нестандартное
|
||||
}
|
||||
msvc { platforms = "windows" }
|
||||
nvcc {
|
||||
platforms = "linux"
|
||||
class = gnu // nvcc принимает gnu-like флаги
|
||||
}
|
||||
}
|
||||
|
||||
build_defaults {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "src/*.c" // glob, раскрывается относительно work dir
|
||||
output = "solution" // на Windows автоматически станет solution.exe
|
||||
includes = "include" "vendor/include"
|
||||
link = "m" "pthread"
|
||||
warnings = strict // → -Wall -Wextra / /W4
|
||||
define("BUILD_ID") = "42"
|
||||
}
|
||||
|
||||
build "release" {
|
||||
profile = release // → -O2 / /O2
|
||||
|
||||
// OS-специфичные правки поверх defaults. Скаляры переопределяются,
|
||||
// списки (extra, sanitize, sources, includes) аккумулируются.
|
||||
linux { extra = "-fPIC" }
|
||||
windows { extra = "/bigobj" }
|
||||
darwin { extra = "-mmacosx-version-min=11" }
|
||||
}
|
||||
|
||||
build "debug" {
|
||||
profile = debug // → -O0 -g / /Od /Zi
|
||||
warnings = pedantic // → добавляет -Wpedantic / /permissive-
|
||||
define("DEBUG") = "1"
|
||||
}
|
||||
|
||||
build "sanitized" {
|
||||
profile = sanitized
|
||||
sanitize = "address" "undefined" "leak"
|
||||
platforms = "linux" // UBSan не работает на MSVC
|
||||
compilers = "gcc" "clang" // и только gnu-like
|
||||
extra = "-fno-sanitize-recover=all"
|
||||
}
|
||||
|
||||
build "debug-valgrind" {
|
||||
profile = debug
|
||||
wrapper = "valgrind --error-exitcode=99 --leak-check=full -q"
|
||||
platforms = "linux"
|
||||
compilers = "gcc"
|
||||
}
|
||||
|
||||
timeout 10s
|
||||
memory_limit = 256M
|
||||
|
||||
group("basic") {
|
||||
weight = 1.0
|
||||
|
||||
test("smoke") {
|
||||
stdout = "ok\n"
|
||||
}
|
||||
}
|
||||
69
example/showcase/03-matchers.jdg
Normal file
69
example/showcase/03-matchers.jdg
Normal file
@@ -0,0 +1,69 @@
|
||||
// Все способы сматчить stdout/stderr: exact, contains, regex, anyOrder,
|
||||
// numeric-eps. Плюс случай, когда сравнение вывода вообще не нужно
|
||||
// (достаточно exitCode).
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
}
|
||||
|
||||
build "release" {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
profile = release
|
||||
}
|
||||
|
||||
group("matchers") {
|
||||
weight = 1.0
|
||||
|
||||
// Точное совпадение (по умолчанию). Пробелы, переводы строк и
|
||||
// регистр важны. Нормализация CRLF / trim_ws настраивается на
|
||||
// уровне файла.
|
||||
test("exact") {
|
||||
stdin = "42\n"
|
||||
stdout = "42\n"
|
||||
}
|
||||
|
||||
// Подстрока в любом месте вывода.
|
||||
test("contains") {
|
||||
stdin = "log me\n"
|
||||
stdout contains "log me"
|
||||
}
|
||||
|
||||
// Регулярное выражение (Go regexp syntax).
|
||||
test("regex") {
|
||||
stdin = "7\n"
|
||||
stdout matches "^result:\\s+[0-9]+\\s*$"
|
||||
}
|
||||
|
||||
// Лайны могут прийти в любом порядке — полезно для stress-тестов
|
||||
// с параллельным выводом.
|
||||
test("any-order") {
|
||||
stdin = "start\n"
|
||||
stdout anyOrder {
|
||||
"alpha"
|
||||
"beta"
|
||||
"gamma"
|
||||
}
|
||||
}
|
||||
|
||||
// Числовое сравнение с epsilon — для задач с плавающей точкой.
|
||||
// Синтаксис: ~ <float> of "<ожидаемое значение как строка>"
|
||||
test("numeric") {
|
||||
stdin = "3.14159\n"
|
||||
stdout ~ 0.0001 of "3.14159\n"
|
||||
}
|
||||
|
||||
// Проверяем только stderr; stdout не трогаем вообще (NoMatcher).
|
||||
test("stderr-only") {
|
||||
args = "--version"
|
||||
stderr contains "version 1."
|
||||
}
|
||||
|
||||
// Никакого матчинга вывода — нас интересует только exit code.
|
||||
test("exit-code-only") {
|
||||
args = "--help"
|
||||
exitCode = 0
|
||||
}
|
||||
}
|
||||
77
example/showcase/04-limits-scoring-env.jdg
Normal file
77
example/showcase/04-limits-scoring-env.jdg
Normal file
@@ -0,0 +1,77 @@
|
||||
// Тонкая настройка: timeout и memory_limit на разных уровнях (file → group
|
||||
// → test), режимы скоринга (partial / all_or_none), переменные окружения,
|
||||
// проверка exit code, передача аргументов.
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
}
|
||||
|
||||
build "release" {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
profile = release
|
||||
}
|
||||
|
||||
// Глобальные дефолты. Применяются к каждому тесту, если тот не
|
||||
// переопределит у себя или на уровне группы.
|
||||
timeout 5s
|
||||
memory_limit = 256M
|
||||
normalize_crlf = true // стрип \r перед сравнением — полезно на Windows
|
||||
trim_trailing_ws = true // trim trailing space/tab на каждой строке
|
||||
|
||||
group("strict-subset") {
|
||||
weight = 0.4
|
||||
scoring = all_or_none // группа даёт weight или 0 — без частичного
|
||||
|
||||
// Эти дефолты применятся к каждому тесту группы.
|
||||
timeout = 2s
|
||||
memory_limit = 64M
|
||||
env("LC_ALL") = "C"
|
||||
env("LANG") = "C"
|
||||
|
||||
test("fast") {
|
||||
args = "--mode" "fast"
|
||||
stdout = "ok\n"
|
||||
}
|
||||
|
||||
test("strict-timeout") {
|
||||
timeout = 500ms // переопределяет group timeout
|
||||
stdout = "ok\n"
|
||||
}
|
||||
|
||||
test("high-memory") {
|
||||
memory_limit = 128M // переопределяет group memory_limit
|
||||
stdout = "ok\n"
|
||||
}
|
||||
|
||||
test("own-env") {
|
||||
env("FOO") = "bar" // добавляется к group env
|
||||
stdout = "ok\n"
|
||||
}
|
||||
}
|
||||
|
||||
group("partial-credit") {
|
||||
weight = 0.6
|
||||
scoring = partial // default: weight * passed/total
|
||||
|
||||
test("case-1") {
|
||||
stdin = "1\n"
|
||||
stdout = "1\n"
|
||||
exitCode = 0
|
||||
}
|
||||
|
||||
test("case-2") {
|
||||
stdin = "2\n"
|
||||
stdout = "4\n"
|
||||
exitCode = 0
|
||||
}
|
||||
|
||||
test("case-error") {
|
||||
// Программа ДОЛЖНА выйти с кодом 1 на плохом вводе.
|
||||
stdin = "abc\n"
|
||||
exitCode = 1
|
||||
stderr contains "invalid input"
|
||||
}
|
||||
}
|
||||
80
example/showcase/05-pattern-expansion.jdg
Normal file
80
example/showcase/05-pattern-expansion.jdg
Normal file
@@ -0,0 +1,80 @@
|
||||
// Автогенерация тестов из файлов/папок. Покрывает четыре типовых сценария:
|
||||
//
|
||||
// 1. Stdio-режим с парой globs — классика: stdin из .in, stdout = .ans
|
||||
// 2. Shared expected — N входов, один общий ожидаемый файл
|
||||
// 3. File-mode по args — программа читает файл по аргументу
|
||||
// 4. Dir-mode с input+output файлами — программа читает И пишет файлы
|
||||
//
|
||||
// Плейсхолдеры в `args` pattern'а:
|
||||
// {input_path} — путь к input-файлу текущего теста (для glob — разный,
|
||||
// для литерала — один и тот же во всех тестах)
|
||||
// {output_path} — аналогично для output
|
||||
// {name} — wildcard-часть имени (glob) или basename директории (dir)
|
||||
// {dir} — dir-mode: полный путь к директории теста
|
||||
//
|
||||
// Правило режима: наличие `{input_path}` в args → input кладётся как InFile,
|
||||
// а не в stdin. Наличие `{output_path}` → expected сравнивается как OutFile,
|
||||
// а не stdout.
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
}
|
||||
|
||||
build "release" {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
profile = release
|
||||
}
|
||||
|
||||
// 1) Классика: каждая пара (*.in, *.ans) → один тест.
|
||||
// Stdin ← .in, Stdout сравнивается с .ans.
|
||||
group("stdio-pair") {
|
||||
weight = 0.25
|
||||
|
||||
pattern {
|
||||
input = "tests/*.in"
|
||||
output = "tests/*.ans"
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Один общий expected для всех входов.
|
||||
// Удобно для задач где «для любого корректного входа ответ одинаковый»
|
||||
// (edge-case fuzzing) или наоборот «все некорректные входы → error»
|
||||
// (смотрим на один и тот же файл с сообщением об ошибке).
|
||||
group("shared-output") {
|
||||
weight = 0.25
|
||||
|
||||
pattern {
|
||||
input = "edge/*.in"
|
||||
output = "edge/expected.ans" // литерал без *
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Программа читает файл по аргументу командной строки, а не из stdin.
|
||||
// Expander создаёт InFiles[01.in]=..., запускает `./solution 01.in`,
|
||||
// сравнивает stdout программы с содержимым соответствующего .ans.
|
||||
group("file-input") {
|
||||
weight = 0.25
|
||||
|
||||
pattern {
|
||||
input = "file-tests/*.in"
|
||||
output = "file-tests/*.ans"
|
||||
args = "{input_path}"
|
||||
}
|
||||
}
|
||||
|
||||
// 4) Программа и читает, и пишет через файлы — никакого stdin/stdout.
|
||||
// Expander кладёт input в InFiles, expected в OutFiles, запускает
|
||||
// `./solution in.txt out.txt` и сравнивает созданный out.txt с expected.
|
||||
group("file-io") {
|
||||
weight = 0.25
|
||||
|
||||
pattern {
|
||||
dirs = "cases/*" // каждая подпапка — отдельный тест
|
||||
input = "in.txt"
|
||||
output = "out.txt"
|
||||
args = "{input_path}" "{output_path}"
|
||||
}
|
||||
}
|
||||
59
example/showcase/06-files.jdg
Normal file
59
example/showcase/06-files.jdg
Normal file
@@ -0,0 +1,59 @@
|
||||
// Тесты, которые общаются через файлы, а не через stdin/stdout.
|
||||
// file("name") = "content" — файл кладётся в рабочую директорию теста
|
||||
// перед запуском программы.
|
||||
// outFile("name") = "content" — после запуска содержимое файла сравнивается
|
||||
// с ожидаемым (точное совпадение с учётом
|
||||
// normalize_crlf / trim_trailing_ws).
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
}
|
||||
|
||||
build "release" {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
profile = release
|
||||
}
|
||||
|
||||
normalize_crlf = true
|
||||
trim_trailing_ws = true
|
||||
|
||||
group("io") {
|
||||
weight = 1.0
|
||||
|
||||
// Программа читает input.txt, пишет output.txt.
|
||||
test("copy") {
|
||||
args = "input.txt" "output.txt"
|
||||
file("input.txt") = "hello world\n"
|
||||
outFile("output.txt") = "hello world\n"
|
||||
}
|
||||
|
||||
// Несколько входных и выходных файлов сразу — удобно для задач
|
||||
// вроде «посчитать сумму по каждой строке и записать в отдельный
|
||||
// файл».
|
||||
test("multi-file") {
|
||||
args = "a.txt" "b.txt" "result.txt"
|
||||
file("a.txt") = "1 2 3\n"
|
||||
file("b.txt") = "10 20 30\n"
|
||||
outFile("result.txt") = "11 22 33\n"
|
||||
}
|
||||
|
||||
// Вложенные пути тоже работают — создаются автоматически.
|
||||
test("nested") {
|
||||
args = "data/in.txt" "data/out.txt"
|
||||
file("data/in.txt") = "payload\n"
|
||||
outFile("data/out.txt") = "PAYLOAD\n"
|
||||
}
|
||||
|
||||
// Можно комбинировать с stdin/stdout и переменными окружения.
|
||||
test("combined") {
|
||||
stdin = "42\n"
|
||||
args = "config.ini"
|
||||
env("MODE") = "strict"
|
||||
file("config.ini") = "threshold=10\n"
|
||||
stdout = "ok\n"
|
||||
outFile("log.txt") = "processed 42\n"
|
||||
}
|
||||
}
|
||||
41
example/showcase/07-include.jdg
Normal file
41
example/showcase/07-include.jdg
Normal file
@@ -0,0 +1,41 @@
|
||||
// Наследование общей конфигурации через `include`. Подключает соседний
|
||||
// common.jdg (тулчейны + build_defaults + глобальные настройки), а затем
|
||||
// задаёт только специфичные для этой задачи build-варианты и тесты.
|
||||
//
|
||||
// Пути в include относительны самому этому файлу (не CWD, не корню репо).
|
||||
// Абсолютные пути тоже работают. Циклические включения детектятся парсером.
|
||||
//
|
||||
// Локальные директивы поверх include могут переопределять:
|
||||
// - скаляры в build_defaults (через последующий build_defaults-блок)
|
||||
// - timeout / memory_limit / binary / sources / normalize_crlf / trim_trailing_ws
|
||||
// Но не могут переопределять:
|
||||
// - toolchains с тем же именем (ошибка «duplicate toolchain»)
|
||||
// - build с тем же именем
|
||||
// - group с тем же именем
|
||||
|
||||
include "common.jdg"
|
||||
|
||||
build "release" {
|
||||
profile = release
|
||||
}
|
||||
|
||||
build "debug" {
|
||||
profile = debug
|
||||
warnings = pedantic
|
||||
}
|
||||
|
||||
build "sanitized" {
|
||||
profile = sanitized
|
||||
sanitize = "address" "undefined"
|
||||
platforms = "linux"
|
||||
compilers = "gcc" "clang"
|
||||
}
|
||||
|
||||
group("basic") {
|
||||
weight = 1.0
|
||||
|
||||
test("smoke") {
|
||||
stdin = "1\n42\n"
|
||||
stdout = "42\n"
|
||||
}
|
||||
}
|
||||
22
example/showcase/common.jdg
Normal file
22
example/showcase/common.jdg
Normal file
@@ -0,0 +1,22 @@
|
||||
// Общая инфраструктура для всех задач курса: тулчейны и базовые настройки
|
||||
// билда. Подключается через `include "common.jdg"` из конкретных .jdg
|
||||
// файлов задач. Локальные build-блоки наследуют эти дефолты через
|
||||
// встроенный merge в build_defaults.
|
||||
|
||||
toolchains {
|
||||
gcc { platforms = "linux" }
|
||||
clang { platforms = "linux" "windows" }
|
||||
msvc { platforms = "windows" }
|
||||
}
|
||||
|
||||
build_defaults {
|
||||
language = "c"
|
||||
standard = "c11"
|
||||
sources = "solution.c"
|
||||
output = "solution"
|
||||
warnings = strict
|
||||
}
|
||||
|
||||
timeout 5s
|
||||
normalize_crlf = true
|
||||
trim_trailing_ws = true
|
||||
Reference in New Issue
Block a user