plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


408b9c0Peter John 2026-08-10T10:25:26+05:30
test: add scripts/test-examples.sh, an end-to-end examples smoke test
Files changed (1) hide show
  1. scripts/test-examples.sh +104 -0
scripts/test-examples.sh ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Integration test: compiles and runs every examples/*.plum file through the
4
+ # REAL toolchain — the `plum` CLI binary (which resolves `import`s against
5
+ # --lib-path, unlike plum-checker/plum-wasm-codegen's unit tests, which parse
6
+ # and compile a single file directly) and, if available, an external
7
+ # `wasmtime` runtime.
8
+ #
9
+ # This exists because the unit tests alone missed a real bug: examples/basics.plum
10
+ # had an `import std/io` where libs/std/io.plum doesn't exist. The unit tests
11
+ # never noticed since they don't touch plum-core's loader/import resolution at
12
+ # all — only compiling and running through the actual CLI catches that class
13
+ # of problem.
14
+ #
15
+ # Usage: scripts/test-examples.sh
16
+ # Exit code is 0 if every example compiled (and, where checked, ran) correctly.
17
+
18
+ set -uo pipefail
19
+
20
+ cd "$(dirname "${BASH_SOURCE[0]}")/.."
21
+
22
+ WORKDIR=$(mktemp -d)
23
+ trap 'rm -rf "$WORKDIR"' EXIT
24
+
25
+ echo "Building plum-cli..."
26
+ if ! cargo build -p plum-cli --quiet 2>"$WORKDIR/build.log"; then
27
+ echo "FAIL: plum-cli failed to build" >&2
28
+ cat "$WORKDIR/build.log" >&2
29
+ exit 1
30
+ fi
31
+ PLUM_BIN="target/debug/plum"
32
+
33
+ HAVE_WASMTIME=0
34
+ if command -v wasmtime >/dev/null 2>&1; then
35
+ HAVE_WASMTIME=1
36
+ else
37
+ echo "note: wasmtime CLI not found on PATH — will compile every example but skip running them" >&2
38
+ fi
39
+
40
+ # Examples that export `main` and are expected to run without trapping. Kept
41
+ # in sync with plum-wasm-codegen/tests/examples_test.rs.
42
+ has_main() {
43
+ case "$1" in
44
+ basics|closures|match|methods) return 0 ;;
45
+ *) return 1 ;;
46
+ esac
47
+ }
48
+
49
+ # Expected `main` return value for examples whose result is asserted in
50
+ # plum-wasm-codegen/tests/examples_test.rs. Empty means "just don't trap"
51
+ # (e.g. basics.plum's main returns Unit, not a value to compare).
52
+ expected_value() {
53
+ case "$1" in
54
+ closures) echo 120 ;;
55
+ match) echo 5 ;;
56
+ methods) echo 10 ;;
57
+ *) echo "" ;;
58
+ esac
59
+ }
60
+
61
+ failed=0
62
+ passed=0
63
+
64
+ for src in examples/*.plum; do
65
+ name=$(basename "$src" .plum)
66
+ wasm="$WORKDIR/$name.wasm"
67
+
68
+ printf '%-14s compile ... ' "$name"
69
+ if ! "$PLUM_BIN" compile "$src" -o "$wasm" >"$WORKDIR/$name.compile.log" 2>&1; then
70
+ echo "FAIL"
71
+ sed 's/^/ /' "$WORKDIR/$name.compile.log"
72
+ failed=$((failed + 1))
73
+ continue
74
+ fi
75
+ echo "ok"
76
+
77
+ if [ "$HAVE_WASMTIME" -eq 1 ] && has_main "$name"; then
78
+ printf '%-14s run ... ' "$name"
79
+ if output=$(wasmtime run --invoke main "$wasm" 2>"$WORKDIR/$name.run.log"); then
80
+ expected=$(expected_value "$name")
81
+ if [ -n "$expected" ] && [ "$output" != "$expected" ]; then
82
+ echo "FAIL (expected $expected, got '$output')"
83
+ failed=$((failed + 1))
84
+ continue
85
+ fi
86
+ if [ -n "$output" ]; then
87
+ echo "ok (-> $output)"
88
+ else
89
+ echo "ok"
90
+ fi
91
+ else
92
+ echo "FAIL (trapped)"
93
+ sed 's/^/ /' "$WORKDIR/$name.run.log"
94
+ failed=$((failed + 1))
95
+ continue
96
+ fi
97
+ fi
98
+
99
+ passed=$((passed + 1))
100
+ done
101
+
102
+ echo
103
+ echo "$passed passed, $failed failed"
104
+ [ "$failed" -eq 0 ]