Testing and validation
TinyFX makes several different claims: language checking, VM semantics, WGSL validity, native rendering, generated TypeScript parity, and browser WebGPU behavior. No single test proves all of them. This page maps the main layers to their evidence.
Baseline checks
Run the Rust workspace checks before broad changes:
cargo test --workspace
cargo clippy --workspace
cargo fmt --all -- --check
cargo check -p tinyfx-wasm --target wasm32-unknown-unknownUseful focused commands include:
cargo test -p tinyfx-compiler --test typecheck
cargo test -p tinyfx-compiler --test stages
cargo test -p tinyfx-compiler --test wgsl
cargo test -p tinyfx-vm --test exec
cargo test -p tinyfx-vm --test tfxb
cargo test -p tinyfx-runtime --test render
cargo test -p tinyfx-lspThe JavaScript workspace has its own checks:
pnpm --filter tinyfx build:wasm
pnpm --dir packages/tinyfx-runtime test
pnpm --dir apps/playground types
pnpm --dir editors/vscode packageThe WASM build is split into compiler/editor and runner artifacts. Rebuild it after a Rust change that affects the browser route; the playground’s ensure-script only builds missing outputs and is not a substitute for a deliberate rebuild after compiler/runtime work.
Test layers
| Claim | Main evidence | Primary locations |
|---|---|---|
| Tokens and syntax | Lexer/parser tests and diagnostic assertions | crates/tinyfx-compiler/tests/parser.rs, typecheck.rs |
| Imports and metadata | Multi-file compiler fixtures | imports.rs, metadata.rs |
| Stage legality | GPU/CPU call-chain and fragment restrictions | stages.rs |
| WGSL generation | Emitted shader/compute fixtures parsed and validated by naga | wgsl.rs |
| Physical pass DTOs | Strict compiler blueprints and generated JS parsers | physical_blueprint.rs, packages/tinyfx-runtime/test |
| Formatter safety | Token-stream equivalence, parseability, idempotency | format.rs |
| VM semantics | Headless bytecode execution with MockHost | crates/tinyfx-vm/tests/exec.rs |
| Serialization | Program round trips and incompatible-artifact errors | crates/tinyfx-vm/tests/tfxb.rs |
| Standard library CPU behavior | Embedded std execution and compiler coverage | stdlib.rs, std_exec.rs |
| Native rendering | Real wgpu frames and pixel readback | crates/tinyfx-runtime/tests/render.rs |
| Native async/media | Host adapter and lifecycle tests | async_text.rs, media_platform.rs |
| Editor behavior | Pure compiler IDE tests and LSP protocol tests | ide.rs, crates/tinyfx-lsp/tests/lsp.rs |
| Generated TypeScript | Emission/typechecking and VM-versus-Node differential fixtures | crates/tinyfx-vm/tests/typescript.rs |
| Browser platform/core | JavaScript runtime contract, platform, and WebGPU tests | packages/tinyfx-runtime/test |
The operation catalog also records target routing and the type of conformance
evidence associated with each operation. Generate its human-readable view with
tfx reference --format markdown instead of treating a narrative
API list as exhaustive.
What native validation proves
The CLI compiles source to a VM Program and validates every generated shader and compute blueprint through naga before reporting a successful check/build. This catches malformed WGSL and many type/interface errors without opening a window:
tfx check examples/fundamentals/cube/main.cube.tfx
tfx build examples/fundamentals/cube/main.cube.tfx --emit-wgsl out/It does not prove that a particular browser accepts the result. Chrome’s Tint validator performs uniformity analysis that can reject texture sampling in non-uniform control flow even when naga accepts it. Treat native WGSL validation and a browser smoke test as separate checks.
GPU tests and runtime smoke tests
The Rust renderer tests create a real GPU device, render to a target, and read pixels back. They skip themselves when no compatible adapter is available. That means a passing workspace test on a machine without an adapter does not prove a render path; inspect the output and run the GPU suite on an adapter when rendering behavior changed.
For a live example smoke test, run the CLI briefly and inspect its log:
./target/debug/tfx run examples/fundamentals/cube/main.cube.tfx > /tmp/tinyfx-cube.log 2>&1 &
pid=$!
sleep 5
kill "$pid"
rg -i 'error|panic' /tmp/tinyfx-cube.logwgpu validation failures often appear only after the runtime has submitted a frame, so a successful compile alone is not enough for render changes.
Generated-program evidence
Generated TypeScript has its own semantic and typechecking evidence. The generated JavaScript core must match TinyFX behavior for values, normalized errors, source spans, host commands, resource lifetimes, and supported GPU blueprints. VM-versus-Node differential fixtures test that boundary directly.
The generated WebGPU runtime is additionally tested as a normal TypeScript package: strict physical DTO parsers, uniform packing, resource state, device loss, platform lifecycle, assets, media, and browser adapters each have focused tests. Passing TypeScript compilation does not prove a real browser WebGPU adapter accepts the emitted WGSL, so retain browser smoke/parity tests for changed GPU paths.
Formatter and documentation checks
The formatter is intentionally protected by two independent properties:
- formatting must preserve the lexer token stream for explicitly terminated
input (implicit statement terminators are canonicalized to
;); and - the result must still parse.
The parse check protects adjacency-sensitive syntax such as adjacent greater-than tokens. Do not weaken it to a visual snapshot.
For documentation, avoid hard-coded test totals, artifact byte sizes, or format revision numbers unless a release record explicitly owns them. Those facts change more quickly than the architectural contracts documented here.