diff options
Diffstat (limited to 'libgo/go/strings/replace_test.go')
-rw-r--r-- | libgo/go/strings/replace_test.go | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/libgo/go/strings/replace_test.go b/libgo/go/strings/replace_test.go new file mode 100644 index 00000000000..e337856c64d --- /dev/null +++ b/libgo/go/strings/replace_test.go @@ -0,0 +1,174 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package strings_test + +import ( + "bytes" + "fmt" + "log" + . "strings" + "testing" +) + +var _ = log.Printf + +type ReplacerTest struct { + r *Replacer + in string + out string +} + +var htmlEscaper = NewReplacer("&", "&", "<", "<", ">", ">", "\"", """) + +// The http package's old HTML escaping function. +func oldhtmlEscape(s string) string { + s = Replace(s, "&", "&", -1) + s = Replace(s, "<", "<", -1) + s = Replace(s, ">", ">", -1) + s = Replace(s, "\"", """, -1) + s = Replace(s, "'", "'", -1) + return s +} + +var replacer = NewReplacer("aaa", "3[aaa]", "aa", "2[aa]", "a", "1[a]", "i", "i", + "longerst", "most long", "longer", "medium", "long", "short", + "X", "Y", "Y", "Z") + +var capitalLetters = NewReplacer("a", "A", "b", "B") + +var blankToXReplacer = NewReplacer("", "X", "o", "O") + +var ReplacerTests = []ReplacerTest{ + // byte->string + {htmlEscaper, "No changes", "No changes"}, + {htmlEscaper, "I <3 escaping & stuff", "I <3 escaping & stuff"}, + {htmlEscaper, "&&&", "&&&"}, + + // generic + {replacer, "fooaaabar", "foo3[aaa]b1[a]r"}, + {replacer, "long, longerst, longer", "short, most long, medium"}, + {replacer, "XiX", "YiY"}, + + // byte->byte + {capitalLetters, "brad", "BrAd"}, + {capitalLetters, Repeat("a", (32<<10)+123), Repeat("A", (32<<10)+123)}, + + // hitting "" special case + {blankToXReplacer, "oo", "XOXOX"}, +} + +func TestReplacer(t *testing.T) { + for i, tt := range ReplacerTests { + if s := tt.r.Replace(tt.in); s != tt.out { + t.Errorf("%d. Replace(%q) = %q, want %q", i, tt.in, s, tt.out) + } + var buf bytes.Buffer + n, err := tt.r.WriteString(&buf, tt.in) + if err != nil { + t.Errorf("%d. WriteString: %v", i, err) + continue + } + got := buf.String() + if got != tt.out { + t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tt.in, got, tt.out) + continue + } + if n != len(tt.out) { + t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)", + i, tt.in, n, len(tt.out), tt.out) + } + } +} + +// pickAlgorithmTest is a test that verifies that given input for a +// Replacer that we pick the correct algorithm. +type pickAlgorithmTest struct { + r *Replacer + want string // name of algorithm +} + +var pickAlgorithmTests = []pickAlgorithmTest{ + {capitalLetters, "*strings.byteReplacer"}, + {NewReplacer("12", "123"), "*strings.genericReplacer"}, + {NewReplacer("1", "12"), "*strings.byteStringReplacer"}, + {htmlEscaper, "*strings.byteStringReplacer"}, +} + +func TestPickAlgorithm(t *testing.T) { + for i, tt := range pickAlgorithmTests { + got := fmt.Sprintf("%T", tt.r.Replacer()) + if got != tt.want { + t.Errorf("%d. algorithm = %s, want %s", i, got, tt.want) + } + } +} + +func BenchmarkGenericMatch(b *testing.B) { + str := Repeat("A", 100) + Repeat("B", 100) + generic := NewReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic + for i := 0; i < b.N; i++ { + generic.Replace(str) + } +} + +func BenchmarkByteByteNoMatch(b *testing.B) { + str := Repeat("A", 100) + Repeat("B", 100) + for i := 0; i < b.N; i++ { + capitalLetters.Replace(str) + } +} + +func BenchmarkByteByteMatch(b *testing.B) { + str := Repeat("a", 100) + Repeat("b", 100) + for i := 0; i < b.N; i++ { + capitalLetters.Replace(str) + } +} + +func BenchmarkByteStringMatch(b *testing.B) { + str := "<" + Repeat("a", 99) + Repeat("b", 99) + ">" + for i := 0; i < b.N; i++ { + htmlEscaper.Replace(str) + } +} + +func BenchmarkHTMLEscapeNew(b *testing.B) { + str := "I <3 to escape HTML & other text too." + for i := 0; i < b.N; i++ { + htmlEscaper.Replace(str) + } +} + +func BenchmarkHTMLEscapeOld(b *testing.B) { + str := "I <3 to escape HTML & other text too." + for i := 0; i < b.N; i++ { + oldhtmlEscape(str) + } +} + +// BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces. +func BenchmarkByteByteReplaces(b *testing.B) { + str := Repeat("a", 100) + Repeat("b", 100) + for i := 0; i < b.N; i++ { + Replace(Replace(str, "a", "A", -1), "b", "B", -1) + } +} + +// BenchmarkByteByteMap compares byteByteImpl against Map. +func BenchmarkByteByteMap(b *testing.B) { + str := Repeat("a", 100) + Repeat("b", 100) + fn := func(r int) int { + switch r { + case 'a': + return int('A') + case 'b': + return int('B') + } + return r + } + for i := 0; i < b.N; i++ { + Map(fn, str) + } +} |