diff --git a/Justfile b/Justfile index fde5021..5cfd23f 100644 --- a/Justfile +++ b/Justfile @@ -54,9 +54,24 @@ check-craftos: # Local CI entry point used by Git hooks. ci: check-craftos check test -# Placeholder for future CraftOS-PC headless integration tests. -test: - @printf '%s\n' 'No CraftOS-PC headless integration tests yet.' +# Run CraftOS-PC headless smoke tests. Pass `--verbose` to list each test. +test *args: + @verbose=0; \ + for a in {{args}}; do [ "$a" = "--verbose" ] && verbose=1; done; \ + rom_arg=""; \ + if [ "$(uname -s)" = "Darwin" ]; then \ + rom_arg="--rom /Applications/CraftOS-PC.app/Contents/Resources"; \ + fi; \ + green=$(printf '\033[32m'); reset=$(printf '\033[0m'); red=$(printf '\033[31m'); \ + for script in tests/boot.lua tests/ready.lua; do \ + if craftos --headless $rom_arg --script "$script" | grep -q __READY__; then \ + [ "$verbose" -eq 1 ] && printf '%s\n' "${green}PASS${reset} $script"; \ + else \ + printf '%s\n' "${red}FAIL${reset} $script did not print __READY__" >&2; \ + exit 1; \ + fi; \ + done; \ + printf '%s\n' 'OK: smoke tests passed' # Lint all Lua source with luacheck. check: diff --git a/docs/adrs/adr-0005-craftos-pc-harness.md b/docs/adrs/adr-0005-craftos-pc-harness.md index 07db332..d921a97 100644 --- a/docs/adrs/adr-0005-craftos-pc-harness.md +++ b/docs/adrs/adr-0005-craftos-pc-harness.md @@ -33,12 +33,13 @@ The existing `CLAUDE.md` constraint ("Do not run Lua locally or add a test harne ## Consequences - Contributors must install CraftOS-PC before `just install` succeeds. The install guide makes this a 4-step copy/paste on macOS. -- Future smoke tests have a clear home: a script under `tests/` (or similar) driven by `craftos --cli --headless --script tests/smoke.lua`, called from `just test`. +- Headless smoke tests live under `tests/` and are driven by `just test`. Today there are two: `tests/boot.lua` (prints a marker and shuts down — proves the BIOS started) and `tests/ready.lua` (round-trips a `craftos-ready` event through `os.queueEvent` / `os.pullEventRaw` — proves the CC event queue works). Each is invoked as `craftos --headless --script ` and its stdout is grepped for `__READY__`. Adding a third test means dropping a Lua file in `tests/` and adding it to the loop in the `test:` recipe. +- The macOS install symlinks the binary into `/usr/local/bin`, which makes CraftOS-PC unable to auto-discover the ROM that ships inside the `.app` bundle (`Could not mount ROM`). The `test:` recipe works around this by passing `--rom /Applications/CraftOS-PC.app/Contents/Resources` on Darwin. Linux (AppImage) and Windows (installer) auto-discover correctly, so no flag is passed there. - The harness version becomes a project-level concern. When CC:Tweaked ships breaking changes that require a newer CraftOS-PC build, we bump the minimum version in `docs/install-craftos-pc.md` and `check-craftos` keeps contributors honest. - No CI integration yet. Running CraftOS-PC headless in GitHub Actions is feasible (the AppImage works on Ubuntu runners) but is out of scope here; the contract is local-only for now. ## Future Work -- **Headless smoke test.** A `tests/smoke.lua` that boots an emulated computer, `require`s `/apis/eventloop`, `/apis/net`, and the router, and asserts the wiring loads without errors. Hooked into `just test`, then into `just ci` when it is ready to run on every commit. -- **CI.** Run the smoke test on push using the Linux AppImage. -- **Pinned ROM.** CraftOS-PC ships its own copy of the CC:Tweaked ROM per release. If we ever need to test against a specific in-game version, point CraftOS-PC at a vendored ROM via `--rom`. +- **API-loading smoke test.** Extend the `tests/` set with a script that mounts the repo into the VM (`--mount-ro /cc-libs=.`) and `require`s `/apis/eventloop`, `/apis/net`, and the router, asserting the wiring loads without errors. Today's smokes only prove CraftOS-PC itself works, not that our code loads inside it. +- **CI.** Run `just test` on push using the Linux AppImage. +- **Pinned ROM.** CraftOS-PC ships its own copy of the CC:Tweaked ROM per release. If we ever need to test against a specific in-game version, point CraftOS-PC at a vendored ROM via `--rom` (the same flag we already pass on macOS for a different reason). diff --git a/docs/install-craftos-pc.md b/docs/install-craftos-pc.md index 76ca6e9..f7a9936 100644 --- a/docs/install-craftos-pc.md +++ b/docs/install-craftos-pc.md @@ -64,6 +64,10 @@ craftos --version Must report `CraftOS-PC v2.8.3` or newer. Once this works, `just install` will succeed. +## Running tests + +`just test` runs the headless smoke tests in `tests/` through CraftOS-PC. On macOS the recipe passes `--rom /Applications/CraftOS-PC.app/Contents/Resources` because the `/usr/local/bin/craftos` symlink loses ROM auto-discovery; on Linux and Windows no flag is needed. `just ci` runs the same tests after `luacheck`. + ## Updating Repeat the steps above against the newer release. The bundle replacement is in-place; the user data directory is preserved. diff --git a/tests/boot.lua b/tests/boot.lua new file mode 100644 index 0000000..8de335f --- /dev/null +++ b/tests/boot.lua @@ -0,0 +1,4 @@ +-- Smoke test: prove CraftOS-PC boots and stdout flushes. +-- Invoked via `craftos --headless --script tests/boot.lua` from `just test`. +print('__READY__'); +os.shutdown(); diff --git a/tests/ready.lua b/tests/ready.lua new file mode 100644 index 0000000..b6d3eeb --- /dev/null +++ b/tests/ready.lua @@ -0,0 +1,8 @@ +-- Smoke test: prove the CC event queue round-trips a custom event. +-- Invoked via `craftos --headless --script tests/ready.lua` from `just test`. +os.queueEvent('craftos-ready'); +local ev = os.pullEventRaw(); +if ev == 'craftos-ready' then + print('__READY__'); +end +os.shutdown();