fix(testrun): alias the installed spec package so one module graph loads

This commit is contained in:
pj committed 2026-08-15 13:30:21 +05:30
1 parent b3d4c5c213
commit fb57ab2f56
2 files changed
+62 -8

No files matched your search

+12 -8
View File
@@ -350,16 +350,20 @@ func resolveRuntimeSibling(specAPIPath, userSpecPath, filename string) string {
return "" return ""
} }
// resolveSpecAPIPath returns the path to pkg/spec/src/index.ts inside // resolveSpecAPIPath returns the path to the spec API's index.ts: a sanderling
// a sanderling source checkout, searched upward from the spec file and the cwd. // source checkout first, searched upward from the spec file and the cwd, then
// Returns "" when not found, in which case esbuild resolves @sanderling/spec via // an installed node_modules/@sanderling/spec. Aliasing the installed copy is
// node_modules the way a downstream user's project would. // what keeps the spec and the runtime entry on one module graph; resolving the
// bare specifier through package.json "exports" would load dist/ alongside the
// runtime's src/ and give sampler-rng.ts two instances.
func resolveSpecAPIPath(specPath string) string { func resolveSpecAPIPath(specPath string) string {
var candidates []string var checkout, installed []string
if absoluteSpec, err := filepath.Abs(specPath); err == nil { if absoluteSpec, err := filepath.Abs(specPath); err == nil {
directory := filepath.Dir(absoluteSpec) directory := filepath.Dir(absoluteSpec)
for { for {
candidates = append(candidates, filepath.Join(directory, "pkg/spec/src/index.ts")) checkout = append(checkout, filepath.Join(directory, "pkg/spec/src/index.ts"))
installed = append(installed,
filepath.Join(directory, "node_modules/@sanderling/spec/src/index.ts"))
parent := filepath.Dir(directory) parent := filepath.Dir(directory)
if parent == directory { if parent == directory {
break break
@@ -368,9 +372,9 @@ func resolveSpecAPIPath(specPath string) string {
} }
} }
if cwd, err := os.Getwd(); err == nil { if cwd, err := os.Getwd(); err == nil {
candidates = append(candidates, filepath.Join(cwd, "pkg/spec/src/index.ts")) checkout = append(checkout, filepath.Join(cwd, "pkg/spec/src/index.ts"))
} }
for _, candidate := range candidates { for _, candidate := range append(checkout, installed...) {
if _, err := os.Stat(candidate); err == nil { if _, err := os.Stat(candidate); err == nil {
return candidate return candidate
} }
+50
View File
@@ -406,3 +406,53 @@ func TestResolveRuntimeSibling_PublishedPackageShipsTheRuntimes(t *testing.T) {
} }
} }
} }
// TestPrepareBundleInputs_InstalledPackageSharesOneModuleGraph pins the
// downstream case: with no sanderling checkout above the spec, the aliases and
// the runtime entry must name the SAME installed copy. An unset alias let
// esbuild resolve @sanderling/spec to dist/ while the runtime came from src/,
// which loads sampler-rng.ts twice; from(), strings(), integers() and emails()
// then read an rng the picker never set and collapse to a fixed default.
func TestPrepareBundleInputs_InstalledPackageSharesOneModuleGraph(t *testing.T) {
root := t.TempDir()
installed := filepath.Join(root, "node_modules", "@sanderling", "spec")
installPublishedPackage(t, installed)
specPath := filepath.Join(root, "sanderling", "spec.ts")
if err := os.MkdirAll(filepath.Dir(specPath), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(specPath, []byte(""), 0o644); err != nil {
t.Fatal(err)
}
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = os.Chdir(cwd) })
if err := os.Chdir(root); err != nil {
t.Fatal(err)
}
prep, err := prepareBundleInputs(Options{Spec: specPath})
if err != nil {
t.Fatal(err)
}
source := filepath.Join(installed, "src")
want := map[string]string{
"@sanderling/spec": filepath.Join(source, "index.ts"),
"@sanderling/spec/defaults": filepath.Join(source, "defaults/index.ts"),
"@sanderling/spec/defaults/properties": filepath.Join(source, "defaults/properties.ts"),
}
for key, wantValue := range want {
if prep.aliases[key] != wantValue {
t.Errorf("alias %q = %q, want %q", key, prep.aliases[key], wantValue)
}
}
if got := prep.gojaRuntimePath; got != filepath.Join(source, "goja-runtime.ts") {
t.Errorf("gojaRuntimePath = %q, want it beside the aliased index.ts", got)
}
if got := resolveWebRuntimePath(prep.specAPIPath, specPath); got != filepath.Join(source, "web-runtime.ts") {
t.Errorf("webRuntimePath = %q, want it beside the aliased index.ts", got)
}
}