test(bundler): lock down deterministic output across builds

The review flagged map-iteration nondeterminism as a possible cause of
unstable bundle SHAs. Empirically esbuild's Define handling is order-
independent (parallel substitution rules), so output is already stable.
Add a regression test that builds 10x with multiple Defines and asserts
SHA equality so any future change that introduces ordering surfaces.
This commit is contained in:
pj committed 2026-05-03 11:10:54 +07:00
1 parent f853af4fac
commit 8b09ab3afc
1 file changed
+39
+39
View File
@@ -83,6 +83,45 @@ func TestBundleWeb_RejectsMissingEntry(t *testing.T) {
}
}
// TestBundleWeb_IsDeterministic builds the same source repeatedly with multiple
// Defines entries and asserts the SHA matches. This guards against any future
// change that introduces map-iteration ordering into the bundle output.
func TestBundleWeb_IsDeterministic(t *testing.T) {
directory := t.TempDir()
runtimePath := filepath.Join(directory, "web-runtime.ts")
specPath := filepath.Join(directory, "spec.ts")
if err := os.WriteFile(runtimePath, []byte(fakeRuntime), 0o644); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(specPath, []byte(fakeSpec), 0o644); err != nil {
t.Fatal(err)
}
options := WebOptions{
EntryFile: specPath,
WebRuntimeFile: runtimePath,
Defines: map[string]string{
"API_BASE": "https://example.com",
"FEATURE": "true",
"VERSION": "1.2.3",
"TENANT": "alpha",
},
}
first, err := BundleWeb(options)
if err != nil {
t.Fatalf("first build: %v", err)
}
for attempt := range 10 {
repeat, err := BundleWeb(options)
if err != nil {
t.Fatalf("attempt %d: %v", attempt, err)
}
if repeat.SHA256 != first.SHA256 {
t.Fatalf("attempt %d: SHA changed (%s vs %s)", attempt, repeat.SHA256, first.SHA256)
}
}
}
func head(text string, max int) string {
if len(text) <= max {
return text