91 lines
2.6 KiB
Go
91 lines
2.6 KiB
Go
|
|
package classify
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"maisym.com/hsa/internal/config"
|
||
|
|
)
|
||
|
|
|
||
|
|
func contains(list []string, want string) bool {
|
||
|
|
for _, s := range list {
|
||
|
|
if s == want {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
// The Tremblay family: Jean-Michel and Jude share the initial "J", so neither may
|
||
|
|
// get a bare "J. Tremblay" variant; Alex ("A") and Evan ("E") are unique and may.
|
||
|
|
func TestNameVariantsAmbiguousInitial(t *testing.T) {
|
||
|
|
all := []config.Person{
|
||
|
|
{First: "Jean-Michel", Last: "Tremblay"},
|
||
|
|
{First: "Jude", Last: "Tremblay"},
|
||
|
|
{First: "Alex", Last: "Tremblay"},
|
||
|
|
{First: "Evan", Last: "Tremblay"},
|
||
|
|
{First: "Lynna", Last: "Nguyen"},
|
||
|
|
}
|
||
|
|
|
||
|
|
jm := NameVariants(all[0], all)
|
||
|
|
if contains(jm, "J. Tremblay") || contains(jm, "Tremblay, J.") {
|
||
|
|
t.Errorf("Jean-Michel must not get an ambiguous single-initial variant: %v", jm)
|
||
|
|
}
|
||
|
|
// Compound initials are unique to Jean-Michel and should appear.
|
||
|
|
if !contains(jm, "J-M Tremblay") {
|
||
|
|
t.Errorf("Jean-Michel should get compound initial variant J-M Tremblay: %v", jm)
|
||
|
|
}
|
||
|
|
|
||
|
|
jude := NameVariants(all[1], all)
|
||
|
|
if contains(jude, "J. Tremblay") {
|
||
|
|
t.Errorf("Jude must not get an ambiguous single-initial variant: %v", jude)
|
||
|
|
}
|
||
|
|
|
||
|
|
alex := NameVariants(all[2], all)
|
||
|
|
if !contains(alex, "A. Tremblay") {
|
||
|
|
t.Errorf("Alex (unique initial) should get A. Tremblay: %v", alex)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Lynna's surname is unique, so a single initial is fine.
|
||
|
|
lynna := NameVariants(all[4], all)
|
||
|
|
if !contains(lynna, "L. Nguyen") {
|
||
|
|
t.Errorf("Lynna (unique surname) should get L. Nguyen: %v", lynna)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Order/comma variants are always present and unambiguous.
|
||
|
|
for _, want := range []string{"Jean-Michel Tremblay", "Tremblay Jean-Michel", "Tremblay, Jean-Michel"} {
|
||
|
|
if !contains(jm, want) {
|
||
|
|
t.Errorf("expected variant %q in %v", want, jm)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestBuildSystemPrompt(t *testing.T) {
|
||
|
|
persons := []config.Person{
|
||
|
|
{First: "Jean-Michel", Last: "Tremblay"},
|
||
|
|
{First: "Lynna", Last: "Nguyen"},
|
||
|
|
}
|
||
|
|
categories := []config.Category{
|
||
|
|
{Name: "Pharmacy", Examples: []string{"CVS", "Rx"}},
|
||
|
|
{Name: "Other"},
|
||
|
|
}
|
||
|
|
p := BuildSystemPrompt(persons, categories, "2026-06-17")
|
||
|
|
|
||
|
|
for _, want := range []string{
|
||
|
|
"Jean-Michel Tremblay", // canonical label
|
||
|
|
"Lynna Nguyen",
|
||
|
|
"Pharmacy",
|
||
|
|
"CVS", // example injected
|
||
|
|
"2026-06-17", // today
|
||
|
|
"AMBIGUOUS", // the ambiguity rule
|
||
|
|
"IGNORE everyone", // ignore-other-people rule
|
||
|
|
"null", // unknown handling
|
||
|
|
"raw_name", // raw echo
|
||
|
|
"CLOSEST to today", // date tie-breaker
|
||
|
|
} {
|
||
|
|
if !strings.Contains(p, want) {
|
||
|
|
t.Errorf("system prompt missing %q", want)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|