Release 1.0.0-beta.19 test discovery foundation
This commit is contained in:
parent
3b231b7f21
commit
98f81d2d59
87
.llm/BETA_19_TEST_DISCOVERY_AND_CONFORMANCE.md
Normal file
87
.llm/BETA_19_TEST_DISCOVERY_AND_CONFORMANCE.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# 1.0.0-beta.19 Test Discovery And User-Project Conformance Foundation
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
`1.0.0-beta.19` is a compiler/tooling and conformance slice. It does
|
||||||
|
not change the Slovo source language or standard library surface.
|
||||||
|
|
||||||
|
Add deterministic list-only test discovery for:
|
||||||
|
|
||||||
|
- `glagol test --list <file|project|workspace>`
|
||||||
|
- `glagol --run-tests --list <file>` for the legacy single-file path
|
||||||
|
|
||||||
|
## Contract
|
||||||
|
|
||||||
|
List mode must reuse the same checked front-end path as normal test execution:
|
||||||
|
parse, lower, type-check, resolve project/workspace inputs, discover tests, and
|
||||||
|
apply `--filter <substring>`.
|
||||||
|
|
||||||
|
The command then lists discovered/selected tests without evaluating test bodies.
|
||||||
|
It must not execute runtime calls from test bodies, mutate files through test
|
||||||
|
logic, open sockets through test logic, or otherwise trigger user test
|
||||||
|
side-effects.
|
||||||
|
|
||||||
|
Ordering must remain deterministic and match current test execution discovery:
|
||||||
|
|
||||||
|
- single-file tests keep source order
|
||||||
|
- project tests keep existing module/package discovery order
|
||||||
|
- workspace tests keep existing workspace/package discovery order
|
||||||
|
|
||||||
|
Normal `glagol test` behavior and output remain unchanged unless `--list` is
|
||||||
|
present. Invalid files, projects, and workspaces still fail through the
|
||||||
|
existing diagnostic path.
|
||||||
|
|
||||||
|
## Output Shape
|
||||||
|
|
||||||
|
The initial output format is beta tooling. It should be stable enough for local
|
||||||
|
release-gate tests, but it is not a frozen public schema.
|
||||||
|
|
||||||
|
The output should make selected, skipped, total discovered, and filter state
|
||||||
|
visible. A concise text shape is enough; a stable JSON/event stream is out of
|
||||||
|
scope for this slice.
|
||||||
|
|
||||||
|
## Non-Scope
|
||||||
|
|
||||||
|
This scope does not add:
|
||||||
|
|
||||||
|
- source-language syntax
|
||||||
|
- runtime helper names
|
||||||
|
- JSON expansion
|
||||||
|
- parallel test execution
|
||||||
|
- retries
|
||||||
|
- tags or groups
|
||||||
|
- coverage reports
|
||||||
|
- event streams
|
||||||
|
- stable artifact-manifest schema freeze
|
||||||
|
- stable Markdown schema freeze
|
||||||
|
- LSP or watch behavior
|
||||||
|
- SARIF or daemon protocols
|
||||||
|
- package registries
|
||||||
|
- semver solving
|
||||||
|
- performance claims
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
- `glagol test --list <file.slo>` lists checked/discovered tests without
|
||||||
|
executing bodies.
|
||||||
|
- `glagol test --list <project>` and workspace inputs preserve current
|
||||||
|
project/workspace ordering.
|
||||||
|
- `glagol --run-tests --list <file.slo>` works for the legacy single-file path.
|
||||||
|
- `--filter <substring>` marks/selects the same tests as normal filtered
|
||||||
|
execution while avoiding body evaluation.
|
||||||
|
- Normal `glagol test` output stays byte-stable for existing covered cases.
|
||||||
|
- Invalid inputs still emit existing diagnostics.
|
||||||
|
- Docs describe beta19 as a released tooling/conformance slice.
|
||||||
|
- Release-gate coverage includes the focused beta19 test-discovery suite.
|
||||||
|
|
||||||
|
## Suggested Gates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --check
|
||||||
|
cargo test --test test_discovery_beta19
|
||||||
|
cargo test --test project_mode
|
||||||
|
cargo test --test cli_v1_1
|
||||||
|
cargo test --test diagnostics_schema_beta13
|
||||||
|
cargo test
|
||||||
|
./scripts/release-gate.sh
|
||||||
|
```
|
||||||
55
.llm/reviews/BETA_19_RELEASE_REVIEW.md
Normal file
55
.llm/reviews/BETA_19_RELEASE_REVIEW.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# 1.0.0-beta.19 Release Review
|
||||||
|
|
||||||
|
Scope: Test Discovery And User-Project Conformance Foundation
|
||||||
|
|
||||||
|
## Findings
|
||||||
|
|
||||||
|
No blocking findings.
|
||||||
|
|
||||||
|
The implementation matches the beta19 contract at the release-blocking level:
|
||||||
|
`glagol test --list <file|project|workspace>` and legacy
|
||||||
|
`glagol --run-tests --list <file>` route through checked discovery, avoid test
|
||||||
|
body evaluation, preserve the existing discovery ordering, honor
|
||||||
|
`--filter <substring>`, keep ordinary test output unchanged, and are wired into
|
||||||
|
the release gate through `cargo test --test test_discovery_beta19`.
|
||||||
|
|
||||||
|
## Non-Blocking Notes
|
||||||
|
|
||||||
|
- Resolved during controller integration: unfiltered list output now prints the
|
||||||
|
same summary suffix as filtered list output, including `total_discovered`,
|
||||||
|
`selected`, `passed`, `failed`, `skipped`, and `filter none`.
|
||||||
|
- Resolved during controller integration: the grammar typo in
|
||||||
|
`docs/POST_BETA_ROADMAP.md` was corrected.
|
||||||
|
|
||||||
|
## Verification Notes
|
||||||
|
|
||||||
|
Inspected:
|
||||||
|
|
||||||
|
- Working tree status and beta19 diff across CLI parsing/dispatch, project test
|
||||||
|
mode, test-runner listing, focused tests, docs, version files, and
|
||||||
|
`scripts/release-gate.sh`.
|
||||||
|
- Contract drift against
|
||||||
|
`.llm/BETA_19_TEST_DISCOVERY_AND_CONFORMANCE.md`,
|
||||||
|
`docs/language/SPEC-v1.md`, release notes, roadmaps, and README beta scope.
|
||||||
|
- Cached diff status; no cached beta19 changes were present.
|
||||||
|
|
||||||
|
Read-only checks run:
|
||||||
|
|
||||||
|
- `git diff --check` - passed.
|
||||||
|
- `git diff --cached --check` - passed.
|
||||||
|
- Stale-version scan for beta18/beta19 references - no blocking stale current
|
||||||
|
release references found.
|
||||||
|
- Conflict-marker and trailing-whitespace scans for the untracked beta19
|
||||||
|
contract/test files - passed.
|
||||||
|
|
||||||
|
Not run:
|
||||||
|
|
||||||
|
- `cargo fmt --check`, focused cargo tests, full `cargo test`, and
|
||||||
|
`./scripts/release-gate.sh`; those commands write build artifacts, and this
|
||||||
|
review was constrained to read-only commands except for the review file.
|
||||||
|
|
||||||
|
## Verdict
|
||||||
|
|
||||||
|
Release-ready from this review. No blocking beta19 issues remain in the current
|
||||||
|
working tree diff. The controller should still run the focused beta19 test suite
|
||||||
|
and full release gate before tagging.
|
||||||
31
README.md
31
README.md
@ -6,7 +6,7 @@ This repository is the canonical public monorepo for the language design,
|
|||||||
standard library source, compiler, runtime, examples, benchmarks, and technical
|
standard library source, compiler, runtime, examples, benchmarks, and technical
|
||||||
documents.
|
documents.
|
||||||
|
|
||||||
Current release: `1.0.0-beta.18`.
|
Current release: `1.0.0-beta.19`.
|
||||||
|
|
||||||
## Repository Layout
|
## Repository Layout
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ scripts/ local release and document tooling
|
|||||||
|
|
||||||
## Beta Scope
|
## Beta Scope
|
||||||
|
|
||||||
`1.0.0-beta.18` keeps the `1.0.0-beta` language baseline, includes the
|
`1.0.0-beta.19` keeps the `1.0.0-beta` language baseline, includes the
|
||||||
`1.0.0-beta.1` tooling/install hardening slice, the `1.0.0-beta.2`
|
`1.0.0-beta.1` tooling/install hardening slice, the `1.0.0-beta.2`
|
||||||
runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library
|
runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library
|
||||||
stabilization bundle, the `1.0.0-beta.4` language-usability diagnostics
|
stabilization bundle, the `1.0.0-beta.4` language-usability diagnostics
|
||||||
@ -39,8 +39,9 @@ slice, the `1.0.0-beta.13` diagnostic catalog and schema policy slice, the
|
|||||||
`1.0.0-beta.14` benchmark suite catalog and metadata gate, and the
|
`1.0.0-beta.14` benchmark suite catalog and metadata gate, and the
|
||||||
`1.0.0-beta.15` reserved generic collection boundary hardening and collection
|
`1.0.0-beta.15` reserved generic collection boundary hardening and collection
|
||||||
ledger, the `1.0.0-beta.16` string scanning and token boundary foundation,
|
ledger, the `1.0.0-beta.16` string scanning and token boundary foundation,
|
||||||
the `1.0.0-beta.17` JSON primitive scalar parsing foundation, and the
|
the `1.0.0-beta.17` JSON primitive scalar parsing foundation, the
|
||||||
`1.0.0-beta.18` JSON string token parsing foundation.
|
`1.0.0-beta.18` JSON string token parsing foundation, and the
|
||||||
|
`1.0.0-beta.19` test discovery and user-project conformance foundation.
|
||||||
The language baseline supports practical local command-line, file, and
|
The language baseline supports practical local command-line, file, and
|
||||||
loopback-network programs with:
|
loopback-network programs with:
|
||||||
|
|
||||||
@ -131,6 +132,13 @@ escapes `\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, and `\t`, and returns
|
|||||||
parsing, tokenizer APIs, Unicode escape decoding/normalization, embedded NUL
|
parsing, tokenizer APIs, Unicode escape decoding/normalization, embedded NUL
|
||||||
policy, stable ABI/layout, and a stable stdlib/API freeze remain deferred.
|
policy, stable ABI/layout, and a stable stdlib/API freeze remain deferred.
|
||||||
|
|
||||||
|
The `1.0.0-beta.19` test discovery and user-project conformance foundation
|
||||||
|
adds `glagol test --list <file|project|workspace>` plus legacy
|
||||||
|
`glagol --run-tests --list <file>` support for listing checked and discovered
|
||||||
|
tests without executing test bodies. The list mode preserves existing file,
|
||||||
|
project, and workspace test ordering, honors `--filter <substring>`, and
|
||||||
|
remains beta tooling rather than a stable output schema.
|
||||||
|
|
||||||
Still deferred before stable: executable generics, generic aliases, maps/sets,
|
Still deferred before stable: executable generics, generic aliases, maps/sets,
|
||||||
broad package registry semantics, stable Markdown schema, stable stdlib/API
|
broad package registry semantics, stable Markdown schema, stable stdlib/API
|
||||||
compatibility freeze, DNS/TLS/async networking, LSP/watch guarantees, SARIF
|
compatibility freeze, DNS/TLS/async networking, LSP/watch guarantees, SARIF
|
||||||
@ -140,16 +148,11 @@ iterators, additional compiler-known runtime names, stable ABI and layout,
|
|||||||
performance claims, stable benchmark JSON metadata schema, and runtime changes
|
performance claims, stable benchmark JSON metadata schema, and runtime changes
|
||||||
for generic collections.
|
for generic collections.
|
||||||
|
|
||||||
The next likely language slice after `1.0.0-beta.18` should continue from the
|
The beta19 tooling scope is deliberately tooling-only. It does not add parallel
|
||||||
developer-experience, package, benchmark metadata, collection, or string
|
test execution, retries, tags/groups, coverage reports, event streams, stable
|
||||||
processing lanes without claiming executable generics, maps, sets, traits,
|
manifest or Markdown schema guarantees, LSP/watch behavior, SARIF/daemon
|
||||||
inference, monomorphization, iterators, ABI stability, broad runtime changes,
|
protocols, JSON expansion, runtime helper names, source-language syntax,
|
||||||
LSP/watch protocols, SARIF/daemon protocols, registry semantics, stable
|
remote package registries, semver solving, or performance claims.
|
||||||
Markdown schema, stable benchmark JSON schema, a stable `1.0.0` diagnostics
|
|
||||||
freeze, standard-library/API compatibility freeze, mutable vectors, language
|
|
||||||
slice/view APIs, additional runtime names, Unicode/grapheme semantics, broader
|
|
||||||
JSON object/array/full-value parsing, or performance claims until the contract
|
|
||||||
and gates are explicit.
|
|
||||||
|
|
||||||
## Build And Test
|
## Build And Test
|
||||||
|
|
||||||
|
|||||||
2
compiler/Cargo.lock
generated
2
compiler/Cargo.lock
generated
@ -4,4 +4,4 @@ version = 3
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glagol"
|
name = "glagol"
|
||||||
version = "1.0.0-beta.18"
|
version = "1.0.0-beta.19"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "glagol"
|
name = "glagol"
|
||||||
version = "1.0.0-beta.18"
|
version = "1.0.0-beta.19"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Glagol, the first compiler for the Slovo language"
|
description = "Glagol, the first compiler for the Slovo language"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@ -52,6 +52,16 @@ pub fn run_tests(
|
|||||||
test_runner::run(file, &checked, filter)
|
test_runner::run(file, &checked, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_tests(
|
||||||
|
file: &str,
|
||||||
|
source: &str,
|
||||||
|
filter: Option<&str>,
|
||||||
|
) -> Result<test_runner::TestRunSuccess, test_runner::TestRunFailure> {
|
||||||
|
let checked =
|
||||||
|
checked_program(file, source).map_err(test_runner::TestRunFailure::before_execution)?;
|
||||||
|
Ok(test_runner::list(&checked, filter))
|
||||||
|
}
|
||||||
|
|
||||||
fn checked_program(file: &str, source: &str) -> Result<check::CheckedProgram, Vec<Diagnostic>> {
|
fn checked_program(file: &str, source: &str) -> Result<check::CheckedProgram, Vec<Diagnostic>> {
|
||||||
let tokens = lexer::lex(file, source)?;
|
let tokens = lexer::lex(file, source)?;
|
||||||
let forms = sexpr::parse(file, &tokens)?;
|
let forms = sexpr::parse(file, &tokens)?;
|
||||||
|
|||||||
@ -184,7 +184,13 @@ fn run_project_check(invocation: Invocation) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_project_test(invocation: Invocation) -> ! {
|
fn run_project_test(invocation: Invocation) -> ! {
|
||||||
match project::run_tests(&invocation.path, invocation.test_filter.as_deref()) {
|
let result = if invocation.test_list {
|
||||||
|
project::list_tests(&invocation.path, invocation.test_filter.as_deref())
|
||||||
|
} else {
|
||||||
|
project::run_tests(&invocation.path, invocation.test_filter.as_deref())
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
Ok(success) => {
|
Ok(success) => {
|
||||||
let output = success.output;
|
let output = success.output;
|
||||||
let primary_output = if let Some(output_path) = invocation.output_path.as_deref() {
|
let primary_output = if let Some(output_path) = invocation.output_path.as_deref() {
|
||||||
@ -679,7 +685,13 @@ fn finish_formatted_source(
|
|||||||
|
|
||||||
fn run_test_mode(invocation: Invocation, source: &str) -> ! {
|
fn run_test_mode(invocation: Invocation, source: &str) -> ! {
|
||||||
let foreign_imports = c_imports_for_manifest(&invocation.path, source);
|
let foreign_imports = c_imports_for_manifest(&invocation.path, source);
|
||||||
match driver::run_tests(&invocation.path, source, invocation.test_filter.as_deref()) {
|
let result = if invocation.test_list {
|
||||||
|
driver::list_tests(&invocation.path, source, invocation.test_filter.as_deref())
|
||||||
|
} else {
|
||||||
|
driver::run_tests(&invocation.path, source, invocation.test_filter.as_deref())
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
let output = result.output;
|
let output = result.output;
|
||||||
let primary_output = if let Some(output_path) = invocation.output_path.as_deref() {
|
let primary_output = if let Some(output_path) = invocation.output_path.as_deref() {
|
||||||
@ -1101,6 +1113,7 @@ struct Invocation {
|
|||||||
project_template: scaffold::ProjectTemplate,
|
project_template: scaffold::ProjectTemplate,
|
||||||
link_c_paths: Vec<String>,
|
link_c_paths: Vec<String>,
|
||||||
test_filter: Option<String>,
|
test_filter: Option<String>,
|
||||||
|
test_list: bool,
|
||||||
run_args: Vec<String>,
|
run_args: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1137,6 +1150,7 @@ fn parse_args(raw_args: &[String]) -> Result<Args, ParseError> {
|
|||||||
let mut project_template = scaffold::ProjectTemplate::Binary;
|
let mut project_template = scaffold::ProjectTemplate::Binary;
|
||||||
let mut link_c_paths = Vec::new();
|
let mut link_c_paths = Vec::new();
|
||||||
let mut test_filter = None;
|
let mut test_filter = None;
|
||||||
|
let mut test_list = false;
|
||||||
let mut run_args = Vec::new();
|
let mut run_args = Vec::new();
|
||||||
let mut no_color = false;
|
let mut no_color = false;
|
||||||
let command_line = raw_args.join(" ");
|
let command_line = raw_args.join(" ");
|
||||||
@ -1345,6 +1359,17 @@ fn parse_args(raw_args: &[String]) -> Result<Args, ParseError> {
|
|||||||
command_line: command_line.clone(),
|
command_line: command_line.clone(),
|
||||||
})?);
|
})?);
|
||||||
}
|
}
|
||||||
|
"--list" => {
|
||||||
|
if test_list {
|
||||||
|
return parse_error(
|
||||||
|
"`--list` was provided more than once",
|
||||||
|
manifest_path,
|
||||||
|
diagnostics,
|
||||||
|
command_line,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
test_list = true;
|
||||||
|
}
|
||||||
"check" | "fmt" | "test" | "build" | "run" | "clean" | "new" | "doc" | "symbols"
|
"check" | "fmt" | "test" | "build" | "run" | "clean" | "new" | "doc" | "symbols"
|
||||||
if path.is_none() =>
|
if path.is_none() =>
|
||||||
{
|
{
|
||||||
@ -1464,6 +1489,15 @@ fn parse_args(raw_args: &[String]) -> Result<Args, ParseError> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if test_list && mode != Mode::RunTests {
|
||||||
|
return parse_error(
|
||||||
|
"`--list` is only supported with `test` and `--run-tests`",
|
||||||
|
manifest_path,
|
||||||
|
diagnostics,
|
||||||
|
command_line,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if !run_args.is_empty() && mode != Mode::Run {
|
if !run_args.is_empty() && mode != Mode::Run {
|
||||||
return parse_error(
|
return parse_error(
|
||||||
"`--` program arguments are only supported with `run`",
|
"`--` program arguments are only supported with `run`",
|
||||||
@ -1515,6 +1549,7 @@ fn parse_args(raw_args: &[String]) -> Result<Args, ParseError> {
|
|||||||
project_template,
|
project_template,
|
||||||
link_c_paths,
|
link_c_paths,
|
||||||
test_filter,
|
test_filter,
|
||||||
|
test_list,
|
||||||
run_args,
|
run_args,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -1588,6 +1623,7 @@ fn exit_parse_error(err: ParseError, command_line: &str) -> ! {
|
|||||||
project_template: scaffold::ProjectTemplate::Binary,
|
project_template: scaffold::ProjectTemplate::Binary,
|
||||||
link_c_paths: Vec::new(),
|
link_c_paths: Vec::new(),
|
||||||
test_filter: None,
|
test_filter: None,
|
||||||
|
test_list: false,
|
||||||
run_args: Vec::new(),
|
run_args: Vec::new(),
|
||||||
};
|
};
|
||||||
write_manifest_or_exit(
|
write_manifest_or_exit(
|
||||||
@ -2567,6 +2603,6 @@ fn normalized_output_path(path: &str) -> Option<PathBuf> {
|
|||||||
|
|
||||||
fn print_usage() {
|
fn print_usage() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"usage: glagol [check|fmt|test|build|run|clean|symbols] [--json-diagnostics] [--no-color] [--manifest <path>] [--link-c <path>] [-o <path>] [--filter <substring>] <file.slo|project> [-- <program-args>...]\n glagol fmt [--check|--write] <file.slo|project>\n glagol new <project-dir> [--name <name>] [--template binary|library|workspace]\n glagol doc <file.slo|project> -o <dir>\n glagol symbols <file.slo|project|workspace>\n glagol [--emit=llvm|--format|--print-tree|--inspect-lowering=surface|--inspect-lowering=checked|--check-tests|--run-tests] [--json-diagnostics] [--no-color] [-o <path>] [--manifest <path>] [--filter <substring>] <file.slo>\n glagol --version"
|
"usage: glagol [check|fmt|test|build|run|clean|symbols] [--json-diagnostics] [--no-color] [--manifest <path>] [--link-c <path>] [-o <path>] [--filter <substring>] [--list] <file.slo|project> [-- <program-args>...]\n glagol fmt [--check|--write] <file.slo|project>\n glagol new <project-dir> [--name <name>] [--template binary|library|workspace]\n glagol doc <file.slo|project> -o <dir>\n glagol symbols <file.slo|project|workspace>\n glagol [--emit=llvm|--format|--print-tree|--inspect-lowering=surface|--inspect-lowering=checked|--check-tests|--run-tests] [--json-diagnostics] [--no-color] [-o <path>] [--manifest <path>] [--filter <substring>] [--list] <file.slo>\n glagol --version"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -452,6 +452,26 @@ pub fn run_tests(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_tests(
|
||||||
|
input: &str,
|
||||||
|
filter: Option<&str>,
|
||||||
|
) -> Result<ProjectTestSuccess, ProjectTestFailure> {
|
||||||
|
let checked = load_checked_project(input, false).map_err(|failure| ProjectTestFailure {
|
||||||
|
diagnostics: failure.diagnostics,
|
||||||
|
report: None,
|
||||||
|
sources: failure.sources,
|
||||||
|
artifact: failure.artifact,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let success = test_runner::list(&checked.program, filter);
|
||||||
|
Ok(ProjectTestSuccess {
|
||||||
|
output: success.output,
|
||||||
|
report: success.report,
|
||||||
|
sources: checked.sources,
|
||||||
|
artifact: checked.artifact,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
struct CheckedProject {
|
struct CheckedProject {
|
||||||
program: CheckedProgram,
|
program: CheckedProgram,
|
||||||
sources: Vec<SourceFile>,
|
sources: Vec<SourceFile>,
|
||||||
|
|||||||
@ -173,6 +173,39 @@ pub fn run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list(program: &CheckedProgram, filter: Option<&str>) -> TestRunSuccess {
|
||||||
|
let mut output = String::new();
|
||||||
|
let mut report = TestReport {
|
||||||
|
total_discovered: program.tests.len(),
|
||||||
|
selected: 0,
|
||||||
|
passed: 0,
|
||||||
|
failed: 0,
|
||||||
|
skipped: 0,
|
||||||
|
filter: filter.map(str::to_string),
|
||||||
|
};
|
||||||
|
|
||||||
|
for test in &program.tests {
|
||||||
|
output.push_str("test ");
|
||||||
|
write_test_name(&test.name, &mut output);
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
if !test.name.contains(filter) {
|
||||||
|
report.skipped += 1;
|
||||||
|
output.push_str(" ... skipped\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report.selected += 1;
|
||||||
|
output.push_str(" ... selected\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push_str(&format!("{} test(s) selected", report.selected));
|
||||||
|
write_report_suffix(&report, &mut output);
|
||||||
|
output.push('\n');
|
||||||
|
|
||||||
|
TestRunSuccess { output, report }
|
||||||
|
}
|
||||||
|
|
||||||
fn write_report_suffix(report: &TestReport, output: &mut String) {
|
fn write_report_suffix(report: &TestReport, output: &mut String) {
|
||||||
output.push_str(&format!(
|
output.push_str(&format!(
|
||||||
" (total_discovered {}, selected {}, passed {}, failed {}, skipped {}",
|
" (total_discovered {}, selected {}, passed {}, failed {}, skipped {}",
|
||||||
@ -181,6 +214,8 @@ fn write_report_suffix(report: &TestReport, output: &mut String) {
|
|||||||
if let Some(filter) = report.filter.as_deref() {
|
if let Some(filter) = report.filter.as_deref() {
|
||||||
output.push_str(", filter ");
|
output.push_str(", filter ");
|
||||||
write_test_name(filter, output);
|
write_test_name(filter, output);
|
||||||
|
} else {
|
||||||
|
output.push_str(", filter none");
|
||||||
}
|
}
|
||||||
output.push(')');
|
output.push(')');
|
||||||
}
|
}
|
||||||
|
|||||||
384
compiler/tests/test_discovery_beta19.rs
Normal file
384
compiler/tests/test_discovery_beta19.rs
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::PathBuf,
|
||||||
|
process::{Command, Output},
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
time::{SystemTime, UNIX_EPOCH},
|
||||||
|
};
|
||||||
|
|
||||||
|
static NEXT_FIXTURE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn file_list_preserves_order_and_does_not_execute_bodies() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"file-list",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(test "alpha first"
|
||||||
|
true)
|
||||||
|
|
||||||
|
(test "beta would fail"
|
||||||
|
false)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol(["test".as_ref(), "--list".as_ref(), fixture.as_os_str()]);
|
||||||
|
|
||||||
|
assert_success_stdout(
|
||||||
|
"file test list",
|
||||||
|
output,
|
||||||
|
"test \"alpha first\" ... selected\n\
|
||||||
|
test \"beta would fail\" ... selected\n\
|
||||||
|
2 test(s) selected (total_discovered 2, selected 2, passed 0, failed 0, skipped 0, filter none)\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn file_list_filter_marks_selected_and_skipped_in_order() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"file-list-filter",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(test "alpha first"
|
||||||
|
false)
|
||||||
|
|
||||||
|
(test "beta second"
|
||||||
|
false)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol([
|
||||||
|
"test".as_ref(),
|
||||||
|
"--list".as_ref(),
|
||||||
|
fixture.as_os_str(),
|
||||||
|
"--filter".as_ref(),
|
||||||
|
"beta".as_ref(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_success_stdout(
|
||||||
|
"file filtered test list",
|
||||||
|
output,
|
||||||
|
"test \"alpha first\" ... skipped\n\
|
||||||
|
test \"beta second\" ... selected\n\
|
||||||
|
1 test(s) selected (total_discovered 2, selected 1, passed 0, failed 0, skipped 1, filter \"beta\")\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn legacy_run_tests_list_matches_test_subcommand_list() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"legacy-list",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(test "legacy first"
|
||||||
|
false)
|
||||||
|
|
||||||
|
(test "legacy second"
|
||||||
|
false)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let subcommand = run_glagol(["test".as_ref(), "--list".as_ref(), fixture.as_os_str()]);
|
||||||
|
let legacy = run_glagol([
|
||||||
|
"--run-tests".as_ref(),
|
||||||
|
"--list".as_ref(),
|
||||||
|
fixture.as_os_str(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_success("test --list", &subcommand);
|
||||||
|
assert_success("legacy --run-tests --list", &legacy);
|
||||||
|
assert_eq!(
|
||||||
|
legacy.stdout, subcommand.stdout,
|
||||||
|
"legacy list output differed from test subcommand"
|
||||||
|
);
|
||||||
|
assert!(legacy.stderr.is_empty(), "legacy list wrote stderr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn project_list_preserves_topological_order_and_filter_counts() {
|
||||||
|
let project = write_project(
|
||||||
|
"project-list",
|
||||||
|
&[(
|
||||||
|
"provider",
|
||||||
|
"(module provider (export value))\n\n\
|
||||||
|
(fn value () -> i32\n 1)\n\n\
|
||||||
|
(test \"provider first\"\n false)\n",
|
||||||
|
)],
|
||||||
|
"(module main)\n\n\
|
||||||
|
(import provider (value))\n\n\
|
||||||
|
(fn main () -> i32\n (value))\n\n\
|
||||||
|
(test \"consumer second\"\n false)\n",
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol([
|
||||||
|
"test".as_ref(),
|
||||||
|
"--list".as_ref(),
|
||||||
|
project.as_os_str(),
|
||||||
|
"--filter".as_ref(),
|
||||||
|
"consumer".as_ref(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert_success_stdout(
|
||||||
|
"project filtered list",
|
||||||
|
output,
|
||||||
|
"test \"provider first\" ... skipped\n\
|
||||||
|
test \"consumer second\" ... selected\n\
|
||||||
|
1 test(s) selected (total_discovered 2, selected 1, passed 0, failed 0, skipped 1, filter \"consumer\")\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn workspace_list_preserves_package_order_without_running_tests() {
|
||||||
|
let workspace = write_workspace(
|
||||||
|
"workspace-list",
|
||||||
|
"[workspace]\nmembers = [\"packages/app\", \"packages/util\"]\n",
|
||||||
|
&[
|
||||||
|
WorkspacePackageSpec {
|
||||||
|
member: "packages/util",
|
||||||
|
manifest: "[package]\nname = \"util\"\nversion = \"0.1.0\"\n",
|
||||||
|
modules: &[(
|
||||||
|
"util",
|
||||||
|
"(module util (export answer))\n\n\
|
||||||
|
(fn answer () -> i32\n 41)\n\n\
|
||||||
|
(test \"util provider first\"\n false)\n",
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
WorkspacePackageSpec {
|
||||||
|
member: "packages/app",
|
||||||
|
manifest: "[package]\nname = \"app\"\nversion = \"0.1.0\"\n\n[dependencies]\nutil = { path = \"../util\" }\n",
|
||||||
|
modules: &[(
|
||||||
|
"main",
|
||||||
|
"(module main)\n\n\
|
||||||
|
(import util.util (answer))\n\n\
|
||||||
|
(fn main () -> i32\n (answer))\n\n\
|
||||||
|
(test \"app consumer second\"\n false)\n",
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol(["test".as_ref(), "--list".as_ref(), workspace.as_os_str()]);
|
||||||
|
|
||||||
|
assert_success_stdout(
|
||||||
|
"workspace list",
|
||||||
|
output,
|
||||||
|
"test \"util provider first\" ... selected\n\
|
||||||
|
test \"app consumer second\" ... selected\n\
|
||||||
|
2 test(s) selected (total_discovered 2, selected 2, passed 0, failed 0, skipped 0, filter none)\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ordinary_test_output_stays_byte_stable() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"ordinary-test",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(test "alpha first"
|
||||||
|
true)
|
||||||
|
|
||||||
|
(test "beta second"
|
||||||
|
true)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let subcommand = run_glagol(["test".as_ref(), fixture.as_os_str()]);
|
||||||
|
assert_success_stdout(
|
||||||
|
"ordinary test",
|
||||||
|
subcommand,
|
||||||
|
"test \"alpha first\" ... ok\n\
|
||||||
|
test \"beta second\" ... ok\n\
|
||||||
|
2 test(s) passed\n",
|
||||||
|
);
|
||||||
|
|
||||||
|
let legacy = run_glagol(["--run-tests".as_ref(), fixture.as_os_str()]);
|
||||||
|
assert_success_stdout(
|
||||||
|
"ordinary legacy run-tests",
|
||||||
|
legacy,
|
||||||
|
"test \"alpha first\" ... ok\n\
|
||||||
|
test \"beta second\" ... ok\n\
|
||||||
|
2 test(s) passed\n",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_mode_reuses_checked_diagnostics_for_invalid_tests() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"invalid-list",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(test "not bool"
|
||||||
|
1)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol(["test".as_ref(), "--list".as_ref(), fixture.as_os_str()]);
|
||||||
|
|
||||||
|
assert_failure_stderr_contains(
|
||||||
|
"invalid list",
|
||||||
|
&output,
|
||||||
|
&[
|
||||||
|
"TestExpressionNotBool",
|
||||||
|
"Expected:",
|
||||||
|
"bool",
|
||||||
|
"Found:",
|
||||||
|
"i32",
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
output.stdout.is_empty(),
|
||||||
|
"invalid list wrote stdout:\n{}",
|
||||||
|
String::from_utf8_lossy(&output.stdout)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_flag_is_rejected_outside_test_mode() {
|
||||||
|
let fixture = write_fixture(
|
||||||
|
"list-outside-test",
|
||||||
|
r#"
|
||||||
|
(module main)
|
||||||
|
|
||||||
|
(fn main () -> i32
|
||||||
|
0)
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let output = run_glagol(["check".as_ref(), "--list".as_ref(), fixture.as_os_str()]);
|
||||||
|
|
||||||
|
assert_failure_stderr_contains(
|
||||||
|
"check --list",
|
||||||
|
&output,
|
||||||
|
&["`--list` is only supported with `test` and `--run-tests`"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_fixture(name: &str, source: &str) -> PathBuf {
|
||||||
|
let path = unique_path(name).with_extension("slo");
|
||||||
|
fs::write(&path, source).expect("write fixture");
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_project(name: &str, modules: &[(&str, &str)], main: &str) -> PathBuf {
|
||||||
|
let root = unique_path(name);
|
||||||
|
let src = root.join("src");
|
||||||
|
fs::create_dir_all(&src).expect("create project src");
|
||||||
|
fs::write(
|
||||||
|
root.join("slovo.toml"),
|
||||||
|
format!(
|
||||||
|
"[project]\nname = \"{}\"\nsource_root = \"src\"\nentry = \"main\"\n",
|
||||||
|
name
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.expect("write project manifest");
|
||||||
|
fs::write(src.join("main.slo"), main).expect("write project main");
|
||||||
|
for (module, source) in modules {
|
||||||
|
fs::write(src.join(format!("{}.slo", module)), source).expect("write project module");
|
||||||
|
}
|
||||||
|
root
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WorkspacePackageSpec<'a> {
|
||||||
|
member: &'a str,
|
||||||
|
manifest: &'a str,
|
||||||
|
modules: &'a [(&'a str, &'a str)],
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_workspace(
|
||||||
|
name: &str,
|
||||||
|
workspace_manifest: &str,
|
||||||
|
packages: &[WorkspacePackageSpec<'_>],
|
||||||
|
) -> PathBuf {
|
||||||
|
let root = unique_path(name);
|
||||||
|
fs::create_dir_all(&root).expect("create workspace root");
|
||||||
|
fs::write(root.join("slovo.toml"), workspace_manifest).expect("write workspace manifest");
|
||||||
|
for package in packages {
|
||||||
|
let package_root = root.join(package.member);
|
||||||
|
let src = package_root.join("src");
|
||||||
|
fs::create_dir_all(&src).expect("create workspace package src");
|
||||||
|
fs::write(package_root.join("slovo.toml"), package.manifest)
|
||||||
|
.expect("write workspace package manifest");
|
||||||
|
for (module, source) in package.modules {
|
||||||
|
fs::write(src.join(format!("{}.slo", module)), source)
|
||||||
|
.expect("write workspace package module");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unique_path(name: &str) -> PathBuf {
|
||||||
|
let id = NEXT_FIXTURE_ID.fetch_add(1, Ordering::SeqCst);
|
||||||
|
let nanos = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.map(|duration| duration.as_nanos())
|
||||||
|
.unwrap_or(0);
|
||||||
|
std::env::temp_dir().join(format!(
|
||||||
|
"glagol-test-discovery-beta19-{}-{}-{}-{}",
|
||||||
|
std::process::id(),
|
||||||
|
nanos,
|
||||||
|
id,
|
||||||
|
name
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_glagol<I, S>(args: I) -> Output
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = S>,
|
||||||
|
S: AsRef<std::ffi::OsStr>,
|
||||||
|
{
|
||||||
|
Command::new(env!("CARGO_BIN_EXE_glagol"))
|
||||||
|
.args(args)
|
||||||
|
.output()
|
||||||
|
.expect("run glagol")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_success(context: &str, output: &Output) {
|
||||||
|
assert!(
|
||||||
|
output.status.success(),
|
||||||
|
"{} failed\nstdout:\n{}\nstderr:\n{}",
|
||||||
|
context,
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_success_stdout(context: &str, output: Output, expected: &str) {
|
||||||
|
assert_success(context, &output);
|
||||||
|
assert_eq!(
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
expected,
|
||||||
|
"{} stdout mismatch",
|
||||||
|
context
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
output.stderr.is_empty(),
|
||||||
|
"{} wrote stderr:\n{}",
|
||||||
|
context,
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_failure_stderr_contains(context: &str, output: &Output, expected: &[&str]) {
|
||||||
|
assert!(
|
||||||
|
!output.status.success(),
|
||||||
|
"{} unexpectedly succeeded\nstdout:\n{}\nstderr:\n{}",
|
||||||
|
context,
|
||||||
|
String::from_utf8_lossy(&output.stdout),
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
for needle in expected {
|
||||||
|
assert!(
|
||||||
|
stderr.contains(needle),
|
||||||
|
"{} stderr missing `{}`:\n{}",
|
||||||
|
context,
|
||||||
|
needle,
|
||||||
|
stderr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -41,6 +41,21 @@ Released in `1.0.0-beta.1`: `glagol run`, `glagol clean`,
|
|||||||
installed std/runtime discovery, README coverage, focused DX tests, and a
|
installed std/runtime discovery, README coverage, focused DX tests, and a
|
||||||
concise release-gate success line.
|
concise release-gate success line.
|
||||||
|
|
||||||
|
Released in `1.0.0-beta.19`: test discovery and user-project conformance
|
||||||
|
tooling. The scope adds the
|
||||||
|
`glagol test --list <file|project|workspace>` command and legacy
|
||||||
|
`glagol --run-tests --list <file>` so users and tooling can list
|
||||||
|
checked/discovered tests without executing test bodies. It preserves existing
|
||||||
|
single-file, project, and workspace ordering, honors
|
||||||
|
`--filter <substring>`, and keeps the output beta-scoped rather than a stable
|
||||||
|
public schema.
|
||||||
|
|
||||||
|
Beta19 non-scope: no parallel test execution, retries, tags/groups, coverage
|
||||||
|
reports, event streams, stable artifact-manifest or Markdown schema freeze,
|
||||||
|
LSP/watch behavior, SARIF/daemon protocols, JSON expansion, runtime helper
|
||||||
|
names, source-language syntax, package registries, semver solving, or
|
||||||
|
performance claims.
|
||||||
|
|
||||||
Why first: it reduces friction for every later feature and gives users a better
|
Why first: it reduces friction for every later feature and gives users a better
|
||||||
way to exercise the beta.
|
way to exercise the beta.
|
||||||
|
|
||||||
|
|||||||
@ -10,10 +10,41 @@ integration/readiness release, not the first real beta.
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
Next scoped Glagol work is expected to continue after the `1.0.0-beta.18`
|
No active unreleased compiler scope is documented here yet.
|
||||||
JSON string token parsing foundation.
|
|
||||||
|
|
||||||
No unreleased compiler scope is committed here yet.
|
## 1.0.0-beta.19
|
||||||
|
|
||||||
|
Release label: `1.0.0-beta.19`
|
||||||
|
|
||||||
|
Release date: 2026-05-23
|
||||||
|
|
||||||
|
Release state: test discovery and user-project conformance foundation
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
The beta.19 compiler/tooling contract adds deterministic list-only test
|
||||||
|
discovery without changing normal test execution output:
|
||||||
|
|
||||||
|
- `glagol test --list <file|project|workspace>`
|
||||||
|
- `glagol --run-tests --list <file>` for legacy single-file test execution
|
||||||
|
|
||||||
|
- Bump the `glagol` compiler package version to `1.0.0-beta.19`.
|
||||||
|
- Reuse the same checked discovery path as normal `glagol test` for file,
|
||||||
|
project, and workspace inputs.
|
||||||
|
- Preserve current file/project/workspace test ordering.
|
||||||
|
- Honor `--filter <substring>` by marking selected and skipped discovered
|
||||||
|
tests without executing test bodies or triggering runtime/test side effects.
|
||||||
|
- Keep normal `glagol test` and legacy `glagol --run-tests` output unchanged
|
||||||
|
when `--list` is absent.
|
||||||
|
- Add focused beta19 release-gate coverage for test discovery.
|
||||||
|
|
||||||
|
### Explicit Deferrals
|
||||||
|
|
||||||
|
This release does not implement parallel test execution, retries, tags/groups, coverage,
|
||||||
|
event streams, stable artifact-manifest or Markdown schema freezes,
|
||||||
|
LSP/watch/SARIF/daemon protocols, JSON expansion, runtime helper names,
|
||||||
|
source-language syntax, package registries, semver solving, and performance
|
||||||
|
claims.
|
||||||
|
|
||||||
## 1.0.0-beta.18
|
## 1.0.0-beta.18
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,8 @@ general-purpose beta release.
|
|||||||
|
|
||||||
A Glagol feature is done only when it has parser/lowerer support, checker behavior, diagnostics for invalid forms, backend behavior or explicit unsupported diagnostics, and tests.
|
A Glagol feature is done only when it has parser/lowerer support, checker behavior, diagnostics for invalid forms, backend behavior or explicit unsupported diagnostics, and tests.
|
||||||
|
|
||||||
Current stage: `1.0.0-beta.18`, released on 2026-05-23 as a JSON string
|
Current stage: `1.0.0-beta.19`, released on 2026-05-23 as a test discovery
|
||||||
token parsing runtime foundation. It keeps the
|
and user-project conformance foundation. It keeps the
|
||||||
`1.0.0-beta` language/compiler support baseline and includes the
|
`1.0.0-beta` language/compiler support baseline and includes the
|
||||||
`1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2` runtime/resource
|
`1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2` runtime/resource
|
||||||
foundation release, the `1.0.0-beta.3` standard-library stabilization release,
|
foundation release, the `1.0.0-beta.3` standard-library stabilization release,
|
||||||
@ -89,16 +89,24 @@ diagnostics. It keeps object parsing, array parsing, recursive values,
|
|||||||
tokenizers, Unicode escape decoding, Unicode normalization, streaming, schema
|
tokenizers, Unicode escape decoding, Unicode normalization, streaming, schema
|
||||||
validation, embedded NUL support in the current null-terminated string ABI, and
|
validation, embedded NUL support in the current null-terminated string ABI, and
|
||||||
stable JSON APIs deferred.
|
stable JSON APIs deferred.
|
||||||
|
The beta.19 compiler/tooling slice adds
|
||||||
|
`glagol test --list <file|project|workspace>` and legacy
|
||||||
|
`glagol --run-tests --list <file>` support. The list action reuses the same
|
||||||
|
checked discovery path as normal test execution, preserves existing
|
||||||
|
single-file, project, and workspace ordering, honors `--filter <substring>`,
|
||||||
|
and avoids executing test bodies. It keeps normal test execution output
|
||||||
|
unchanged when `--list` is absent.
|
||||||
|
|
||||||
Next stage target: post-`1.0.0-beta.18` developer-experience, package, and
|
Generic vectors, generic collections, maps, sets, generic stdlib dispatch,
|
||||||
collection/generic planning. Generic vectors, generic collections, maps, sets,
|
runtime collection changes, collection unification, stable human diagnostic
|
||||||
generic stdlib dispatch, runtime collection changes, collection unification,
|
text, stable artifact-manifest or Markdown schema freezes, LSP/watch
|
||||||
stable human diagnostic text, stable Markdown schema, LSP/watch protocols,
|
protocols, SARIF/daemon protocols, re-exports/globs/hierarchical modules,
|
||||||
SARIF/daemon protocols, re-exports/globs/hierarchical modules, registry
|
registry semantics, semver solving, mutable vectors, stable slice/view APIs,
|
||||||
semantics, mutable vectors, stable slice/view APIs, tokenizers, broader JSON
|
tokenizers, broader JSON parsing, runtime helper names, source-language
|
||||||
parsing, iterators, performance claims, ABI/layout stability, and a stable
|
syntax, parallel test execution, retries, tags/groups, coverage/event streams,
|
||||||
stdlib/API compatibility freeze remain unimplemented until a later scoped
|
performance claims, ABI/layout stability, and a stable stdlib/API
|
||||||
contract promotes them explicitly.
|
compatibility freeze remain unimplemented until a later scoped contract
|
||||||
|
promotes them explicitly.
|
||||||
|
|
||||||
The final experimental precursor scope is `exp-125`. Its unsigned direct-value
|
The final experimental precursor scope is `exp-125`. Its unsigned direct-value
|
||||||
flow, parse/format runtime lanes, and matching staged stdlib helper breadth
|
flow, parse/format runtime lanes, and matching staged stdlib helper breadth
|
||||||
|
|||||||
@ -8,7 +8,7 @@ Historical `exp-*` releases listed here are experimental maturity milestones.
|
|||||||
The pushed tag `v2.0.0-beta.1` is historical. It is now documented as an
|
The pushed tag `v2.0.0-beta.1` is historical. It is now documented as an
|
||||||
experimental integration/readiness release, not as a beta maturity claim.
|
experimental integration/readiness release, not as a beta maturity claim.
|
||||||
|
|
||||||
The current release is `1.0.0-beta.18`, published on 2026-05-23. It keeps the
|
The current release is `1.0.0-beta.19`, published on 2026-05-23. It keeps the
|
||||||
`1.0.0-beta` language surface, includes the first post-beta tooling/install
|
`1.0.0-beta` language surface, includes the first post-beta tooling/install
|
||||||
hardening bundle from `1.0.0-beta.1`, and adds the first runtime/resource
|
hardening bundle from `1.0.0-beta.1`, and adds the first runtime/resource
|
||||||
foundation bundle from `1.0.0-beta.2` plus the first standard-library
|
foundation bundle from `1.0.0-beta.2` plus the first standard-library
|
||||||
@ -28,11 +28,41 @@ collection alias unification and generic reservation slice from
|
|||||||
collection ledger from `1.0.0-beta.15`, plus the string scanning and token
|
collection ledger from `1.0.0-beta.15`, plus the string scanning and token
|
||||||
boundary foundation from `1.0.0-beta.16`, and the JSON primitive scalar
|
boundary foundation from `1.0.0-beta.16`, and the JSON primitive scalar
|
||||||
parsing foundation from `1.0.0-beta.17`, plus the JSON string token parsing
|
parsing foundation from `1.0.0-beta.17`, plus the JSON string token parsing
|
||||||
foundation from `1.0.0-beta.18`.
|
foundation from `1.0.0-beta.18`, and the test discovery and user-project
|
||||||
|
conformance foundation from `1.0.0-beta.19`.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
No unreleased language scope is committed here yet.
|
No active unreleased language scope is documented here yet.
|
||||||
|
|
||||||
|
## 1.0.0-beta.19
|
||||||
|
|
||||||
|
Release label: `1.0.0-beta.19`
|
||||||
|
|
||||||
|
Release name: Test Discovery And User-Project Conformance Foundation
|
||||||
|
|
||||||
|
Release date: 2026-05-23
|
||||||
|
|
||||||
|
Status: released beta tooling/conformance foundation on the `1.0.0-beta`
|
||||||
|
language baseline.
|
||||||
|
|
||||||
|
The beta19 contract is tooling/conformance only. It adds deterministic test
|
||||||
|
discovery listing for:
|
||||||
|
|
||||||
|
- `glagol test --list <file|project|workspace>`
|
||||||
|
- `glagol --run-tests --list <file>` for the legacy single-file test path
|
||||||
|
|
||||||
|
List mode parses, lowers, type-checks, and discovers tests through the same
|
||||||
|
front-end path as normal test execution, then prints the discovered/selected
|
||||||
|
tests without evaluating their bodies. It preserves current single-file,
|
||||||
|
project, and workspace test ordering, honors `--filter <substring>`, and
|
||||||
|
leaves normal `glagol test` execution output unchanged.
|
||||||
|
|
||||||
|
This release does not add source-language syntax, runtime helper names, JSON
|
||||||
|
expansion, parallel test execution, retries, tags/groups, coverage reports,
|
||||||
|
event streams, stable manifest schemas, stable Markdown schemas, LSP/watch
|
||||||
|
behavior, SARIF/daemon protocols, package registries, semver solving, or
|
||||||
|
performance claims.
|
||||||
|
|
||||||
## 1.0.0-beta.18
|
## 1.0.0-beta.18
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,9 @@ Long-horizon planning lives in
|
|||||||
release train from the historical `v2.0.0-beta.1` tag toward and beyond the
|
release train from the historical `v2.0.0-beta.1` tag toward and beyond the
|
||||||
first real general-purpose beta Slovo contract.
|
first real general-purpose beta Slovo contract.
|
||||||
|
|
||||||
Current stage: `1.0.0-beta.18`, released on 2026-05-23 as a post-beta JSON
|
Current stage: `1.0.0-beta.19`, released on 2026-05-23 as a post-beta test
|
||||||
string token parsing foundation. It keeps the `1.0.0-beta` language
|
discovery and user-project conformance foundation. It keeps the
|
||||||
|
`1.0.0-beta` language
|
||||||
contract and includes the `1.0.0-beta.1` tooling hardening release, the
|
contract and includes the `1.0.0-beta.1` tooling hardening release, the
|
||||||
`1.0.0-beta.2` runtime/resource foundation release, the `1.0.0-beta.3`
|
`1.0.0-beta.2` runtime/resource foundation release, the `1.0.0-beta.3`
|
||||||
standard-library stabilization release, the `1.0.0-beta.4`
|
standard-library stabilization release, the `1.0.0-beta.4`
|
||||||
@ -25,7 +26,8 @@ documentation, `1.0.0-beta.12` concrete vector helper parity,
|
|||||||
benchmark suite catalog and metadata gate, `1.0.0-beta.15` reserved generic
|
benchmark suite catalog and metadata gate, `1.0.0-beta.15` reserved generic
|
||||||
collection boundary hardening and collection ledger, and `1.0.0-beta.16`
|
collection boundary hardening and collection ledger, and `1.0.0-beta.16`
|
||||||
string scanning and token boundary helpers, `1.0.0-beta.17` JSON primitive
|
string scanning and token boundary helpers, `1.0.0-beta.17` JSON primitive
|
||||||
scalar token parsing, and `1.0.0-beta.18` JSON string token parsing.
|
scalar token parsing, `1.0.0-beta.18` JSON string token parsing, and
|
||||||
|
`1.0.0-beta.19` test discovery and user-project conformance tooling.
|
||||||
|
|
||||||
`1.0.0-beta.16` adds `std.string` source facades and examples for
|
`1.0.0-beta.16` adds `std.string` source facades and examples for
|
||||||
`byte_at_result`, `slice_result`, `starts_with`, and `ends_with`. These helpers
|
`byte_at_result`, `slice_result`, `starts_with`, and `ends_with`. These helpers
|
||||||
@ -56,16 +58,23 @@ APIs, additional runtime names, Unicode/grapheme string semantics, timing
|
|||||||
publication, performance claims, stable benchmark JSON schema, and package
|
publication, performance claims, stable benchmark JSON schema, and package
|
||||||
registry semantics remain deferred.
|
registry semantics remain deferred.
|
||||||
|
|
||||||
Next stage target: post-`1.0.0-beta.18` continuation from
|
`1.0.0-beta.19` is a tooling/conformance slice, not a new source-language
|
||||||
developer-experience,
|
feature. It adds the `glagol test --list <file|project|workspace>` command
|
||||||
package, benchmark metadata, collection, or string-processing planning without
|
plus legacy `glagol --run-tests --list <file>`: parse, lower, type-check, and
|
||||||
claiming executable generics, an LSP/watch protocol, SARIF/daemon protocol,
|
discover tests through the same front-end path as normal test execution, then
|
||||||
stable Markdown schema, registry semantics, stable benchmark JSON schema,
|
list the discovered/selected tests without evaluating test bodies. The mode
|
||||||
stable `1.0.0` diagnostics freeze, stable standard-library/API compatibility
|
preserves current single-file, project, and workspace ordering, honors
|
||||||
freeze, mutable vectors, language slice/view APIs, additional runtime names,
|
`--filter <substring>`, and leaves normal `glagol test` execution behavior
|
||||||
Unicode/grapheme semantics, full JSON parsing, maps/sets, iterators, or
|
unchanged.
|
||||||
performance claims until the exact scope is frozen from the manifest and
|
|
||||||
roadmap.
|
The beta19 tooling scope does not claim executable generics, maps/sets,
|
||||||
|
iterators, runtime helper names, source-language syntax, JSON expansion,
|
||||||
|
parallel test execution, retries, tags/groups, coverage/event streams,
|
||||||
|
LSP/watch protocols, SARIF/daemon protocols, stable artifact-manifest or
|
||||||
|
Markdown schemas, stable benchmark JSON schema, stable `1.0.0` diagnostics
|
||||||
|
freeze, stable standard-library/API compatibility freeze, registry semantics,
|
||||||
|
semver solving, performance claims, mutable vectors, language slice/view APIs,
|
||||||
|
additional runtime names, or Unicode/grapheme semantics.
|
||||||
|
|
||||||
The final experimental precursor scope is `exp-125`, defined in
|
The final experimental precursor scope is `exp-125`, defined in
|
||||||
`.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its
|
`.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its
|
||||||
|
|||||||
@ -9,8 +9,9 @@ diagnostic catalog and schema policy update, and `1.0.0-beta.14` benchmark
|
|||||||
suite catalog and metadata gate, `1.0.0-beta.15` reserved generic collection
|
suite catalog and metadata gate, `1.0.0-beta.15` reserved generic collection
|
||||||
boundary hardening and collection ledger, `1.0.0-beta.16` string scanning
|
boundary hardening and collection ledger, `1.0.0-beta.16` string scanning
|
||||||
and token boundary foundation, `1.0.0-beta.17` JSON primitive scalar parsing
|
and token boundary foundation, `1.0.0-beta.17` JSON primitive scalar parsing
|
||||||
foundation, and `1.0.0-beta.18` JSON string token
|
foundation, `1.0.0-beta.18` JSON string token parsing foundation, and
|
||||||
parsing foundation. The language contract
|
`1.0.0-beta.19` test discovery and user-project conformance tooling. The
|
||||||
|
language contract
|
||||||
integrates
|
integrates
|
||||||
promoted language slices through `exp-125` and the historical publication
|
promoted language slices through `exp-125` and the historical publication
|
||||||
baseline through `exp-123`. `1.0.0-beta` is the first real general-purpose
|
baseline through `exp-123`. `1.0.0-beta` is the first real general-purpose
|
||||||
@ -217,6 +218,16 @@ Current v1 release surface and explicit experimental targets:
|
|||||||
APIs, recursive `JsonValue`, Unicode escape decoding/normalization, embedded
|
APIs, recursive `JsonValue`, Unicode escape decoding/normalization, embedded
|
||||||
NUL policy, stable ABI/layout, performance claims, and stable stdlib/API
|
NUL policy, stable ABI/layout, performance claims, and stable stdlib/API
|
||||||
freeze remain out of scope
|
freeze remain out of scope
|
||||||
|
- `1.0.0-beta.19` test discovery and user-project conformance target:
|
||||||
|
`glagol test --list <file|project|workspace>` and legacy
|
||||||
|
`glagol --run-tests --list <file>` list checked/discovered tests without
|
||||||
|
executing test bodies; list mode preserves current test ordering, honors
|
||||||
|
`--filter <substring>`, and remains beta tooling rather than a stable
|
||||||
|
schema. This target does not add source-language syntax, runtime helper
|
||||||
|
names, JSON expansion, parallel test execution, retries, tags/groups,
|
||||||
|
coverage/event streams, stable artifact-manifest or Markdown schemas,
|
||||||
|
LSP/watch behavior, SARIF/daemon protocols, package registries, semver
|
||||||
|
solving, or performance claims
|
||||||
- `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two
|
- `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two
|
||||||
`string` values and returns an immutable runtime-owned `string`; existing
|
`string` values and returns an immutable runtime-owned `string`; existing
|
||||||
string equality, length, printing, locals, parameters, returns, and calls work
|
string equality, length, printing, locals, parameters, returns, and calls work
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Do not edit this file by hand.
|
|||||||
## Stability Tiers
|
## Stability Tiers
|
||||||
|
|
||||||
- `beta-supported`: exported from `lib/std` and covered by source-search, promotion, or facade gates in the current beta line.
|
- `beta-supported`: exported from `lib/std` and covered by source-search, promotion, or facade gates in the current beta line.
|
||||||
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.18`; future releases may mark new helpers this way before they graduate.
|
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.19`; future releases may mark new helpers this way before they graduate.
|
||||||
- `internal`: helper names that are not exported from their module; they are intentionally omitted from this catalog.
|
- `internal`: helper names that are not exported from their module; they are intentionally omitted from this catalog.
|
||||||
|
|
||||||
The catalog is a beta API discovery aid, not a stable `1.0.0` standard-library freeze.
|
The catalog is a beta API discovery aid, not a stable `1.0.0` standard-library freeze.
|
||||||
|
|||||||
@ -69,6 +69,7 @@ cargo test --test reserved_generic_collection_beta15
|
|||||||
cargo test --test standard_string_scanning_beta16
|
cargo test --test standard_string_scanning_beta16
|
||||||
cargo test --test standard_json_scalar_parsing_beta17
|
cargo test --test standard_json_scalar_parsing_beta17
|
||||||
cargo test --test standard_json_string_parsing_beta18
|
cargo test --test standard_json_string_parsing_beta18
|
||||||
|
cargo test --test test_discovery_beta19
|
||||||
# Full cargo test includes unignored integration gates such as dx_v1_7,
|
# Full cargo test includes unignored integration gates such as dx_v1_7,
|
||||||
# beta_v2_0_0_beta_1, and beta_1_0_0.
|
# beta_v2_0_0_beta_1, and beta_1_0_0.
|
||||||
cargo test
|
cargo test
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user