Skip to content

Commit a8f16c7

Browse files
committed
chore: drop the screenshot harness, superseded by sim-test
docker/capture.sh substituted its own main() for src/main.cpp and drew one prefilled stack, so it exercised neither the event loop nor the keymap, and it needed its own Docker image plus the same Epsilon checkout. make sim-test covers all of that and asserts, instead of producing a picture for a human to eyeball. Removed: docker/capture.sh, docker/screenshot.sh, experimental/screenshot_main.cpp, the screenshot target, the capture/ ignore rule. Dockerfile.capture is kept and renamed Dockerfile.sim -- simtest.sh builds its image from it -- with its dependency list aligned on the CI job that is proven to work: no libsdl2-dev (Epsilon vendors SDL and links only -lX11 -lXext -ldl -lpthread), and no baked-in entrypoint since the runner comes from the mounted repo. Also: cap the simulator job at 30 min instead of 300 (measured 3.5 min cold, ~20 s warm on a 4-vCPU runner), and correct 1/(1+sqrt2) in README and CONTRIBUTING -- both still claimed sqrt2-1 where the engine prints -1 + sqrt2, the same error already fixed in the CHANGELOG.
1 parent 09ad663 commit a8f16c7

11 files changed

Lines changed: 52 additions & 188 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ jobs:
5757
# 32 KiB.
5858
simulator:
5959
runs-on: ubuntu-latest
60-
# Building Epsilon from scratch takes hours on a 4-vCPU runner; it happens
61-
# once per EPSILON_REF and is cached afterwards. The cap is a backstop.
62-
timeout-minutes: 300
60+
# Measured on a 4-vCPU runner: ~3.5 min to build Epsilon from scratch, ~20 s
61+
# once the cache is warm. The cap is a backstop against a hung build, with
62+
# room for Epsilon to grow — not a budget to fill.
63+
timeout-minutes: 30
6364
env:
6465
# Pinned on purpose: the scenarios compare screenshots pixel for pixel, so
6566
# an Epsilon font or layout change would fail them for no fault of ours.

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ tests/test_engine
55
*.nwa
66
node_modules/
77
.DS_Store
8-
capture/
98
*.dSYM/
109
__pycache__/
1110
*.pyc

CONTRIBUTING.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ src/
2525
utf8.h UTF-8 glyph counter (shared by layout + screen)
2626
eadkpp.h C++ wrapper over the External App Dev Kit
2727
main.cpp event loop + app metadata
28-
tests/ host unit tests + PNG render harnesses
29-
docker/ web simulator (run.sh) + real-font screenshot (screenshot.sh)
28+
tests/ host unit tests, PNG render harnesses, sim/ scenarios
29+
docker/ web simulator (run.sh) + simulator tests (simtest.sh)
3030
docs/ GitHub Pages: landing page, interactive key map, ROADMAP
3131
.github/ CI / Release (rc + retention prune) / Pages workflows
3232
```
@@ -39,13 +39,12 @@ device build also needs `arm-none-eabi-gcc`.
3939
```shell
4040
make # device app -> output/rpn.nwa
4141
make install # build + upload to a plugged-in calculator
42-
make test # host unit tests for the engine (no calculator needed)
43-
make PLATFORM=web # web app .nwb (needs emcc)
42+
make test # host unit tests for the engine (no calculator needed)
4443
make verify-install # perform the install-time link, no calculator needed
4544
make check-budgets # assert the RAM and 32 KiB-stack budgets
46-
make sim-test # replay tests/sim in the Epsilon simulator (Docker)
47-
make screenshot # real-font render via the Epsilon Linux simulator (Docker)
48-
docker/run.sh # run the app in the Epsilon web simulator (Docker)
45+
make sim-test # replay tests/sim in the Epsilon simulator (Docker)
46+
make PLATFORM=web # web app .nwb (needs emcc)
47+
docker/run.sh # run the app in the Epsilon web simulator (Docker)
4948
```
5049

5150
The engine and layout are pure C++ with no calculator dependency, so `make test`
@@ -69,7 +68,7 @@ The exact form is a canonical *polynomial in atoms*: `Σ coeff · Π atom^e`, wh
6968
an atom is `π`, a variable, `√(sub-expression)`, or `1/(sub-expression)`. This
7069
represents fractions, `k√m`, rational multiples of π and their
7170
sums/products/integer powers, **nested radicals** (`√(1+√2)`) and **conjugate
72-
division** (`1/(1+√2)``√2−1`). Anything outside it (transcendental functions,
71+
division** (`1/(1+√2)``-1 + √2`). Anything outside it (transcendental functions,
7372
overflow, or exceeding the arena) falls back to a double — **never a wrongly
7473
exact result**.
7574

Makefile

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# Build the NumWorks RPN external app.
22
#
33
# make device app -> output/rpn.nwa (arm-none-eabi)
4+
# make PLATFORM=simulator Epsilon simulator app -> output/simulator/rpn.nwb
45
# make PLATFORM=web web app -> output/rpn.nwb (emscripten)
56
# make install upload to a plugged-in calculator
67
# make test build & run the host engine tests
8+
# make verify-install perform the install-time link (no calculator)
9+
# make check-budgets assert the RAM and 32 KiB-stack budgets
10+
# make sim-test replay tests/sim in the Epsilon simulator (Docker)
711
# make clean
812
#
913
# Requirements: node/npx (nwlink); arm-none-eabi-gcc for device; emcc for web.
@@ -44,8 +48,7 @@ ifeq ($(PLATFORM),device)
4448
else ifeq ($(PLATFORM),simulator)
4549
# Native shared object dlopen'd by the Epsilon Linux/macOS simulator
4650
# (`epsilon.bin --nwb`). Same sources and same main() as the device app, so
47-
# the real event loop and keymap are what gets exercised — unlike the
48-
# screenshot harness, which substitutes its own main.
51+
# the real event loop and keymap are what gets exercised.
4952
#
5053
# No LTO, no --gc-sections, no -fvisibility=internal here: the simulator
5154
# resolves main and eadk_app_name through dlsym, and those flags would hide
@@ -133,11 +136,6 @@ sim-test:
133136
sim-test-update:
134137
docker/simtest.sh --update
135138

136-
# Render the app in the Epsilon Linux simulator -> capture/render.png (Docker).
137-
.PHONY: screenshot
138-
screenshot:
139-
docker/screenshot.sh
140-
141139
.PHONY: clean
142140
clean:
143141
rm -rf $(OUTPUT_DIR)

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ NumWorks feel, RPN-style.
2828
> **expression tree** kept in a canonical polynomial-in-atoms form. It keeps
2929
> exact fractions, `k√m`, rational multiples of π, their sums/products/integer
3030
> powers, **nested radicals** (`√(1+√2)`) and **conjugate division**
31-
> (`1/(1+√2)``√2−1`), and it carries symbolic variables. Transcendental
31+
> (`1/(1+√2)``-1 + √2`), and it carries symbolic variables. Transcendental
3232
> functions (`sin`, `ln`), integer overflow, or exceeding the on-device arena
3333
> fall back to a decimal — so a result is never *wrongly* exact. The engine is
3434
> STL-free with a compacting garbage collector over a fixed arena.
@@ -139,17 +139,20 @@ the web app alone with `make PLATFORM=web` (needs `emcc`).
139139

140140
> **Note.** Loading the app in the *web* simulator is not wired up yet (our side
141141
> module needs libc/soft-float symbols Epsilon's size-deduped main module does
142-
> not export). To see a real-font render, use the native capture below.
142+
> not export). For a real-font render, use `make sim-test` below.
143143
144-
### Real-font screenshot (Docker)
144+
### Automated runs in the Epsilon simulator (Docker)
145145

146146
```shell
147-
make screenshot # or: docker/screenshot.sh
147+
make sim-test # replay every scenario
148+
make sim-test-update # rewrite the reference screenshots — review them
148149
```
149150

150-
Builds the Epsilon **Linux** simulator, renders the app headless with a sample
151-
stack, and writes `capture/render.png` — the actual NumWorks font, no browser
152-
needed.
151+
Builds the Epsilon **Linux** simulator, loads the app as a real external app and
152+
replays the key sequences in `tests/sim/scenarios/` headless, comparing each
153+
320×240 frame with `tests/sim/expected/` pixel for pixel. Real NumWorks fonts, no
154+
browser. This is the only test that runs `src/main.cpp` itself, so the event loop,
155+
the keymap and the Toolbox menu are covered.
153156

154157
## Project layout
155158

@@ -167,7 +170,7 @@ src/
167170
utf8.h UTF-8 glyph counter (shared by layout + screen)
168171
eadkpp.h C++ wrapper over the External App Dev Kit
169172
main.cpp event loop + metadata
170-
tests/ host unit tests + PNG render harnesses
173+
tests/ host unit tests, PNG render harnesses, sim/ scenarios
171174
docs/ GitHub Pages landing page
172175
```
173176

