Go Fan Report: charmbracelet/x/exp/golden πΉ
Daily round-robin review picked the most-recently-pushed unreviewed direct dependency: github.com/charmbracelet/x/exp/golden (umbrella repo pushed 2026-05-24). It's a tiny test helper β ~80 lines of code β but it's load-bearing for both the console rendering tests and the entire compiler-output snapshot suite, so it's worth a careful look.
Module Overview
A single-function golden-file assertion library. RequireEqual compares output against a checked-in testdata/<TestName>.golden file, prints a go-udiff unified diff on mismatch, and regenerates files when tests are invoked with -update. Control codes are escaped before comparison so ANSI sequences round-trip cleanly through golden files.
Current Usage in gh-aw
- Files: 3 (
pkg/console/golden_test.go, pkg/workflow/wasm_golden_test.go, scripts/test-wasm-golden.mjs mirrors the snapshots from JS)
- API used:
golden.RequireEqual(t, output) only β both string and []byte callers, leveraging the generic API added 2025-06-02
- Test coverage (.golden files): 29 in
pkg/console/testdata/, 4 in pkg/workflow/testdata/wasm_golden/WasmBinary/, plus TestWasmGolden_CompileFixtures fixtures
Research Findings
Recent Updates
- 2026-03-09 β bumped
aymanbagabas/go-udiff (deps only)
- 2025-09-08 β min Go version raised to 1.24
- 2025-06-02 β
feat(exp/golden): accept strings on RequireEqual β the generic RequireEqual[T []byte | string] form gh-aw now uses
- 2025-06-02 β testdata directories are no longer ignored by the package's own
.gitignore (gh-aw already commits its golden files β
)
RequireEqualEscape(tb, out, escapes bool) is marked deprecated in favor of RequireEqual β gh-aw does not use it (good)
Notable internals
- Registers a global
flag.Bool("update", ...) at package init β importing exposes -update to the whole test binary (standard idiom, no concern)
- On mismatch, prints full expected + full got + unified diff. For multi-KB compiler YAML snapshots in
TestWasmGolden_* this can flood CI logs
- Normalizes Windows
\r\n to \n only on Windows
Improvement Opportunities
π Quick Wins
- Dead
os.Stdout swap in TestGolden_TableRendering β pkg/console/golden_test.go:77-79 saves/restores os.Stdout, but RenderTable() returns a string and never touches stdout. The block has no effect today and would race if the test ever called t.Parallel(). Delete it.
- Stale example in
scratchpad/visual-regression-testing.md:137 β example shows golden.RequireEqual(t, []byte(output)); with the generic API the cast is redundant and inconsistent with the rest of the codebase. Drop the []byte().
- Add the path-safety comment to
pkg/workflow/wasm_golden_test.go β only pkg/console/golden_test.go warns that subtest names must avoid /. Same constraint applies where fixture filenames feed t.Run(...).
β¨ Feature Opportunities
- Diff-only wrapper for compiler snapshots β
RequireEqual prints the full expected + got payload on failure. For YAML compiler snapshots that's multi-KB of noise on every failed CI run. A thin local helper that uses udiff.Unified directly and skips the dumps would make logs scannable. Source is ~30 lines, easy to copy locally.
- Orphan-golden linter β when subtests are renamed/removed, stale
.golden files survive -update. A CI check (find testdata -name '*.golden' cross-referenced with go test -list) would prevent accretion.
π Best Practice Alignment
- Centralize normalization β
normalizeOutput() in pkg/workflow/wasm_golden_test.go and normalize() in scripts/test-wasm-golden.mjs are mirror images maintained by hand (heredoc tokens, container pin digests, default-model strings). One drift between them would silently mask a wasm-vs-native regression. Consider extracting a single declarative manifest of regex pairs consumed by both.
- Document
-update once, in code β currently only the Makefile and the scratchpad doc mention it. A package-level doc comment in each golden_test.go would let go doc users find it.
π§ General Improvements
- The codex
engineYAML test patches output post-compilation to strip --exclude-env CODEX_API_KEY. Adding a short comment pointing at the underlying compiler conditional would help future readers locate the source-of-truth.
Recommendations
Prioritized:
- (Quick win) Delete the no-op
os.Stdout swap and update the doc example β 2-line PR.
- (Best practice) Unify the Go and JS normalization rules into one source β prevents subtle wasm-vs-native drift.
- (Feature) Add an orphan-golden CI check β protects against testdata bloat as the suite grows.
- (Feature) Wrap
RequireEqual for compiler snapshots so failure output stays scannable.
Next Steps
- Open small PRs for the two quick wins above.
- Discuss whether the diff-only wrapper is worth the local maintenance vs. accepting verbose CI logs on rare snapshot failures.
Module summary saved to scratchpad/mods/charmbracelet-x-exp-golden.md.
References: Β§26392689464
Generated by πΉ Go Fan Β· opus47 8.4M Β· β·
Go Fan Report: charmbracelet/x/exp/golden πΉ
Daily round-robin review picked the most-recently-pushed unreviewed direct dependency:
github.com/charmbracelet/x/exp/golden(umbrella repo pushed 2026-05-24). It's a tiny test helper β ~80 lines of code β but it's load-bearing for both the console rendering tests and the entire compiler-output snapshot suite, so it's worth a careful look.Module Overview
A single-function golden-file assertion library.
RequireEqualcompares output against a checked-intestdata/<TestName>.goldenfile, prints a go-udiff unified diff on mismatch, and regenerates files when tests are invoked with-update. Control codes are escaped before comparison so ANSI sequences round-trip cleanly through golden files.Current Usage in gh-aw
pkg/console/golden_test.go,pkg/workflow/wasm_golden_test.go,scripts/test-wasm-golden.mjsmirrors the snapshots from JS)golden.RequireEqual(t, output)only β bothstringand[]bytecallers, leveraging the generic API added 2025-06-02pkg/console/testdata/, 4 inpkg/workflow/testdata/wasm_golden/WasmBinary/, plusTestWasmGolden_CompileFixturesfixturesResearch Findings
Recent Updates
aymanbagabas/go-udiff(deps only)feat(exp/golden): accept strings on RequireEqualβ the genericRequireEqual[T []byte | string]form gh-aw now uses.gitignore(gh-aw already commits its golden files β )RequireEqualEscape(tb, out, escapes bool)is marked deprecated in favor ofRequireEqualβ gh-aw does not use it (good)Notable internals
flag.Bool("update", ...)at package init β importing exposes-updateto the whole test binary (standard idiom, no concern)TestWasmGolden_*this can flood CI logs\r\nto\nonly on WindowsImprovement Opportunities
π Quick Wins
os.Stdoutswap inTestGolden_TableRenderingβpkg/console/golden_test.go:77-79saves/restoresos.Stdout, butRenderTable()returns a string and never touches stdout. The block has no effect today and would race if the test ever calledt.Parallel(). Delete it.scratchpad/visual-regression-testing.md:137β example showsgolden.RequireEqual(t, []byte(output)); with the generic API the cast is redundant and inconsistent with the rest of the codebase. Drop the[]byte().pkg/workflow/wasm_golden_test.goβ onlypkg/console/golden_test.gowarns that subtest names must avoid/. Same constraint applies where fixture filenames feedt.Run(...).β¨ Feature Opportunities
RequireEqualprints the full expected + got payload on failure. For YAML compiler snapshots that's multi-KB of noise on every failed CI run. A thin local helper that usesudiff.Unifieddirectly and skips the dumps would make logs scannable. Source is ~30 lines, easy to copy locally..goldenfiles survive-update. A CI check (find testdata -name '*.golden'cross-referenced withgo test -list) would prevent accretion.π Best Practice Alignment
normalizeOutput()inpkg/workflow/wasm_golden_test.goandnormalize()inscripts/test-wasm-golden.mjsare mirror images maintained by hand (heredoc tokens, container pin digests, default-model strings). One drift between them would silently mask a wasm-vs-native regression. Consider extracting a single declarative manifest of regex pairs consumed by both.-updateonce, in code β currently only the Makefile and the scratchpad doc mention it. A package-level doc comment in eachgolden_test.gowould letgo docusers find it.π§ General Improvements
engineYAMLtest patches output post-compilation to strip--exclude-env CODEX_API_KEY. Adding a short comment pointing at the underlying compiler conditional would help future readers locate the source-of-truth.Recommendations
Prioritized:
os.Stdoutswap and update the doc example β 2-line PR.RequireEqualfor compiler snapshots so failure output stays scannable.Next Steps
Module summary saved to
scratchpad/mods/charmbracelet-x-exp-golden.md.References: Β§26392689464