// internal/skills/debug/handlers_test.go package debug_test import ( "context" "encoding/json" "testing" iexec "github.com/mathiasbq/supervisor/internal/exec" "github.com/mathiasbq/supervisor/internal/skills/debug" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestDebugToolRegistered(t *testing.T) { sk := debug.New(debug.Config{SkillPrompt: "debug rules"}) names := make([]string, 0) for _, tool := range sk.Tools() { names = append(names, tool.Name) } assert.Contains(t, names, "debug") } func TestDebugRequiresProjectRoot(t *testing.T) { sk := debug.New(debug.Config{SkillPrompt: "d"}) _, err := sk.Handle(context.Background(), "debug", json.RawMessage(`{"error":"panic: nil pointer"}`)) assert.ErrorContains(t, err, "project_root") } func TestDebugRequiresError(t *testing.T) { sk := debug.New(debug.Config{SkillPrompt: "d"}) _, err := sk.Handle(context.Background(), "debug", json.RawMessage(`{"project_root":"/tmp"}`)) assert.ErrorContains(t, err, "error") } func TestDebugCallsExecutor(t *testing.T) { called := false var capturedTask string fakeFn := func(_ context.Context, req iexec.Request) (iexec.Result, error) { called = true capturedTask = req.TaskPrompt return iexec.Result{ Status: "pass", Phase: "debug", Skill: "debug", RunnerOutput: "HYPOTHESIS 1 (likelihood: high): nil map access\nVERIFY: go test ./... → expected: panic line reference", Verified: false, ModelUsed: "self", Message: "3 hypotheses for: panic nil pointer at foo.go:42", }, nil } sk := debug.New(debug.Config{SkillPrompt: "debug rules", ExecutorFn: fakeFn, SessionsDir: t.TempDir()}) out, err := sk.Handle(context.Background(), "debug", json.RawMessage( `{"project_root":"/tmp/proj","error":"panic: nil pointer dereference at foo.go:42","context":"occurs on startup"}`, )) require.NoError(t, err) assert.True(t, called) assert.Contains(t, capturedTask, "panic: nil pointer dereference") assert.Contains(t, capturedTask, "occurs on startup") var result iexec.Result require.NoError(t, json.Unmarshal(out, &result)) assert.Equal(t, "debug", result.Phase) }