package tdd_test import ( "context" "encoding/json" "testing" iexec "github.com/mathiasbq/supervisor/internal/exec" "github.com/mathiasbq/supervisor/internal/session" "github.com/mathiasbq/supervisor/internal/skills/tdd" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestTDDSkillTools(t *testing.T) { skill := tdd.New(tdd.Config{ SystemPrompt: "supervisor rules", SkillPrompt: "tdd rules", }) tools := skill.Tools() names := make([]string, len(tools)) for i, tool := range tools { names[i] = tool.Name } assert.ElementsMatch(t, []string{"tdd_red", "tdd_green", "tdd_refactor"}, names) } func TestTDDSkillHandleUnknown(t *testing.T) { skill := tdd.New(tdd.Config{SystemPrompt: "s", SkillPrompt: "t"}) _, err := skill.Handle(context.Background(), "tdd_unknown", json.RawMessage(`{}`)) assert.ErrorContains(t, err, "unknown tool") } func TestTDDRedRequiresProjectRoot(t *testing.T) { skill := tdd.New(tdd.Config{SystemPrompt: "s", SkillPrompt: "t"}) _, err := skill.Handle(context.Background(), "tdd_red", json.RawMessage(`{"spec":"add two numbers"}`)) assert.ErrorContains(t, err, "project_root") } func TestTDDRedRequiresSpec(t *testing.T) { skill := tdd.New(tdd.Config{SystemPrompt: "s", SkillPrompt: "t"}) _, err := skill.Handle(context.Background(), "tdd_red", json.RawMessage(`{"project_root":"/tmp/proj"}`)) assert.ErrorContains(t, err, "spec") } func TestTDDGreenInjectsSessionHistory(t *testing.T) { sessDir := t.TempDir() require.NoError(t, session.Append(sessDir, "sess-1", session.Entry{ SessionID: "sess-1", Skill: "tdd", Phase: "red", FinalStatus: "pass", FilePath: "internal/foo/foo_test.go", Message: "wrote failing test for Foo", })) var capturedPrompt string fakeFn := func(_ context.Context, req iexec.Request) (iexec.Result, error) { capturedPrompt = req.TaskPrompt return iexec.Result{Status: "pass", Phase: "green", Skill: "tdd", Verified: true, ModelUsed: "self", Message: "ok"}, nil } sk := tdd.New(tdd.Config{SkillPrompt: "tdd", ExecutorFn: fakeFn, SessionsDir: sessDir}) _, err := sk.Handle(context.Background(), "tdd_green", json.RawMessage( `{"project_root":"/tmp","test_path":"internal/foo/foo_test.go","test_cmd":"go test ./...","session_id":"sess-1"}`, )) require.NoError(t, err) assert.Contains(t, capturedPrompt, "## Session history") assert.Contains(t, capturedPrompt, "wrote failing test for Foo") } func TestTDDGreenNoHistoryWhenSessionIDEmpty(t *testing.T) { var capturedPrompt string fakeFn := func(_ context.Context, req iexec.Request) (iexec.Result, error) { capturedPrompt = req.TaskPrompt return iexec.Result{Status: "pass", Phase: "green", Skill: "tdd", Verified: true, ModelUsed: "self", Message: "ok"}, nil } sk := tdd.New(tdd.Config{SkillPrompt: "tdd", ExecutorFn: fakeFn, SessionsDir: t.TempDir()}) _, err := sk.Handle(context.Background(), "tdd_green", json.RawMessage( `{"project_root":"/tmp","test_path":"internal/foo/foo_test.go"}`, )) require.NoError(t, err) assert.NotContains(t, capturedPrompt, "## Session history") } // Ensure require is used (avoids import error). var _ = require.New