mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			175 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Go
		
	
	
	
| // 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 rune) rune {
 | |
| 		switch r {
 | |
| 		case 'a':
 | |
| 			return 'A'
 | |
| 		case 'b':
 | |
| 			return 'B'
 | |
| 		}
 | |
| 		return r
 | |
| 	}
 | |
| 	for i := 0; i < b.N; i++ {
 | |
| 		Map(fn, str)
 | |
| 	}
 | |
| }
 |