Files
sanderling/internal/verifier/setup_action_test.go
T

96 lines
2.7 KiB
Go

package verifier
import (
"errors"
"os"
"path/filepath"
"testing"
"github.com/priyanshujain/sanderling/internal/bundler"
"github.com/priyanshujain/sanderling/internal/hierarchy"
)
// bundleInlineSpec bundles an inline spec through the real @sanderling/spec API
// and goja runtime entry, so the bundle installs __sanderlingSetupAction__ the
// way the CLI does.
func bundleInlineSpec(t *testing.T, source string) string {
t.Helper()
dir := t.TempDir()
specPath := filepath.Join(dir, "spec.ts")
if err := os.WriteFile(specPath, []byte(source), 0o600); err != nil {
t.Fatal(err)
}
abs := func(rel string) string {
path, err := filepath.Abs(rel)
if err != nil {
t.Fatal(err)
}
return path
}
bundle, err := bundler.Bundle(bundler.Options{
EntryFile: specPath,
RuntimeFile: abs("../../pkg/spec/src/goja-runtime.ts"),
Aliases: map[string]string{
"@sanderling/spec": abs("../../pkg/spec/src/index.ts"),
"@sanderling/spec/defaults": abs("../../pkg/spec/src/defaults/index.ts"),
"@sanderling/spec/defaults/properties": abs("../../pkg/spec/src/defaults/properties.ts"),
},
})
if err != nil {
t.Fatalf("bundle: %v", err)
}
return string(bundle.JavaScript)
}
func loadBundled(t *testing.T, source, treeJSON string) *Verifier {
t.Helper()
v, err := New()
if err != nil {
t.Fatal(err)
}
if err := v.Load(bundleInlineSpec(t, source)); err != nil {
t.Fatalf("load: %v", err)
}
tree, err := hierarchy.Parse(treeJSON)
if err != nil {
t.Fatal(err)
}
if err := v.PushSnapshot(SnapshotInput{Tree: tree}); err != nil {
t.Fatalf("push snapshot: %v", err)
}
return v
}
func TestSetupActionWalksSetupOnly(t *testing.T) {
spec := `
import { Tap, actions, taps } from "@sanderling/spec";
export const setup = actions(() => [Tap({ on: "id:SignIn" })]);
export const actionsRoot = taps;
`
v := loadBundled(t, spec, enumTreeJSON)
action, err := v.SetupAction()
if err != nil {
t.Fatalf("SetupAction: %v", err)
}
if action.Kind != ActionKindTap || action.On != "id:SignIn" {
t.Errorf("SetupAction = %+v, want Tap on id:SignIn from setup", action)
}
}
func TestSetupActionIgnoresActionsRoot(t *testing.T) {
// No setup, but a live actionsRoot that NextAction would happily draw from.
spec := `
import { taps } from "@sanderling/spec";
export const actionsRoot = taps;
`
v := loadBundled(t, spec, enumTreeJSON)
if _, err := v.SetupAction(); !errors.Is(err, ErrNoAction) {
t.Fatalf("SetupAction err = %v, want ErrNoAction when no setup is declared", err)
}
// Sanity: the seeded root would have produced an action, proving SetupAction
// deliberately skips it.
if _, err := v.NextAction(); err != nil {
t.Fatalf("NextAction should draw from actionsRoot: %v", err)
}
}