OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / secure / precis / profile_test.go
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. This behavior is "correct", even if it
107                 // is unexpected.
108                 {"\u00a8", "\u0020\u0308", false},
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 }