1
0
treerack/url_test.go
2026-06-24 11:16:26 +02:00

1597 lines
49 KiB
Go

package treerack
import (
"bytes"
"code.squareroundforest.org/arpio/notation"
"net/url"
"os"
"testing"
"time"
)
type urlCheck struct {
stdQuery func(u *url.URL) string
treerackQuery func(Node) string
expect string
}
type urlTestCase struct {
title string
input string
checks []urlCheck
bench int
skipSTD bool
skipSTDReq bool
}
func queryTreerack(p ...string) func(Node) string {
return func(a Node) string {
return astPath(a, p...)
}
}
func fakeSTDCheck(v string) func(*url.URL) string {
return func(*url.URL) string {
return v
}
}
func fakeTRCheck(v string) func(Node) string {
return func(Node) string {
return v
}
}
func printURLTree(t *testing.T, a Node) {
var trimTokens func(a Node) Node
trimTokens = func(a Node) Node {
for i := range a.Nodes {
a.Nodes[i] = trimTokens(a.Nodes[i])
}
a.tokens = nil
return a
}
a = trimTokens(a)
notation.Lprintw(t, a)
}
func urlParser(trace bool) func(string) (Node, error) {
b, err := os.ReadFile("doc/example/url.treerack")
if err != nil {
panic(err)
}
p := new(Syntax)
if trace {
p.MaxTraceLength = 180
}
if err = p.ReadSyntax(bytes.NewBuffer(b)); err != nil {
panic(err)
}
return func(s string) (a Node, err error) {
return p.Parse(bytes.NewBufferString(s))
}
}
func astPath(a Node, p ...string) string {
if len(p) == 0 {
return a.Text()
}
for _, ai := range a.Nodes {
if ai.Name == p[0] {
return astPath(ai, p[1:]...)
}
}
return ""
}
func TestURL(t *testing.T) {
for _, test := range []urlTestCase{{
title: "scheme only",
input: "http:",
bench: 3600,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}},
}, {
title: "scheme only with separator",
input: "http://",
bench: 3600,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}},
}, {
title: "user and passord only",
input: "//foo:bar@",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}},
}, {
title: "user only",
input: "//foo@",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo",
}},
}, {
title: "host only",
input: "//foo.bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}},
}, {
title: "host only with port",
input: "//foo.bar:8080",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("foo.bar:8080"),
expect: "foo.bar:8080",
}, {
stdQuery: fakeSTDCheck("foo.bar"),
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: fakeSTDCheck("8080"),
treerackQuery: queryTreerack("relative-url", "port"),
expect: "8080",
}},
}, {
title: "absolute path only",
input: "/foo/bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute"),
expect: "/foo/bar",
}},
}, {
title: "relative path only",
input: "foo/bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
expect: "foo/bar",
}},
}, {
title: "relative path only with navigation segments",
input: "../foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
expect: "../foo",
}},
}, {
title: "query only",
input: "?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "query only empty",
input: "?",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "",
}},
}, {
title: "fragment only",
input: "#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "fragment only empty",
input: "#",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "",
}},
}, {
title: "scheme and user",
input: "http://foo:bar@",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}},
}, {
title: "scheme and user without password",
input: "http://foo@",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo",
}},
}, {
title: "scheme and host",
input: "http://foo.bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}},
}, {
title: "scheme and host ipv4 as domain name because of numeric range",
input: "http://256.0.0.1",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "256.0.0.1",
}},
}, {
title: "scheme and host ipv4 as domain name because of leading zero",
input: "http://128.0.0.01",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "128.0.0.01",
}},
}, {
title: "scheme and host ipv4",
input: "http://128.0.0.1",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv4"),
expect: "128.0.0.1",
}},
}, {
title: "scheme and host ipv6",
input: "http://[fe80::1]",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("[fe80::1]"),
expect: "[fe80::1]",
}, {
stdQuery: fakeSTDCheck("fe80::1"),
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6"),
expect: "fe80::1",
}},
}, {
title: "scheme and host ipv6 with zone",
input: "http://[fe80::1%25eth0]",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("[fe80::1%eth0]"),
expect: "[fe80::1%eth0]",
}, {
stdQuery: fakeSTDCheck("fe80::1%25eth0"),
treerackQuery: queryTreerack("absolute-url", "hostname", "ipv6-zone"),
expect: "fe80::1%25eth0",
}},
}, {
title: "scheme and host with port",
input: "http://foo.bar:8080",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: fakeTRCheck("foo.bar:8080"),
expect: "foo.bar:8080",
}, {
stdQuery: fakeSTDCheck("foo.bar"),
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: fakeSTDCheck("8080"),
treerackQuery: queryTreerack("absolute-url", "port"),
expect: "8080",
}},
}, {
title: "scheme and path",
input: "http:/foo/bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
expect: "/foo/bar",
}},
}, {
title: "scheme and relative path",
input: "http:foo/bar",
skipSTD: true,
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-rootless"),
expect: "foo/bar",
}},
}, {
title: "scheme and query",
input: "http:?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and query empty",
input: "http:?",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "",
}},
}, {
title: "scheme and fragment",
input: "http:#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and fragment",
input: "http:#",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "",
}},
}, {
title: "user and host",
input: "//foo:bar@foo.bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}},
}, {
title: "user and path",
input: "//foo:bar@/foo/bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "user and query",
input: "//foo:bar@?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url-rfc", "query"),
expect: "foo=bar",
}},
}, {
title: "user and fragment",
input: "//foo:bar@#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "host and path",
input: "//foo.bar/foo/bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "host and query",
input: "//foo.bar?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "host and fragment",
input: "//foo.bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "path and query",
input: "/foo/bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "path and fragment",
input: "/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "query and fragment",
input: "?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and host",
input: "http://foo:bar@foo.bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}},
}, {
title: "scheme and user and path",
input: "http://foo:bar@/foo/bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "scheme and user and query",
input: "http://foo:bar@?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and user and fragment",
input: "http://foo:bar@#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and host and path",
input: "http://foo.bar/foo/bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "scheme and host and query",
input: "http://foo.bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and host and fragment",
input: "http://foo.bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and path and query",
input: "http:/foo/bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and path and fragment",
input: "http:/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and query and fragment",
input: "http:?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "user and host and path",
input: "//foo:bar@foo.bar/foo/bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "user and host and query",
input: "//foo:bar@foo.bar?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "user and host and fragment",
input: "//foo:bar@foo.bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "user and path and query",
input: "//foo:bar@/foo/bar?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url-rfc", "query"),
expect: "foo=bar",
}},
}, {
title: "user and path and fragment",
input: "//foo:bar@/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "user and query and fragment",
input: "//foo:bar@?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url-rfc", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "host and path and query",
input: "//foo.bar/foo/bar?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "host and path and fragment",
input: "//foo.bar/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "host and query and fragment",
input: "//foo.bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "path and query and fragment",
input: "/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "relative path and query and fragment",
input: "../foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-noscheme"),
expect: "../foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and host and path",
input: "http://foo:bar@foo.bar/foo/bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}},
}, {
title: "scheme and user and host and query",
input: "http://foo:bar@foo.bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and user and host and fragment",
input: "http://foo:bar@foo.bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and path and query",
input: "http://foo:bar@/foo/bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and user and path and fragment",
input: "http://foo:bar@/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and query and fragment",
input: "http://foo:bar@?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and host and path and query",
input: "http://foo.bar/foo/bar?foo=bar",
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and host and path and fragment",
input: "http://foo.bar/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and host and query and fragment",
input: "http://foo.bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and path and query and fragment",
input: "http:/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "user and host and path and query",
input: "//foo:bar@foo.bar/foo/bar?foo=bar",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}},
}, {
title: "user and host and path and fragment",
input: "//foo:bar@foo.bar/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "user and path and query and fragment",
input: "//foo:bar@/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url-rfc", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "host and path and query and fragment",
input: "//foo.bar/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and host and path and query",
input: "http://foo:bar@foo.bar/foo/bar?foo=bar",
bench: 3600,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}},
}, {
title: "scheme and user and host and path and fragment",
input: "http://foo:bar@foo.bar/foo/bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and host and query and fragment",
input: "http://foo:bar@foo.bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and path and query and fragment",
input: "http://foo:bar@/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url-rfc", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url-rfc", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url-rfc", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url-rfc", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url-rfc", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and host and path and query and fragment",
input: "http://foo.bar/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}, {
title: "user and host and path and query and fragment",
input: "//foo:bar@foo.bar/foo/bar?foo=bar#foo",
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("relative-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("relative-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("relative-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("relative-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("relative-url", "fragment"),
expect: "foo",
}},
}, {
title: "scheme and user and host and path and query and fragment",
input: "http://foo:bar@foo.bar/foo/bar?foo=bar#foo",
bench: 3600,
skipSTDReq: true,
checks: []urlCheck{{
stdQuery: func(u *url.URL) string { return u.Scheme },
treerackQuery: queryTreerack("absolute-url", "scheme"),
expect: "http",
}, {
stdQuery: func(u *url.URL) string { return u.User.String() },
treerackQuery: queryTreerack("absolute-url", "userinfo"),
expect: "foo:bar",
}, {
stdQuery: func(u *url.URL) string { return u.Host },
treerackQuery: queryTreerack("absolute-url", "hostname", "domain-name"),
expect: "foo.bar",
}, {
stdQuery: func(u *url.URL) string { return u.Path },
treerackQuery: queryTreerack("absolute-url", "path-absolute-or-empty"),
expect: "/foo/bar",
}, {
stdQuery: func(u *url.URL) string { return u.RawQuery },
treerackQuery: queryTreerack("absolute-url", "query"),
expect: "foo=bar",
}, {
stdQuery: func(u *url.URL) string { return u.Fragment },
treerackQuery: queryTreerack("absolute-url", "fragment"),
expect: "foo",
}},
}} {
t.Run(test.title, func(t *testing.T) {
t.Run("std", func(t *testing.T) {
if test.skipSTD {
t.Skip("!!!skipping standard library parser!!!")
}
n := test.bench
if n <= 0 {
n = 1
}
var d time.Duration
for i := 0; i < n && !t.Failed(); i++ {
start := time.Now()
u, err := url.Parse(test.input)
d += time.Since(start)
if err != nil {
t.Fatal(err)
}
if i > 0 {
continue
}
for _, check := range test.checks {
v := check.stdQuery(u)
if v != check.expect {
notation.Lprintw(t, u)
t.Fatal("expecting:", check.expect, "got:", v)
}
}
}
if test.bench > 0 {
t.Log("average duration:", d/time.Duration(n))
}
})
t.Run("stdreq", func(t *testing.T) {
if test.skipSTDReq {
t.Skip("non-request URI")
}
n := test.bench
if n <= 0 {
n = 1
}
var d time.Duration
for i := 0; i < n && !t.Failed(); i++ {
start := time.Now()
u, err := url.ParseRequestURI(test.input)
d += time.Since(start)
if err != nil {
t.Fatal(err)
}
if i > 0 {
continue
}
for _, check := range test.checks {
v := check.stdQuery(u)
if v != check.expect {
notation.Lprintw(t, u)
t.Fatal("expecting:", check.expect, "got:", v)
}
}
}
if test.bench > 0 {
t.Log("average duration:", d/time.Duration(n))
}
})
t.Run("treerack", func(t *testing.T) {
n := test.bench
if n <= 0 {
n = 1
}
var d time.Duration
p := urlParser(test.bench <= 0)
for i := 0; i < n && !t.Failed(); i++ {
start := time.Now()
a, err := p(test.input)
d += time.Since(start)
if err != nil {
Trace(t.Output(), err)
t.Fatal(err)
}
if i > 0 {
continue
}
for _, check := range test.checks {
v := check.treerackQuery(a)
if v != check.expect {
printURLTree(t, a)
t.Fatal("expecting:", check.expect, "got:", v)
}
}
}
if test.bench > 0 {
t.Log("average duration:", d/time.Duration(n))
}
})
})
}
}
func TestURLErrors(t *testing.T) {
for _, test := range []struct{ title, input string }{{
title: "scheme cannot start on a number",
input: "123http://foo.bar/foo/bar",
}, {
title: "scheme characters",
input: "http,unix://foo.bar/foo/bar",
}, {
title: "ipv4 in brackets",
input: "http://[128.0.0.1]",
}, {
title: "ipv6 without closing bracket",
input: "http://[fe80::1%25eth0",
}, {
title: "invalid port",
input: "http://foo.bar:99x99",
}, {
title: "invalid path",
input: "http://foo.bar/foo%xbar",
}} {
t.Run(test.title, func(t *testing.T) {
p := urlParser(false)
if a, err := p(test.input); err == nil {
printURLTree(t, a)
t.Fatal("failed to fail", test.input)
}
})
}
}