Harden item occurrence grounding
This commit is contained in:
@@ -3,14 +3,12 @@ package shared
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/identity"
|
||||
)
|
||||
|
||||
// NormalizedTokens returns identity-normalized alphanumeric tokens from a
|
||||
// D&D value.
|
||||
func NormalizedTokens(value string) []string {
|
||||
value = identity.ComparisonKey(value)
|
||||
value = ComparisonKey(value)
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,32 @@ package shared
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestComparisonKeyNormalizesDNDText(t *testing.T) {
|
||||
if TextComparisonPolicy != "dnd.text_comparison.v1" {
|
||||
t.Fatalf("TextComparisonPolicy = %q", TextComparisonPolicy)
|
||||
}
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
input string
|
||||
want string
|
||||
}{
|
||||
{name: "case", input: "Captain Vale", want: "captain vale"},
|
||||
{name: "compatibility", input: "Ally", want: "ally"},
|
||||
{name: "whitespace", input: " Mira\u2003Thorn ", want: "mira thorn"},
|
||||
{name: "apostrophes", input: "O’Rin and OʼRin", want: "o'rin and o'rin"},
|
||||
{name: "unicode composition", input: " Cafe\u0301\u2003d’Or ", want: "café d'or"},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := ComparisonKey(test.input); got != test.want {
|
||||
t.Fatalf("ComparisonKey(%q) = %q, want %q", test.input, got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
if ComparisonKey("Mira Thorn") == ComparisonKey("Mira Thorne") {
|
||||
t.Fatal("different names received the same comparison key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsTokenSequence(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
28
internal/modules/dnd/shared/text_comparison.go
Normal file
28
internal/modules/dnd/shared/text_comparison.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
// TextComparisonPolicy identifies the shared D&D text-comparison semantics.
|
||||
// A semantic change requires a new value and a review of every dependent
|
||||
// identity, mapping, normalization, and validator policy.
|
||||
const TextComparisonPolicy = "dnd.text_comparison.v1"
|
||||
|
||||
// ComparisonKey returns the D&D Unicode- and case-insensitive comparison key.
|
||||
func ComparisonKey(value string) string {
|
||||
value = norm.NFKC.String(value)
|
||||
value = strings.Map(func(r rune) rune {
|
||||
switch r {
|
||||
case '\u2018', '\u2019', '\u02bc':
|
||||
return '\''
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}, value)
|
||||
value = strings.Join(strings.Fields(value), " ")
|
||||
return cases.Fold().String(value)
|
||||
}
|
||||
Reference in New Issue
Block a user