blob: 543fe527ba2aa4cbdabdc7746f95f9c422e4949d [file] [log] [blame]
// Copyright 2016 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 idna
import (
"encoding/hex"
"fmt"
"regexp"
"strconv"
"strings"
"testing"
"golang.org/x/text/internal/testtext"
)
func TestAllocToUnicode(t *testing.T) {
avg := testtext.AllocsPerRun(1000, func() {
ToUnicode("www.golang.org")
})
if avg > 0 {
t.Errorf("got %f; want 0", avg)
}
}
func TestAllocToASCII(t *testing.T) {
avg := testtext.AllocsPerRun(1000, func() {
ToASCII("www.golang.org")
})
if avg > 0 {
t.Errorf("got %f; want 0", avg)
}
}
func TestProfiles(t *testing.T) {
testCases := []struct {
name string
want, got *Profile
}{
{"Punycode", punycode, New()},
{"Registration", registration, New(ValidateForRegistration())},
{"Registration", registration, New(
ValidateForRegistration(),
VerifyDNSLength(true),
BidiRule(),
)},
{"Lookup", lookup, New(MapForLookup(), BidiRule(), Transitional(transitionalLookup))},
{"Display", display, New(MapForLookup(), BidiRule())},
}
for _, tc := range testCases {
// Functions are not comparable, but the printed version will include
// their pointers.
got := fmt.Sprintf("%#v", tc.got)
want := fmt.Sprintf("%#v", tc.want)
if got != want {
t.Errorf("%s: \ngot %#v,\nwant %#v", tc.name, got, want)
}
}
}
// doTest performs a single test f(input) and verifies that the output matches
// out and that the returned error is expected. The errors string contains
// all allowed error codes as categorized in
// https://www.unicode.org/Public/idna/9.0.0/IdnaTest.txt:
// P: Processing
// V: Validity
// A: to ASCII
// B: Bidi
// C: Context J
func doTest(t *testing.T, f func(string) (string, error), name, input, want, errors string) {
errors = strings.Trim(errors, "[]")
test := "ok"
if errors != "" {
test = "err:" + errors
}
// Replace some of the escape sequences to make it easier to single out
// tests on the command name.
in := strings.Trim(strconv.QuoteToASCII(input), `"`)
in = strings.Replace(in, `\u`, "#", -1)
in = strings.Replace(in, `\U`, "#", -1)
name = fmt.Sprintf("%s/%s/%s", name, in, test)
t.Run(name, func(t *testing.T) {
got, err := f(input)
if err != nil {
code := err.(interface {
code() string
}).code()
if strings.Index(errors, code) == -1 {
t.Errorf("error %q not in set of expected errors {%v}", code, errors)
}
} else if errors != "" {
t.Errorf("no errors; want error in {%v}", errors)
}
if want != "" && got != want {
t.Errorf(`string: got %+q; want %+q`, got, want)
}
})
}
var unescapeRE = regexp.MustCompile(`\\u([0-9a-zA-Z]{4})`)
func unescape(s string) string {
return unescapeRE.ReplaceAllStringFunc(s, func(v string) string {
var d [2]byte
hex.Decode(d[:], []byte(v[2:]))
return string(rune(d[0])<<8 | rune(d[1]))
})
}
func BenchmarkProfile(b *testing.B) {
for i := 0; i < b.N; i++ {
Lookup.ToASCII("www.yahoogle.com")
}
}