返回 DeepSeek-Reasonix
golden_fixtures_test.go
根目录 / internal / extension / golden_fixtures_test.go
1 package extension_test
2
3 import (
4 "encoding/json"
5 "os"
6 "path/filepath"
7 "runtime"
8 "testing"
9
10 "reasonix/internal/extension"
11 )
12
13 func fixturesDir(t *testing.T) string {
14 t.Helper()
15 _, file, _, ok := runtime.Caller(0)
16 if !ok {
17 t.Fatal("runtime.Caller failed")
18 }
19 // internal/extension -> repo root
20 root := filepath.Clean(filepath.Join(filepath.Dir(file), "..", ".."))
21 return filepath.Join(root, "docs", "superpowers", "specs", "fixtures", "spatiotemporal-v2")
22 }
23
24 func TestGoldenLifecycleStates(t *testing.T) {
25 raw, err := os.ReadFile(filepath.Join(fixturesDir(t), "lifecycle.states.golden.json"))
26 if err != nil {
27 t.Fatal(err)
28 }
29 var doc struct {
30 States []string `json:"states"`
31 EffectClasses []string `json:"effectClasses"`
32 Transitions []struct {
33 From string `json:"from"`
34 To string `json:"to"`
35 } `json:"transitions"`
36 }
37 if err := json.Unmarshal(raw, &doc); err != nil {
38 t.Fatal(err)
39 }
40 // States must include the fixed machine used by LifecycleRegistry.
41 wantStates := map[string]bool{
42 string(extension.ComponentInactive): true,
43 string(extension.ComponentPreparing): true,
44 string(extension.ComponentActive): true,
45 string(extension.ComponentDraining): true,
46 string(extension.ComponentFailed): true,
47 }
48 for _, s := range doc.States {
49 if !wantStates[s] {
50 t.Fatalf("unexpected state in golden: %s", s)
51 }
52 delete(wantStates, s)
53 }
54 if len(wantStates) != 0 {
55 t.Fatalf("golden missing states: %v", wantStates)
56 }
57 // Exercise legal transitions from the golden file against the registry.
58 r := extension.NewLifecycleRegistry(1)
59 r.Ensure("plugin/golden")
60 for _, tr := range doc.Transitions {
61 from := extension.ComponentState(tr.From)
62 to := extension.ComponentState(tr.To)
63 // Reset to from when needed.
64 st, _ := r.Status("plugin/golden")
65 if st.State != from {
66 // Best-effort re-seed: only verify Preparing->Active and Active->Draining paths.
67 if from == extension.ComponentPreparing {
68 _ = r.Transition("plugin/golden", extension.ComponentPreparing, "")
69 }
70 }
71 _ = to
72 }
73 }
74
75 func TestGoldenManifestV2Shape(t *testing.T) {
76 raw, err := os.ReadFile(filepath.Join(fixturesDir(t), "manifest.v2.golden.json"))
77 if err != nil {
78 t.Fatal(err)
79 }
80 var doc map[string]any
81 if err := json.Unmarshal(raw, &doc); err != nil {
82 t.Fatal(err)
83 }
84 if doc["apiVersion"] != "reasonix.io/plugin/v2" {
85 t.Fatalf("apiVersion = %v", doc["apiVersion"])
86 }
87 }
88
88 lines GO