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.
12 "golang.org/x/text/cases"
13 "golang.org/x/text/language"
14 "golang.org/x/text/transform"
18 toUpper = cases.Upper(language.Und)
19 toLower = cases.Lower(language.Und)
22 type spanformer interface {
23 transform.SpanningTransformer
26 func TestPredicate(t *testing.T) {
27 testConditional(t, func(rt *unicode.RangeTable, t, f spanformer) spanformer {
28 return If(Predicate(func(r rune) bool {
29 return unicode.Is(rt, r)
34 func TestIn(t *testing.T) {
35 testConditional(t, func(rt *unicode.RangeTable, t, f spanformer) spanformer {
36 return If(In(rt), t, f)
40 func TestNotIn(t *testing.T) {
41 testConditional(t, func(rt *unicode.RangeTable, t, f spanformer) spanformer {
42 return If(NotIn(rt), f, t)
46 func testConditional(t *testing.T, f func(rt *unicode.RangeTable, t, f spanformer) spanformer) {
47 lower := f(unicode.Latin, toLower, toLower)
49 for i, tt := range []transformTest{{
64 errSpan: transform.ErrEndOfSpan,
73 err: transform.ErrShortDst,
74 errSpan: transform.ErrEndOfSpan,
77 desc: "short dst writing error",
83 err: transform.ErrShortDst,
84 errSpan: transform.ErrEndOfSpan,
87 desc: "short dst writing incomplete rune",
93 err: transform.ErrShortDst,
94 t: f(unicode.Latin, toLower, nil),
96 desc: "short dst, longer",
102 err: transform.ErrShortDst,
103 // idem is used to test short buffers by forcing processing of full-rune increments.
104 t: f(unicode.Latin, Map(idem), nil),
106 desc: "short dst, longer, writing error",
111 outFull: "\x80Hello\x80",
112 err: transform.ErrShortDst,
113 t: f(unicode.Latin, Map(idem), nil),
121 err: transform.ErrShortSrc,
122 errSpan: transform.ErrEndOfSpan,
125 desc: "short src no change",
131 err: transform.ErrShortSrc,
132 errSpan: transform.ErrShortSrc,
136 desc: "invalid input, atEOF",
144 desc: "invalid input, !atEOF",
152 desc: "invalid input, incomplete rune atEOF",
165 outFull: "Hello World!",
166 t: f(unicode.Latin, nil, nil),
171 in: "THIS IS α ΤΕΣΤ",
172 out: "this is α ΤΕΣΤ",
173 outFull: "this is α ΤΕΣΤ",
174 errSpan: transform.ErrEndOfSpan,
175 t: f(unicode.Greek, nil, toLower),
177 desc: "nop in latin",
180 in: "THIS IS α ΤΕΣΤ",
181 out: "THIS IS α τεστ",
182 outFull: "THIS IS α τεστ",
183 errSpan: transform.ErrEndOfSpan,
184 t: f(unicode.Latin, nil, toLower),
189 in: "THIS IS α ΤΕΣΤ",
190 out: "this is α ΤΕΣΤ",
191 outFull: "this is α ΤΕΣΤ",
192 errSpan: transform.ErrEndOfSpan,
193 t: f(unicode.Latin, toLower, nil),
195 desc: "pass atEOF is true when at end",
201 errSpan: transform.ErrEndOfSpan,
202 t: f(unicode.Latin, upperAtEOF{}, nil),
204 desc: "pass atEOF is true when at end of segment",
210 errSpan: transform.ErrEndOfSpan,
211 t: f(unicode.Latin, upperAtEOF{}, nil),
213 desc: "don't pass atEOF is true when atEOF is false",
219 err: transform.ErrShortSrc,
220 errSpan: transform.ErrShortSrc,
221 t: f(unicode.Latin, upperAtEOF{}, nil),
223 desc: "pass atEOF is true when at end, no change",
229 t: f(unicode.Latin, upperAtEOF{}, nil),
231 desc: "pass atEOF is true when at end of segment, no change",
237 t: f(unicode.Latin, upperAtEOF{}, nil),
239 desc: "large input ASCII",
242 in: strings.Repeat("HELLO", 2000),
243 out: strings.Repeat("hello", 2000),
244 outFull: strings.Repeat("hello", 2000),
245 errSpan: transform.ErrEndOfSpan,
249 desc: "large input non-ASCII",
252 in: strings.Repeat("\u3333", 2000),
253 out: strings.Repeat("\u3333", 2000),
254 outFull: strings.Repeat("\u3333", 2000),
262 // upperAtEOF is a strange Transformer that converts text to uppercase, but only
264 type upperAtEOF struct{ transform.NopResetter }
266 func (upperAtEOF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
268 return 0, 0, transform.ErrShortSrc
270 return toUpper.Transform(dst, src, atEOF)
273 func (upperAtEOF) Span(src []byte, atEOF bool) (n int, err error) {
275 return 0, transform.ErrShortSrc
277 return toUpper.Span(src, atEOF)
280 func BenchmarkConditional(b *testing.B) {
281 doBench(b, If(In(unicode.Hangul), transform.Nop, transform.Nop))