OSDN Git Service

libgo: Update to weekly.2011-11-01.
[pf3gnuchains/gcc-fork.git] / libgo / go / strings / replace_test.go
1 // Copyright 2009 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 strings_test
6
7 import (
8         "bytes"
9         "fmt"
10         "log"
11         . "strings"
12         "testing"
13 )
14
15 var _ = log.Printf
16
17 type ReplacerTest struct {
18         r   *Replacer
19         in  string
20         out string
21 }
22
23 var htmlEscaper = NewReplacer("&", "&amp;", "<", "&lt;", ">", "&gt;", "\"", "&quot;")
24
25 // The http package's old HTML escaping function.
26 func oldhtmlEscape(s string) string {
27         s = Replace(s, "&", "&amp;", -1)
28         s = Replace(s, "<", "&lt;", -1)
29         s = Replace(s, ">", "&gt;", -1)
30         s = Replace(s, "\"", "&quot;", -1)
31         s = Replace(s, "'", "&apos;", -1)
32         return s
33 }
34
35 var replacer = NewReplacer("aaa", "3[aaa]", "aa", "2[aa]", "a", "1[a]", "i", "i",
36         "longerst", "most long", "longer", "medium", "long", "short",
37         "X", "Y", "Y", "Z")
38
39 var capitalLetters = NewReplacer("a", "A", "b", "B")
40
41 var blankToXReplacer = NewReplacer("", "X", "o", "O")
42
43 var ReplacerTests = []ReplacerTest{
44         // byte->string
45         {htmlEscaper, "No changes", "No changes"},
46         {htmlEscaper, "I <3 escaping & stuff", "I &lt;3 escaping &amp; stuff"},
47         {htmlEscaper, "&&&", "&amp;&amp;&amp;"},
48
49         // generic
50         {replacer, "fooaaabar", "foo3[aaa]b1[a]r"},
51         {replacer, "long, longerst, longer", "short, most long, medium"},
52         {replacer, "XiX", "YiY"},
53
54         // byte->byte
55         {capitalLetters, "brad", "BrAd"},
56         {capitalLetters, Repeat("a", (32<<10)+123), Repeat("A", (32<<10)+123)},
57
58         // hitting "" special case
59         {blankToXReplacer, "oo", "XOXOX"},
60 }
61
62 func TestReplacer(t *testing.T) {
63         for i, tt := range ReplacerTests {
64                 if s := tt.r.Replace(tt.in); s != tt.out {
65                         t.Errorf("%d. Replace(%q) = %q, want %q", i, tt.in, s, tt.out)
66                 }
67                 var buf bytes.Buffer
68                 n, err := tt.r.WriteString(&buf, tt.in)
69                 if err != nil {
70                         t.Errorf("%d. WriteString: %v", i, err)
71                         continue
72                 }
73                 got := buf.String()
74                 if got != tt.out {
75                         t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tt.in, got, tt.out)
76                         continue
77                 }
78                 if n != len(tt.out) {
79                         t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)",
80                                 i, tt.in, n, len(tt.out), tt.out)
81                 }
82         }
83 }
84
85 // pickAlgorithmTest is a test that verifies that given input for a
86 // Replacer that we pick the correct algorithm.
87 type pickAlgorithmTest struct {
88         r    *Replacer
89         want string // name of algorithm
90 }
91
92 var pickAlgorithmTests = []pickAlgorithmTest{
93         {capitalLetters, "*strings.byteReplacer"},
94         {NewReplacer("12", "123"), "*strings.genericReplacer"},
95         {NewReplacer("1", "12"), "*strings.byteStringReplacer"},
96         {htmlEscaper, "*strings.byteStringReplacer"},
97 }
98
99 func TestPickAlgorithm(t *testing.T) {
100         for i, tt := range pickAlgorithmTests {
101                 got := fmt.Sprintf("%T", tt.r.Replacer())
102                 if got != tt.want {
103                         t.Errorf("%d. algorithm = %s, want %s", i, got, tt.want)
104                 }
105         }
106 }
107
108 func BenchmarkGenericMatch(b *testing.B) {
109         str := Repeat("A", 100) + Repeat("B", 100)
110         generic := NewReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic
111         for i := 0; i < b.N; i++ {
112                 generic.Replace(str)
113         }
114 }
115
116 func BenchmarkByteByteNoMatch(b *testing.B) {
117         str := Repeat("A", 100) + Repeat("B", 100)
118         for i := 0; i < b.N; i++ {
119                 capitalLetters.Replace(str)
120         }
121 }
122
123 func BenchmarkByteByteMatch(b *testing.B) {
124         str := Repeat("a", 100) + Repeat("b", 100)
125         for i := 0; i < b.N; i++ {
126                 capitalLetters.Replace(str)
127         }
128 }
129
130 func BenchmarkByteStringMatch(b *testing.B) {
131         str := "<" + Repeat("a", 99) + Repeat("b", 99) + ">"
132         for i := 0; i < b.N; i++ {
133                 htmlEscaper.Replace(str)
134         }
135 }
136
137 func BenchmarkHTMLEscapeNew(b *testing.B) {
138         str := "I <3 to escape HTML & other text too."
139         for i := 0; i < b.N; i++ {
140                 htmlEscaper.Replace(str)
141         }
142 }
143
144 func BenchmarkHTMLEscapeOld(b *testing.B) {
145         str := "I <3 to escape HTML & other text too."
146         for i := 0; i < b.N; i++ {
147                 oldhtmlEscape(str)
148         }
149 }
150
151 // BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces.
152 func BenchmarkByteByteReplaces(b *testing.B) {
153         str := Repeat("a", 100) + Repeat("b", 100)
154         for i := 0; i < b.N; i++ {
155                 Replace(Replace(str, "a", "A", -1), "b", "B", -1)
156         }
157 }
158
159 // BenchmarkByteByteMap compares byteByteImpl against Map.
160 func BenchmarkByteByteMap(b *testing.B) {
161         str := Repeat("a", 100) + Repeat("b", 100)
162         fn := func(r rune) rune {
163                 switch r {
164                 case 'a':
165                         return 'A'
166                 case 'b':
167                         return 'B'
168                 }
169                 return r
170         }
171         for i := 0; i < b.N; i++ {
172                 Map(fn, str)
173         }
174 }