docker/Dockerfile.capture

Lines changed: 0 additions & 17 deletions
This file was deleted.

docker/Dockerfile.sim

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Native (non-emscripten) environment for `make sim-test`: builds the Epsilon
2+
# Linux simulator and replays tests/sim/scenarios against the app inside it.
3+
#
4+
# Pass --platform matching your host (docker/simtest.sh does) so the host tools
5+
# Epsilon builds — notably the font rasterizer — are native; an amd64 tool under
6+
# Rosetta breaks the font step.
7+
#
8+
# Dependency list mirrors the simulator job in .github/workflows/ci.yml. Note
9+
# there is no libsdl2-dev: Epsilon vendors SDL under
10+
# shared/ion/src/simulator/external/sdl and compiles it itself, linking only
11+
# -lX11 -lXext -ldl -lpthread. freetype feeds the font rasterizer; python3-pil,
12+
# python3-lz4 and imagemagick the image pipeline.
13+
FROM ubuntu:24.04
14+
15+
RUN apt-get update && apt-get install -y --no-install-recommends \
16+
build-essential python3 python3-pil python3-lz4 imagemagick \
17+
pkg-config libfreetype-dev libx11-dev libxext-dev \
18+
libpng-dev libjpeg-dev \
19+
nodejs npm ca-certificates \
20+
&& rm -rf /var/lib/apt/lists/*
21+
22+
# The runner script comes from the mounted repo (docker/simtest.sh points
23+
# --entrypoint at /app/docker/sim.sh), so nothing is baked into the image.
24+
WORKDIR /work

docker/capture.sh

Lines changed: 0 additions & 36 deletions
This file was deleted.

docker/screenshot.sh

Lines changed: 0 additions & 38 deletions
This file was deleted.

docker/simtest.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ case "$(uname -m)" in
2727
esac
2828

2929
docker build --platform "$PLATFORM" -q -t numworks-rpn-sim-test \
30-
-f "$APP_DIR/docker/Dockerfile.capture" "$APP_DIR/docker" >/dev/null
30+
-f "$APP_DIR/docker/Dockerfile.sim" "$APP_DIR/docker" >/dev/null
3131

3232
exec docker run --rm --platform "$PLATFORM" \
3333
--entrypoint /app/docker/sim.sh \

0 commit comments

Comments
 (0)