mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
96 lines
2.7 KiB
Go
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)
|
|
}
|
|
}
|