golang.org/x/text@v0.14.0/secure/precis/profile_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package precis 6 7 import ( 8 "fmt" 9 "math/rand" 10 "testing" 11 "unicode" 12 13 "golang.org/x/text/internal/testtext" 14 "golang.org/x/text/transform" 15 ) 16 17 // copyOrbit is a Transformer for the sole purpose of testing the apply method, 18 // testing that apply will always call Span for the prefix of the input that 19 // remains identical and then call Transform for the remainder. It will produce 20 // inconsistent output for other usage patterns. 21 // Provided that copyOrbit is used this way, the first t bytes of the output 22 // will be identical to the input and the remaining output will be the result 23 // of calling caseOrbit on the remaining input bytes. 24 type copyOrbit int 25 26 func (t copyOrbit) Reset() {} 27 func (t copyOrbit) Span(src []byte, atEOF bool) (n int, err error) { 28 if int(t) == len(src) { 29 return int(t), nil 30 } 31 return int(t), transform.ErrEndOfSpan 32 } 33 34 // Transform implements transform.Transformer specifically for testing the apply method. 35 // See documentation of copyOrbit before using this method. 36 func (t copyOrbit) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 37 n := copy(dst, src) 38 for i, c := range dst[:n] { 39 dst[i] = orbitCase(c) 40 } 41 return n, n, nil 42 } 43 44 func orbitCase(c byte) byte { 45 if unicode.IsLower(rune(c)) { 46 return byte(unicode.ToUpper(rune(c))) 47 } else { 48 return byte(unicode.ToLower(rune(c))) 49 } 50 } 51 52 func TestBuffers(t *testing.T) { 53 want := "Those who cannot remember the past are condemned to compute it." 54 55 spans := rand.Perm(len(want) + 1) 56 57 // Compute the result of applying copyOrbit(span) transforms in reverse. 58 input := []byte(want) 59 for i := len(spans) - 1; i >= 0; i-- { 60 for j := spans[i]; j < len(input); j++ { 61 input[j] = orbitCase(input[j]) 62 } 63 } 64 65 // Apply the copyOrbit(span) transforms. 66 b := buffers{src: input} 67 for _, n := range spans { 68 b.apply(copyOrbit(n)) 69 if n%11 == 0 { 70 b.apply(transform.Nop) 71 } 72 } 73 if got := string(b.src); got != want { 74 t.Errorf("got %q; want %q", got, want) 75 } 76 } 77 78 type compareTestCase struct { 79 a string 80 b string 81 result bool 82 } 83 84 var compareTestCases = []struct { 85 name string 86 p *Profile 87 cases []compareTestCase 88 }{ 89 {"Nickname", Nickname, []compareTestCase{ 90 {"a", "b", false}, 91 {" Swan of Avon ", "swan of avon", true}, 92 {"Foo", "foo", true}, 93 {"foo", "foo", true}, 94 {"Foo Bar", "foo bar", true}, 95 {"foo bar", "foo bar", true}, 96 {"\u03A3", "\u03C3", true}, 97 {"\u03A3", "\u03C2", false}, 98 {"\u03C3", "\u03C2", false}, 99 {"Richard \u2163", "richard iv", true}, 100 {"Å", "å", true}, 101 {"ff", "ff", true}, // because of NFKC 102 {"ß", "sS", false}, 103 104 // After applying the Nickname profile, \u00a8 becomes \u0020\u0308, 105 // however because the nickname profile is not idempotent, applying it again 106 // to \u0020\u0308 results in \u0308. 107 {"\u00a8", "\u0020\u0308", true}, 108 {"\u00a8", "\u0308", true}, 109 {"\u0020\u0308", "\u0308", true}, 110 }}, 111 } 112 113 func doCompareTests(t *testing.T, fn func(t *testing.T, p *Profile, tc compareTestCase)) { 114 for _, g := range compareTestCases { 115 for i, tc := range g.cases { 116 name := fmt.Sprintf("%s:%d:%+q", g.name, i, tc.a) 117 testtext.Run(t, name, func(t *testing.T) { 118 fn(t, g.p, tc) 119 }) 120 } 121 } 122 } 123 124 func TestCompare(t *testing.T) { 125 doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) { 126 if result := p.Compare(tc.a, tc.b); result != tc.result { 127 t.Errorf("got %v; want %v", result, tc.result) 128 } 129 }) 130 } 131 132 func TestCompareString(t *testing.T) { 133 doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) { 134 a, err := p.CompareKey(tc.a) 135 if err != nil { 136 t.Errorf("Unexpected error when creating key: %v", err) 137 return 138 } 139 b, err := p.CompareKey(tc.b) 140 if err != nil { 141 t.Errorf("Unexpected error when creating key: %v", err) 142 return 143 } 144 145 if result := (a == b); result != tc.result { 146 t.Errorf("got %v; want %v", result, tc.result) 147 } 148 }) 149 }