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.
13 "golang.org/x/text/internal/testtext"
14 "golang.org/x/text/transform"
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.
26 func (t copyOrbit) Reset() {}
27 func (t copyOrbit) Span(src []byte, atEOF bool) (n int, err error) {
28 if int(t) == len(src) {
31 return int(t), transform.ErrEndOfSpan
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) {
38 for i, c := range dst[:n] {
44 func orbitCase(c byte) byte {
45 if unicode.IsLower(rune(c)) {
46 return byte(unicode.ToUpper(rune(c)))
48 return byte(unicode.ToLower(rune(c)))
52 func TestBuffers(t *testing.T) {
53 want := "Those who cannot remember the past are condemned to compute it."
55 spans := rand.Perm(len(want) + 1)
57 // Compute the result of applying copyOrbit(span) transforms in reverse.
59 for i := len(spans) - 1; i >= 0; i-- {
60 for j := spans[i]; j < len(input); j++ {
61 input[j] = orbitCase(input[j])
65 // Apply the copyOrbit(span) transforms.
66 b := buffers{src: input}
67 for _, n := range spans {
70 b.apply(transform.Nop)
73 if got := string(b.src); got != want {
74 t.Errorf("got %q; want %q", got, want)
78 type compareTestCase struct {
84 var compareTestCases = []struct {
87 cases []compareTestCase
89 {"Nickname", Nickname, []compareTestCase{
91 {" Swan of Avon ", "swan of avon", 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},
101 {"ff", "ff", true}, // because of NFKC
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. This behavior is "correct", even if it
108 {"\u00a8", "\u0020\u0308", false},
109 {"\u0020\u0308", "\u0308", true},
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) {
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)
132 func TestCompareString(t *testing.T) {
133 doCompareTests(t, func(t *testing.T, p *Profile, tc compareTestCase) {
134 a, err := p.CompareKey(tc.a)
136 t.Errorf("Unexpected error when creating key: %v", err)
139 b, err := p.CompareKey(tc.b)
141 t.Errorf("Unexpected error when creating key: %v", err)
145 if result := (a == b); result != tc.result {
146 t.Errorf("got %v; want %v", result, tc.result)