Files
AetherForge/server/internal/ai/personas_test.go

100 lines
3.2 KiB
Go

package ai
import (
"strings"
"testing"
)
func TestPersonaSystemPromptNonEmptyDistinct(t *testing.T) {
modes := []string{PersonaAggressive, PersonaSilent, PersonaPassive, PersonaPersuasive, PersonaBalanced}
seen := make(map[string]string, len(modes))
for _, mode := range modes {
prompt := PersonaSystemPrompt(mode)
if strings.TrimSpace(prompt) == "" {
t.Fatalf("persona %q returned empty prompt", mode)
}
if !strings.Contains(prompt, "AetherForge fleet controller") {
t.Fatalf("persona %q missing base system prompt", mode)
}
if prev, ok := seen[prompt]; ok {
t.Fatalf("personas %q and %q produced identical prompts", prev, mode)
}
seen[prompt] = mode
}
}
func TestPersonaSystemPromptModeSpecificGuidance(t *testing.T) {
cases := []struct {
mode string
needle string
}{
{PersonaAggressive, "spread_now and discover_and_join"},
{PersonaSilent, "Never spread_now unless stuck"},
{PersonaPassive, "Default to noop"},
{PersonaPersuasive, "discover_and_join before restart_mining"},
{PersonaBalanced, "Balance spread vs mine"},
}
for _, tc := range cases {
prompt := PersonaSystemPrompt(tc.mode)
if !strings.Contains(prompt, tc.needle) {
t.Fatalf("persona %q missing %q in:\n%s", tc.mode, tc.needle, prompt)
}
}
}
func TestNormalizePersona(t *testing.T) {
if got := NormalizePersona(" AGGRESSIVE "); got != PersonaAggressive {
t.Fatalf("got %q", got)
}
if got := NormalizePersona("unknown"); got != PersonaBalanced {
t.Fatalf("unknown should map to balanced, got %q", got)
}
}
func TestPersonaSpreadTierOrderDistinct(t *testing.T) {
modes := []string{PersonaAggressive, PersonaSilent, PersonaPassive, PersonaPersuasive, PersonaBalanced}
seen := make(map[string]string, len(modes))
for _, mode := range modes {
order := PersonaSpreadTierOrder(mode)
if len(order) != len(defaultSpreadTiers) {
t.Fatalf("persona %q tier count = %d want %d", mode, len(order), len(defaultSpreadTiers))
}
key := strings.Join(order, ",")
if prev, ok := seen[key]; ok && mode != PersonaBalanced {
t.Fatalf("personas %q and %q share spread order", prev, mode)
}
seen[key] = mode
}
if PersonaSpreadTierOrder(PersonaPersuasive)[1] != "dns_txt" {
t.Fatalf("persuasive should front dns_txt, got %v", PersonaSpreadTierOrder(PersonaPersuasive))
}
if PersonaSpreadTierOrder(PersonaAggressive)[2] != "smb" {
t.Fatalf("aggressive should front smb early, got %v", PersonaSpreadTierOrder(PersonaAggressive))
}
}
func TestPersonaSpreadTemperamentShape(t *testing.T) {
temp := PersonaSpreadTemperament(PersonaSilent)
if len(temp.TierOrder) == 0 || len(temp.Reasoning) == 0 || temp.Confidence <= 0 {
t.Fatalf("invalid spread temperament: %+v", temp)
}
if !strings.Contains(temp.Reasoning[0].Fact, PersonaSilent) {
t.Fatalf("reasoning should cite persona: %+v", temp.Reasoning[0])
}
}
func TestCourtJudgeOverlayDistinct(t *testing.T) {
modes := []string{PersonaAggressive, PersonaSilent, PersonaPassive, PersonaPersuasive, PersonaBalanced}
prev := ""
for _, mode := range modes {
overlay := CourtJudgeOverlay(mode)
if strings.TrimSpace(overlay) == "" {
t.Fatalf("empty overlay for %q", mode)
}
if overlay == prev && prev != "" {
t.Fatalf("duplicate court overlay for %q", mode)
}
prev = overlay
}
}