test(routing): pin tool-schema parity with supervisor
Captures the four routed skills' (review, debug, retrospective, trainer) tool definitions as a JSON snapshot and asserts the routing pod's registry advertises byte-equal schemas. A deliberate schema change fails this test, requiring an intentional snapshot update in lockstep with consumers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
80
internal/routing/snapshot_test.go
Normal file
80
internal/routing/snapshot_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package routing_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/mathiasbq/supervisor/internal/registry"
|
||||
"github.com/mathiasbq/supervisor/internal/skills/debug"
|
||||
"github.com/mathiasbq/supervisor/internal/skills/retrospective"
|
||||
"github.com/mathiasbq/supervisor/internal/skills/review"
|
||||
"github.com/mathiasbq/supervisor/internal/skills/trainer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestToolsListMatchesSupervisorSnapshot pins the four routed skills' tool
|
||||
// definitions to the supervisor's current advertisement. A deliberate schema
|
||||
// change must be reflected here by updating testdata/tools_list.snapshot.json.
|
||||
func TestToolsListMatchesSupervisorSnapshot(t *testing.T) {
|
||||
complete := func(_ context.Context, _, _, _ string) (string, int64, error) {
|
||||
return "", 0, nil
|
||||
}
|
||||
|
||||
reg := registry.New()
|
||||
reg.Register(review.New(review.Config{
|
||||
SkillPrompt: "stub",
|
||||
DefaultModel: "stub",
|
||||
CompleteFunc: complete,
|
||||
}))
|
||||
reg.Register(debug.New(debug.Config{
|
||||
SkillPrompt: "stub",
|
||||
DefaultModel: "stub",
|
||||
CompleteFunc: complete,
|
||||
}))
|
||||
reg.Register(retrospective.New(retrospective.Config{
|
||||
SkillPrompt: "stub",
|
||||
DefaultModel: "stub",
|
||||
CompleteFunc: complete,
|
||||
}))
|
||||
reg.Register(trainer.New(trainer.Config{
|
||||
ReaderPrompt: "stub",
|
||||
WriterPrompt: "stub",
|
||||
DefaultModel: "stub",
|
||||
CompleteFunc: complete,
|
||||
}))
|
||||
|
||||
wanted := map[string]bool{
|
||||
"review": true,
|
||||
"debug": true,
|
||||
"retrospective": true,
|
||||
"trainer": true,
|
||||
}
|
||||
var routed []registry.ToolDef
|
||||
for _, td := range reg.Tools() {
|
||||
if wanted[td.Name] {
|
||||
routed = append(routed, td)
|
||||
}
|
||||
}
|
||||
sort.Slice(routed, func(i, j int) bool { return routed[i].Name < routed[j].Name })
|
||||
|
||||
got, err := json.MarshalIndent(routed, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
want, err := os.ReadFile("testdata/tools_list.snapshot.json")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Normalize both via re-encode so whitespace differences don't dominate.
|
||||
var gotV, wantV any
|
||||
require.NoError(t, json.Unmarshal(got, &gotV))
|
||||
require.NoError(t, json.Unmarshal(want, &wantV))
|
||||
|
||||
gotN, _ := json.MarshalIndent(gotV, "", " ")
|
||||
wantN, _ := json.MarshalIndent(wantV, "", " ")
|
||||
|
||||
assert.Equal(t, string(wantN), string(gotN),
|
||||
"tool advertisement drifted from supervisor snapshot — update testdata/tools_list.snapshot.json deliberately if the schema change is intentional")
|
||||
}
|
||||
Reference in New Issue
Block a user