Project spell aliases into extraction prompts
This commit is contained in:
@@ -79,6 +79,67 @@ func TestResolveEffectiveCatalogAddsAndAugmentsSpells(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEffectiveCatalogPromptSpellsIncludeSortedAliasesWithoutProvenance(t *testing.T) {
|
||||
overlay := testOverlayJSON(t, testOverlayCatalog(
|
||||
"campaign.example",
|
||||
testOverlaySpell("Aegis of Emberfall", "Z Emberfall", "Emberfall Aegis", "emberfall aegis"),
|
||||
testOverlaySpell("Cure Wounds", "Healing Touch"),
|
||||
))
|
||||
effective, err := ResolveEffectiveCatalog(overlayReference([]byte(overlay), "application/json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
spells := effective.PromptSpells()
|
||||
if len(spells) != len(effective.CanonicalNames()) {
|
||||
t.Fatalf("prompt spell count = %d, want %d", len(spells), len(effective.CanonicalNames()))
|
||||
}
|
||||
for index := 1; index < len(spells); index++ {
|
||||
if spells[index-1].CanonicalName > spells[index].CanonicalName {
|
||||
t.Fatalf("prompt spells are not sorted: %q before %q", spells[index-1].CanonicalName, spells[index].CanonicalName)
|
||||
}
|
||||
}
|
||||
|
||||
aliases := make(map[string][]string, len(spells))
|
||||
for _, spell := range spells {
|
||||
aliases[spell.CanonicalName] = spell.Aliases
|
||||
if !sort.StringsAreSorted(spell.Aliases) {
|
||||
t.Fatalf("aliases for %q are not sorted: %#v", spell.CanonicalName, spell.Aliases)
|
||||
}
|
||||
}
|
||||
if got := aliases["Aegis of Emberfall"]; !reflect.DeepEqual(got, []string{"Emberfall Aegis", "Z Emberfall"}) {
|
||||
t.Fatalf("Aegis aliases = %#v, want normalized aliases once", got)
|
||||
}
|
||||
if got := aliases["Cure Wounds"]; !reflect.DeepEqual(got, []string{"Healing Touch"}) {
|
||||
t.Fatalf("Cure Wounds aliases = %#v", got)
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(spells)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(string(encoded), `"aliases":null`) {
|
||||
t.Fatalf("prompt projection encoded missing aliases as null: %s", encoded)
|
||||
}
|
||||
for _, forbidden := range []string{"campaign.example", "spells", "source", "license", "ruleset", "provenance"} {
|
||||
if strings.Contains(string(encoded), forbidden) {
|
||||
t.Fatalf("prompt projection leaked %q: %s", forbidden, encoded)
|
||||
}
|
||||
}
|
||||
|
||||
for index := range spells {
|
||||
if spells[index].CanonicalName == "Aegis of Emberfall" {
|
||||
spells[index].Aliases[0] = "changed"
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, spell := range effective.PromptSpells() {
|
||||
if spell.CanonicalName == "Aegis of Emberfall" && spell.Aliases[0] == "changed" {
|
||||
t.Fatal("effective catalog exposed mutable prompt projection storage")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveEffectiveCatalogTreatsRepeatedAliasesAsIdempotent(t *testing.T) {
|
||||
single := testOverlayJSON(t, testOverlayCatalog(
|
||||
"campaign.example",
|
||||
|
||||
Reference in New Issue
Block a user