diff options
Diffstat (limited to 'internal/norm/fuzz_test.go')
| -rw-r--r-- | internal/norm/fuzz_test.go | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/internal/norm/fuzz_test.go b/internal/norm/fuzz_test.go index fde62a0..27deadc 100644 --- a/internal/norm/fuzz_test.go +++ b/internal/norm/fuzz_test.go @@ -2,7 +2,11 @@ package norm -import "testing" +import ( + "strings" + "testing" + "unicode/utf8" +) // FuzzTextIdempotent: normalising text twice changes nothing more than // normalising it once, under every case and fold setting, and so for names. @@ -28,3 +32,33 @@ func FuzzTextIdempotent(f *testing.F) { } }) } + +// FuzzFoldMapped: FoldMapped's text is always Fold's, and any part of it +// leads back to original text that folds to something holding that part. +func FuzzFoldMapped(f *testing.F) { + for _, s := range []string{"Łódź-faktura.pdf", "straße", "áb", "\xff\xfeé", "́a", "Æsir"} { + f.Add(s, 0, 2) + } + f.Fuzz(func(t *testing.T, s string, a, b int) { + m := FoldMapped(s) + if m.Text != Fold(s) { + t.Fatalf("FoldMapped(%q).Text = %q, Fold = %q", s, m.Text, Fold(s)) + } + n := len(m.Text) + 1 + a, b = (a%n+n)%n, (b%n+n)%n + if a > b { + a, b = b, a + } + // A regex match starts and ends on whole characters. + for a < len(m.Text) && !utf8.RuneStart(m.Text[a]) { + a-- + } + for b < len(m.Text) && !utf8.RuneStart(m.Text[b]) { + b-- + } + src := m.Source(a, b) + if !strings.Contains(Fold(src), m.Text[a:b]) { + t.Fatalf("FoldMapped(%q).Source(%d, %d) = %q, which folds to %q, not holding %q", s, a, b, src, Fold(src), m.Text[a:b]) + } + }) +} |
