github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/runes/cond_test.go (about) 1 // Copyright 2015 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 runes 6 7 import ( 8 "strings" 9 "testing" 10 "unicode" 11 12 "golang.org/x/text/cases" 13 "golang.org/x/text/language" 14 "golang.org/x/text/transform" 15 ) 16 17 var ( 18 toUpper = cases.Upper(language.Und) 19 toLower = cases.Lower(language.Und) 20 ) 21 22 func TestPredicate(t *testing.T) { 23 testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer { 24 return If(Predicate(func(r rune) bool { 25 return unicode.Is(rt, r) 26 }), t, f) 27 }) 28 } 29 30 func TestIn(t *testing.T) { 31 testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer { 32 return If(In(rt), t, f) 33 }) 34 } 35 36 func TestNotIn(t *testing.T) { 37 testConditional(t, func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer { 38 return If(NotIn(rt), f, t) 39 }) 40 } 41 42 func testConditional(t *testing.T, f func(rt *unicode.RangeTable, t, f transform.Transformer) transform.Transformer) { 43 lower := f(unicode.Latin, toLower, toLower) 44 45 for i, tt := range []transformTest{{ 46 desc: "empty", 47 szDst: large, 48 atEOF: true, 49 in: "", 50 out: "", 51 outFull: "", 52 t: lower, 53 }, { 54 desc: "small", 55 szDst: 1, 56 atEOF: true, 57 in: "B", 58 out: "b", 59 outFull: "b", 60 t: lower, 61 }, { 62 desc: "short dst", 63 szDst: 2, 64 atEOF: true, 65 in: "AAA", 66 out: "aa", 67 outFull: "aaa", 68 err: transform.ErrShortDst, 69 t: lower, 70 }, { 71 desc: "short dst writing error", 72 szDst: 1, 73 atEOF: false, 74 in: "A\x80", 75 out: "a", 76 outFull: "a\x80", 77 err: transform.ErrShortDst, 78 t: lower, 79 }, { 80 desc: "short dst writing incomplete rune", 81 szDst: 2, 82 atEOF: true, 83 in: "Σ\xc2", 84 out: "Σ", 85 outFull: "Σ\xc2", 86 err: transform.ErrShortDst, 87 t: f(unicode.Latin, toLower, nil), 88 }, { 89 desc: "short dst, longer", 90 szDst: 5, 91 atEOF: true, 92 in: "Hellø", 93 out: "Hell", 94 outFull: "Hellø", 95 err: transform.ErrShortDst, 96 // idem is used to test short buffers by forcing processing of full-rune increments. 97 t: f(unicode.Latin, Map(idem), nil), 98 }, { 99 desc: "short dst, longer, writing error", 100 szDst: 6, 101 atEOF: false, 102 in: "\x80Hello\x80", 103 out: "\x80Hello", 104 outFull: "\x80Hello\x80", 105 err: transform.ErrShortDst, 106 t: f(unicode.Latin, Map(idem), nil), 107 }, { 108 desc: "short src", 109 szDst: 2, 110 atEOF: false, 111 in: "A\xc2", 112 out: "a", 113 outFull: "a\xc2", 114 err: transform.ErrShortSrc, 115 t: lower, 116 }, { 117 desc: "invalid input, atEOF", 118 szDst: large, 119 atEOF: true, 120 in: "\x80", 121 out: "\x80", 122 outFull: "\x80", 123 t: lower, 124 }, { 125 desc: "invalid input, !atEOF", 126 szDst: large, 127 atEOF: false, 128 in: "\x80", 129 out: "\x80", 130 outFull: "\x80", 131 t: lower, 132 }, { 133 desc: "invalid input, incomplete rune atEOF", 134 szDst: large, 135 atEOF: true, 136 in: "\xc2", 137 out: "\xc2", 138 outFull: "\xc2", 139 t: lower, 140 }, { 141 desc: "nop", 142 szDst: large, 143 atEOF: true, 144 in: "Hello World!", 145 out: "Hello World!", 146 outFull: "Hello World!", 147 t: f(unicode.Latin, nil, nil), 148 }, { 149 desc: "nop in", 150 szDst: large, 151 atEOF: true, 152 in: "THIS IS α ΤΕΣΤ", 153 out: "this is α ΤΕΣΤ", 154 outFull: "this is α ΤΕΣΤ", 155 t: f(unicode.Greek, nil, toLower), 156 }, { 157 desc: "nop not in", 158 szDst: large, 159 atEOF: true, 160 in: "THIS IS α ΤΕΣΤ", 161 out: "this is α ΤΕΣΤ", 162 outFull: "this is α ΤΕΣΤ", 163 t: f(unicode.Latin, toLower, nil), 164 }, { 165 desc: "pass atEOF is true when at end", 166 szDst: large, 167 atEOF: true, 168 in: "hello", 169 out: "HELLO", 170 outFull: "HELLO", 171 t: f(unicode.Latin, upperAtEOF{}, nil), 172 }, { 173 desc: "pass atEOF is true when at end of segment", 174 szDst: large, 175 atEOF: true, 176 in: "hello ", 177 out: "HELLO ", 178 outFull: "HELLO ", 179 t: f(unicode.Latin, upperAtEOF{}, nil), 180 }, { 181 desc: "don't pass atEOF is true when atEOF is false", 182 szDst: large, 183 atEOF: false, 184 in: "hello", 185 out: "", 186 outFull: "HELLO", 187 t: f(unicode.Latin, upperAtEOF{}, nil), 188 err: transform.ErrShortSrc, 189 }, { 190 desc: "large input ASCII", 191 szDst: 12000, 192 atEOF: false, 193 in: strings.Repeat("HELLO", 2000), 194 out: strings.Repeat("hello", 2000), 195 outFull: strings.Repeat("hello", 2000), 196 t: lower, 197 err: nil, 198 }, { 199 desc: "large input non-ASCII", 200 szDst: 12000, 201 atEOF: false, 202 in: strings.Repeat("\u3333", 2000), 203 out: strings.Repeat("\u3333", 2000), 204 outFull: strings.Repeat("\u3333", 2000), 205 t: lower, 206 err: nil, 207 }} { 208 tt.check(t, i) 209 } 210 } 211 212 // upperAtEOF is a strange Transformer that converts text to uppercase, but only 213 // if atEOF is true. 214 type upperAtEOF struct{ transform.NopResetter } 215 216 func (upperAtEOF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 217 if !atEOF { 218 return 0, 0, transform.ErrShortSrc 219 } 220 return toUpper.Transform(dst, src, atEOF) 221 } 222 223 func BenchmarkConditional(b *testing.B) { 224 dst := make([]byte, len(input)) 225 src := []byte(input) 226 227 r := If(In(unicode.Hangul), transform.Nop, transform.Nop) 228 b.ResetTimer() 229 230 for i := 0; i < b.N; i++ { 231 r.Transform(dst, src, true) 232 } 233 }