From aae5d21ad4421847d858a8a55ab938f474fab299 Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 20 Feb 2026 08:42:58 +0000 Subject: [PATCH] test(wasm): add binary size gate test TestWASMBinarySize builds WASM with -ldflags="-s -w", gzips the binary, and asserts < 1MB gzip (842KB actual) and < 3MB raw (2.90MB actual). Skipped in -short mode. Matches Makefile WASM_GZ_LIMIT. Co-Authored-By: Virgil --- TODO.md | 2 +- cmd/wasm/size_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 cmd/wasm/size_test.go diff --git a/TODO.md b/TODO.md index 0c4b24d..32c4297 100644 --- a/TODO.md +++ b/TODO.md @@ -28,7 +28,7 @@ Root cause: `registerComponents()` pulled in `encoding/json` (~200KB gz), `text/ ### Step 5: Tests -- [ ] **WASM build gate test** — `TestWASMBinarySize` in `cmd/wasm/main_test.go`: build WASM, gzip, assert < 1MB +- [x] **WASM build gate test** — `TestWASMBinarySize` in `cmd/wasm/size_test.go`: builds WASM, gzips, asserts < 1MB gzip and < 3MB raw. Result: 2.90MB raw, 842KB gzip. `//go:build !js` guarded. - [x] **Codegen CLI test** — `cmd/codegen/main_test.go`: pipe JSON stdin, verify JS output matches `GenerateBundle()` - [x] **renderToString still works** — Existing WASM tests for `renderToString` pass (build-tag guarded) - [x] **Existing tests still pass** — `go test ./...` (non-WASM) all 70+ tests pass, pipeline/codegen tests unaffected diff --git a/cmd/wasm/size_test.go b/cmd/wasm/size_test.go new file mode 100644 index 0000000..73b07ba --- /dev/null +++ b/cmd/wasm/size_test.go @@ -0,0 +1,52 @@ +// SPDX-Licence-Identifier: EUPL-1.2 +//go:build !js + +package main + +import ( + "bytes" + "compress/gzip" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + wasmGzLimit = 1_048_576 // 1 MB gzip transfer size limit + wasmRawLimit = 3_145_728 // 3 MB raw size limit +) + +func TestWASMBinarySize_Good(t *testing.T) { + if testing.Short() { + t.Skip("skipping WASM build test in short mode") + } + + dir := t.TempDir() + out := filepath.Join(dir, "gohtml.wasm") + + cmd := exec.Command("go", "build", "-ldflags=-s -w", "-o", out, ".") + cmd.Env = append(os.Environ(), "GOOS=js", "GOARCH=wasm") + output, err := cmd.CombinedOutput() + require.NoError(t, err, "WASM build failed: %s", output) + + raw, err := os.ReadFile(out) + require.NoError(t, err) + + var buf bytes.Buffer + gz, err := gzip.NewWriterLevel(&buf, gzip.BestCompression) + require.NoError(t, err) + _, err = gz.Write(raw) + require.NoError(t, err) + require.NoError(t, gz.Close()) + + t.Logf("WASM size: %d bytes raw, %d bytes gzip", len(raw), buf.Len()) + + assert.Less(t, buf.Len(), wasmGzLimit, + "WASM gzip size %d exceeds 1MB limit", buf.Len()) + assert.Less(t, len(raw), wasmRawLimit, + "WASM raw size %d exceeds 3MB limit", len(raw)) +}