diff --git a/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt new file mode 100644 index 00000000000..9f981c7baf6 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt @@ -0,0 +1,356 @@ +Harness status: OK + +Found 350 tests + +8 Pass +342 Fail +Pass Loading data... +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/ba"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: ["https://example.com/foo/bar"] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: ["https://example.com/foo/bar/baz"] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"hostname":"example.com","pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"hostname":"example.com","pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/baz","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"hostname":"example.com","pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?otherquery#otherhash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar?otherquery#otherhash"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar?query#hash"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar/baz"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://other.com/foo/bar"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["http://other.com/foo/bar"] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar/baz","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://other.com"}] +Fail Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"http://example.com"}] +Fail Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/([^\\/]+?)"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/index.html"}] +Fail Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/bar/"}] +Fail Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foobar"}] +Fail Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/fo"}] +Fail Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar/bar"}] +Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/"}] +Fail Pattern: [{"protocol":"(café)"}] Inputs: undefined +Fail Pattern: [{"username":"(café)"}] Inputs: undefined +Fail Pattern: [{"password":"(café)"}] Inputs: undefined +Fail Pattern: [{"hostname":"(café)"}] Inputs: undefined +Fail Pattern: [{"pathname":"(café)"}] Inputs: undefined +Fail Pattern: [{"search":"(café)"}] Inputs: undefined +Fail Pattern: [{"hash":"(café)"}] Inputs: undefined +Fail Pattern: [{"protocol":":café"}] Inputs: [{"protocol":"foo"}] +Fail Pattern: [{"username":":café"}] Inputs: [{"username":"foo"}] +Fail Pattern: [{"password":":café"}] Inputs: [{"password":"foo"}] +Fail Pattern: [{"hostname":":café"}] Inputs: [{"hostname":"foo"}] +Fail Pattern: [{"pathname":"/:café"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"search":":café"}] Inputs: [{"search":"foo"}] +Fail Pattern: [{"hash":":café"}] Inputs: [{"hash":"foo"}] +Fail Pattern: [{"protocol":":℘"}] Inputs: [{"protocol":"foo"}] +Fail Pattern: [{"username":":℘"}] Inputs: [{"username":"foo"}] +Fail Pattern: [{"password":":℘"}] Inputs: [{"password":"foo"}] +Fail Pattern: [{"hostname":":℘"}] Inputs: [{"hostname":"foo"}] +Fail Pattern: [{"pathname":"/:℘"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"search":":℘"}] Inputs: [{"search":"foo"}] +Fail Pattern: [{"hash":":℘"}] Inputs: [{"hash":"foo"}] +Fail Pattern: [{"protocol":":㐀"}] Inputs: [{"protocol":"foo"}] +Fail Pattern: [{"username":":㐀"}] Inputs: [{"username":"foo"}] +Fail Pattern: [{"password":":㐀"}] Inputs: [{"password":"foo"}] +Fail Pattern: [{"hostname":":㐀"}] Inputs: [{"hostname":"foo"}] +Fail Pattern: [{"pathname":"/:㐀"}] Inputs: [{"pathname":"/foo"}] +Fail Pattern: [{"search":":㐀"}] Inputs: [{"search":"foo"}] +Fail Pattern: [{"hash":":㐀"}] Inputs: [{"hash":"foo"}] +Fail Pattern: [{"protocol":"(.*)"}] Inputs: [{"protocol":"café"}] +Fail Pattern: [{"protocol":"(.*)"}] Inputs: [{"protocol":"cafe"}] +Fail Pattern: [{"protocol":"foo-bar"}] Inputs: [{"protocol":"foo-bar"}] +Fail Pattern: [{"username":"caf%C3%A9"}] Inputs: [{"username":"café"}] +Fail Pattern: [{"username":"café"}] Inputs: [{"username":"café"}] +Fail Pattern: [{"username":"caf%c3%a9"}] Inputs: [{"username":"café"}] +Fail Pattern: [{"password":"caf%C3%A9"}] Inputs: [{"password":"café"}] +Fail Pattern: [{"password":"café"}] Inputs: [{"password":"café"}] +Fail Pattern: [{"password":"caf%c3%a9"}] Inputs: [{"password":"café"}] +Fail Pattern: [{"hostname":"xn--caf-dma.com"}] Inputs: [{"hostname":"café.com"}] +Fail Pattern: [{"hostname":"café.com"}] Inputs: [{"hostname":"café.com"}] +Fail Pattern: ["http://U+deb2.com/"] Inputs: ["http://U+deb2.com/"] +Fail Pattern: ["http://\ud83d \udeb2"] Inputs: undefined +Fail Pattern: [{"hostname":"\ud83d \udeb2"}] Inputs: undefined +Fail Pattern: [{"pathname":"\ud83d \udeb2"}] Inputs: [] +Fail Pattern: [{"pathname":":\ud83d \udeb2"}] Inputs: undefined +Fail Pattern: [{"pathname":":aU+dd00b"}] Inputs: [] +Fail Pattern: [{"pathname":"test/:aU+dc50b"}] Inputs: [{"pathname":"test/foo"}] +Fail Pattern: [{"pathname":":U+deb2"}] Inputs: undefined +Fail Pattern: [{"port":""}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http","port":"80{20}?"}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http","port":"80 "}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http","port":"100000"}] Inputs: [{"protocol":"http","port":"100000"}] +Fail Pattern: [{"port":"80"}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"protocol":"http{s}?","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] +Fail Pattern: [{"port":"80"}] Inputs: [{"port":"80"}] +Fail Pattern: [{"port":"(.*)"}] Inputs: [{"port":"invalid80"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/./bar"}] +Fail Pattern: [{"pathname":"/foo/baz"}] Inputs: [{"pathname":"/foo/bar/../baz"}] +Fail Pattern: [{"pathname":"/caf%C3%A9"}] Inputs: [{"pathname":"/café"}] +Fail Pattern: [{"pathname":"/café"}] Inputs: [{"pathname":"/café"}] +Fail Pattern: [{"pathname":"/caf%c3%a9"}] Inputs: [{"pathname":"/café"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"foo/bar"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"foo/bar","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"/foo/../bar"}] Inputs: [{"pathname":"/bar"}] +Fail Pattern: [{"pathname":"./foo/bar","baseURL":"https://example.com"}] Inputs: [{"pathname":"foo/bar","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"","baseURL":"https://example.com"}] Inputs: [{"pathname":"/","baseURL":"https://example.com"}] +Fail Pattern: [{"pathname":"{/bar}","baseURL":"https://example.com/foo/"}] Inputs: [{"pathname":"./bar","baseURL":"https://example.com/foo/"}] +Fail Pattern: [{"pathname":"\\/bar","baseURL":"https://example.com/foo/"}] Inputs: [{"pathname":"./bar","baseURL":"https://example.com/foo/"}] +Fail Pattern: [{"pathname":"b","baseURL":"https://example.com/foo/"}] Inputs: [{"pathname":"./b","baseURL":"https://example.com/foo/"}] +Fail Pattern: [{"pathname":"foo/bar"}] Inputs: ["https://example.com/foo/bar"] +Fail Pattern: [{"pathname":"foo/bar","baseURL":"https://example.com"}] Inputs: ["https://example.com/foo/bar"] +Fail Pattern: [{"pathname":":name.html","baseURL":"https://example.com"}] Inputs: ["https://example.com/foo.html"] +Fail Pattern: [{"search":"q=caf%C3%A9"}] Inputs: [{"search":"q=café"}] +Fail Pattern: [{"search":"q=café"}] Inputs: [{"search":"q=café"}] +Fail Pattern: [{"search":"q=caf%c3%a9"}] Inputs: [{"search":"q=café"}] +Fail Pattern: [{"hash":"caf%C3%A9"}] Inputs: [{"hash":"café"}] +Fail Pattern: [{"hash":"café"}] Inputs: [{"hash":"café"}] +Fail Pattern: [{"hash":"caf%c3%a9"}] Inputs: [{"hash":"café"}] +Fail Pattern: [{"protocol":"about","pathname":"(blank|sourcedoc)"}] Inputs: ["about:blank"] +Fail Pattern: [{"protocol":"data","pathname":":number([0-9]+)"}] Inputs: ["data:8675309"] +Fail Pattern: [{"pathname":"/(\\m)"}] Inputs: undefined +Fail Pattern: [{"pathname":"/foo!"}] Inputs: [{"pathname":"/foo!"}] +Fail Pattern: [{"pathname":"/foo\\:"}] Inputs: [{"pathname":"/foo:"}] +Fail Pattern: [{"pathname":"/foo\\{"}] Inputs: [{"pathname":"/foo{"}] +Fail Pattern: [{"pathname":"/foo\\("}] Inputs: [{"pathname":"/foo("}] +Fail Pattern: [{"protocol":"javascript","pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] +Fail Pattern: [{"pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] +Fail Pattern: [{"protocol":"javascript","pathname":"var x = 1;"}] Inputs: [{"baseURL":"javascript:var x = 1;"}] +Fail Pattern: [{"protocol":"(data|javascript)","pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] +Fail Pattern: [{"protocol":"(https|javascript)","pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] +Fail Pattern: [{"pathname":"var x = 1;"}] Inputs: [{"pathname":"var x = 1;"}] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: ["./foo/bar","https://example.com"] +Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"},"https://example.com"] +Fail Pattern: ["https://example.com:8080/foo?bar#baz"] Inputs: [{"pathname":"/foo","search":"bar","hash":"baz","baseURL":"https://example.com:8080"}] +Fail Pattern: ["/foo?bar#baz","https://example.com:8080"] Inputs: [{"pathname":"/foo","search":"bar","hash":"baz","baseURL":"https://example.com:8080"}] +Pass Pattern: ["/foo"] Inputs: undefined +Pass Pattern: ["example.com/foo"] Inputs: undefined +Fail Pattern: ["http{s}?://{*.}?example.com/:product/:endpoint"] Inputs: ["https://sub.example.com/foo/bar"] +Fail Pattern: ["https://example.com?foo"] Inputs: ["https://example.com/?foo"] +Fail Pattern: ["https://example.com#foo"] Inputs: ["https://example.com/#foo"] +Fail Pattern: ["https://example.com:8080?foo"] Inputs: ["https://example.com:8080/?foo"] +Fail Pattern: ["https://example.com:8080#foo"] Inputs: ["https://example.com:8080/#foo"] +Fail Pattern: ["https://example.com/?foo"] Inputs: ["https://example.com/?foo"] +Fail Pattern: ["https://example.com/#foo"] Inputs: ["https://example.com/#foo"] +Fail Pattern: ["https://example.com/*?foo"] Inputs: ["https://example.com/?foo"] +Fail Pattern: ["https://example.com/*\\?foo"] Inputs: ["https://example.com/?foo"] +Fail Pattern: ["https://example.com/:name?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/:name\\?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/(bar)?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/(bar)\\?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/{bar}?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/{bar}\\?foo"] Inputs: ["https://example.com/bar?foo"] +Fail Pattern: ["https://example.com/"] Inputs: ["https://example.com:8080/"] +Pass Pattern: ["data:foobar"] Inputs: ["data:foobar"] +Fail Pattern: ["data\\:foobar"] Inputs: ["data:foobar"] +Fail Pattern: ["https://{sub.}?example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["https://{sub.}?example{.com/}foo"] Inputs: ["https://example.com/foo"] +Pass Pattern: ["{https://}example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["https://(sub.)?example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["https://(sub.)?example(.com/)foo"] Inputs: ["https://example.com/foo"] +Pass Pattern: ["(https://)example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["https://{sub{.}}example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["https://(sub(?:.))?example.com/foo"] Inputs: ["https://example.com/foo"] +Fail Pattern: ["file:///foo/bar"] Inputs: ["file:///foo/bar"] +Fail Pattern: ["data:"] Inputs: ["data:"] +Fail Pattern: ["foo://bar"] Inputs: ["foo://bad_url_browser_interop"] +Fail Pattern: ["(café)://foo"] Inputs: undefined +Fail Pattern: ["https://example.com/foo?bar#baz"] Inputs: [{"protocol":"https:","search":"?bar","hash":"#baz","baseURL":"http://example.com/foo"}] +Fail Pattern: [{"protocol":"http{s}?:","search":"?bar","hash":"#baz"}] Inputs: ["http://example.com/foo?bar#baz"] +Fail Pattern: ["?bar#baz","https://example.com/foo"] Inputs: ["?bar#baz","https://example.com/foo"] +Fail Pattern: ["?bar","https://example.com/foo#baz"] Inputs: ["?bar","https://example.com/foo#snafu"] +Fail Pattern: ["#baz","https://example.com/foo?bar"] Inputs: ["#baz","https://example.com/foo?bar"] +Fail Pattern: ["#baz","https://example.com/foo"] Inputs: ["#baz","https://example.com/foo"] +Fail Pattern: [{"pathname":"*"}] Inputs: ["foo","data:data-urls-cannot-be-base-urls"] +Fail Pattern: [{"pathname":"*"}] Inputs: ["foo","not|a|valid|url"] +Fail Pattern: ["https://foo\\:bar@example.com"] Inputs: ["https://foo:bar@example.com"] +Fail Pattern: ["https://foo@example.com"] Inputs: ["https://foo@example.com"] +Fail Pattern: ["https://\\:bar@example.com"] Inputs: ["https://:bar@example.com"] +Fail Pattern: ["https://:user::pass@example.com"] Inputs: ["https://foo:bar@example.com"] +Fail Pattern: ["https\\:foo\\:bar@example.com"] Inputs: ["https:foo:bar@example.com"] +Fail Pattern: ["data\\:foo\\:bar@example.com"] Inputs: ["data:foo:bar@example.com"] +Fail Pattern: ["https://foo{\\:}bar@example.com"] Inputs: ["https://foo:bar@example.com"] +Fail Pattern: ["data{\\:}channel.html","https://example.com"] Inputs: ["https://example.com/data:channel.html"] +Fail Pattern: ["http://[\\:\\:1]/"] Inputs: ["http://[::1]/"] +Fail Pattern: ["http://[\\:\\:1]:8080/"] Inputs: ["http://[::1]:8080/"] +Fail Pattern: ["http://[\\:\\:a]/"] Inputs: ["http://[::a]/"] +Fail Pattern: ["http://[:address]/"] Inputs: ["http://[::1]/"] +Fail Pattern: ["http://[\\:\\:AB\\::num]/"] Inputs: ["http://[::ab:1]/"] +Fail Pattern: [{"hostname":"[\\:\\:AB\\::num]"}] Inputs: [{"hostname":"[::ab:1]"}] +Fail Pattern: [{"hostname":"[\\:\\:xY\\::num]"}] Inputs: undefined +Fail Pattern: [{"hostname":"{[\\:\\:ab\\::num]}"}] Inputs: [{"hostname":"[::ab:1]"}] +Fail Pattern: [{"hostname":"{[\\:\\:fé\\::num]}"}] Inputs: undefined +Fail Pattern: [{"hostname":"{[\\:\\::num\\:1]}"}] Inputs: [{"hostname":"[::ab:1]"}] +Fail Pattern: [{"hostname":"{[\\:\\::num\\:fé]}"}] Inputs: undefined +Fail Pattern: [{"hostname":"[*\\:1]"}] Inputs: [{"hostname":"[::ab:1]"}] +Fail Pattern: [{"hostname":"*\\:1]"}] Inputs: undefined +Fail Pattern: ["https://foo{{@}}example.com"] Inputs: ["https://foo@example.com"] +Fail Pattern: ["https://foo{@example.com"] Inputs: ["https://foo@example.com"] +Fail Pattern: ["data\\:text/javascript,let x = 100/:tens?5;"] Inputs: ["data:text/javascript,let x = 100/5;"] +Fail Pattern: [{"pathname":"/:id/:id"}] Inputs: undefined +Fail Pattern: [{"pathname":"/foo","baseURL":""}] Inputs: undefined +Fail Pattern: ["/foo",""] Inputs: undefined +Pass Pattern: [{"pathname":"/foo"},"https://example.com"] Inputs: undefined +Fail Pattern: [{"pathname":":name*"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":name+"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":name"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"protocol":":name*"}] Inputs: [{"protocol":"foobar"}] +Fail Pattern: [{"protocol":":name+"}] Inputs: [{"protocol":"foobar"}] +Fail Pattern: [{"protocol":":name"}] Inputs: [{"protocol":"foobar"}] +Fail Pattern: [{"hostname":"bad hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad#hostname"}] Inputs: [{"hostname":"bad"}] +Fail Pattern: [{"hostname":"bad%hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad/hostname"}] Inputs: [{"hostname":"bad"}] +Fail Pattern: [{"hostname":"bad\\:hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"badhostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad?hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad@hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad[hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad]hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad\\\\hostname"}] Inputs: [{"hostname":"badhostname"}] +Fail Pattern: [{"hostname":"bad^hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad|hostname"}] Inputs: undefined +Fail Pattern: [{"hostname":"bad\nhostname"}] Inputs: [{"hostname":"badhostname"}] +Fail Pattern: [{"hostname":"bad\rhostname"}] Inputs: [{"hostname":"badhostname"}] +Fail Pattern: [{"hostname":"bad\thostname"}] Inputs: [{"hostname":"badhostname"}] +Fail Pattern: [{}] Inputs: ["https://example.com/"] +Fail Pattern: [] Inputs: ["https://example.com/"] +Fail Pattern: [] Inputs: [{}] +Fail Pattern: [] Inputs: [] +Fail Pattern: [{"pathname":"(foo)(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{(foo)bar}(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"(foo)?(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}(barbaz)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}{(.*)}"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}{(.*)bar}"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}{bar(.*)}"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}:bar(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo}?(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Fail Pattern: [{"pathname":"{:foo\\bar}"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":"{:foo\\.bar}"}] Inputs: [{"pathname":"foo.bar"}] +Fail Pattern: [{"pathname":"{:foo(foo)bar}"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":"{:foo}bar"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":foo\\bar"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":foo{}(.*)"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":foo{}bar"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":foo{}?bar"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":"*{}**?"}] Inputs: [{"pathname":"foobar"}] +Fail Pattern: [{"pathname":":foo(baz)(.*)"}] Inputs: [{"pathname":"bazbar"}] +Fail Pattern: [{"pathname":":foo(baz)bar"}] Inputs: [{"pathname":"bazbar"}] +Fail Pattern: [{"pathname":"*/*"}] Inputs: [{"pathname":"foo/bar"}] +Fail Pattern: [{"pathname":"*\\/*"}] Inputs: [{"pathname":"foo/bar"}] +Fail Pattern: [{"pathname":"*/{*}"}] Inputs: [{"pathname":"foo/bar"}] +Fail Pattern: [{"pathname":"*//*"}] Inputs: [{"pathname":"foo/bar"}] +Fail Pattern: [{"pathname":"/:foo."}] Inputs: [{"pathname":"/bar."}] +Fail Pattern: [{"pathname":"/:foo.."}] Inputs: [{"pathname":"/bar.."}] +Fail Pattern: [{"pathname":"./foo"}] Inputs: [{"pathname":"./foo"}] +Fail Pattern: [{"pathname":"../foo"}] Inputs: [{"pathname":"../foo"}] +Fail Pattern: [{"pathname":":foo./"}] Inputs: [{"pathname":"bar./"}] +Fail Pattern: [{"pathname":":foo../"}] Inputs: [{"pathname":"bar../"}] +Fail Pattern: [{"pathname":"/:foo\\bar"}] Inputs: [{"pathname":"/bazbar"}] +Fail Pattern: [{"pathname":"/foo/bar"},{"ignoreCase":true}] Inputs: [{"pathname":"/FOO/BAR"}] +Fail Pattern: [{"ignoreCase":true}] Inputs: [{"pathname":"/FOO/BAR"}] +Fail Pattern: ["https://example.com:8080/foo?bar#baz",{"ignoreCase":true}] Inputs: [{"pathname":"/FOO","search":"BAR","hash":"BAZ","baseURL":"https://example.com:8080"}] +Fail Pattern: ["/foo?bar#baz","https://example.com:8080",{"ignoreCase":true}] Inputs: [{"pathname":"/FOO","search":"BAR","hash":"BAZ","baseURL":"https://example.com:8080"}] +Pass Pattern: ["/foo?bar#baz",{"ignoreCase":true},"https://example.com:8080"] Inputs: [{"pathname":"/FOO","search":"BAR","hash":"BAZ","baseURL":"https://example.com:8080"}] +Fail Pattern: [{"search":"foo","baseURL":"https://example.com/a/+/b"}] Inputs: [{"search":"foo","baseURL":"https://example.com/a/+/b"}] +Fail Pattern: [{"hash":"foo","baseURL":"https://example.com/?q=*&v=?&hmm={}&umm=()"}] Inputs: [{"hash":"foo","baseURL":"https://example.com/?q=*&v=?&hmm={}&umm=()"}] +Fail Pattern: ["#foo","https://example.com/?q=*&v=?&hmm={}&umm=()"] Inputs: ["https://example.com/?q=*&v=?&hmm={}&umm=()#foo"] +Fail Pattern: [{"pathname":"/([[a-z]--a])"}] Inputs: [{"pathname":"/a"}] +Fail Pattern: [{"pathname":"/([[a-z]--a])"}] Inputs: [{"pathname":"/z"}] +Fail Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/0"}] +Fail Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/3"}] \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json new file mode 100644 index 00000000000..f92ab76b71d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntestdata.json @@ -0,0 +1,2956 @@ +[ + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/ba" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/bar/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [ "https://example.com/foo/bar" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": { "0": "example.com" } }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": { "0": "https" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [ "https://example.com/foo/bar/baz" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "hostname": "example.com", "pathname": "/foo/bar" }], + "expected_match": { + "hostname": { "input": "example.com", "groups": { "0": "example.com" } }, + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "hostname": "example.com", "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/bar", "baseURL": "https://example.com" }], + "expected_match": { + "hostname": { "input": "example.com", "groups": { "0": "example.com" } }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": { "0": "https" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/bar/baz", + "baseURL": "https://example.com" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "hostname": "example.com", "pathname": "/foo/bar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar", "search": "otherquery", + "hash": "otherhash" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hash": { "input": "otherhash", "groups": { "0": "otherhash" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "otherquery", "groups": { "0": "otherquery" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar", "search": "otherquery", + "hash": "otherhash" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hash": { "input": "otherhash", "groups": { "0": "otherhash" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "otherquery", "groups": { "0": "otherquery" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?otherquery#otherhash" }], + "inputs": [{ "protocol": "https", "hostname": "example.com", + "pathname": "/foo/bar", "search": "otherquery", + "hash": "otherhash" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hash": { "input": "otherhash", "groups": { "0": "otherhash" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "otherquery", "groups": { "0": "otherquery" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "https://example.com/foo/bar" ], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "https://example.com/foo/bar?otherquery#otherhash" ], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hash": { "input": "otherhash", "groups": { "0": "otherhash" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "otherquery", "groups": { "0": "otherquery" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "https://example.com/foo/bar?query#hash" ], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hash": { "input": "hash", "groups": { "0": "hash" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "query", "groups": { "0": "query" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "https://example.com/foo/bar/baz" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "https://other.com/foo/bar" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [ "http://other.com/foo/bar" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar", "baseURL": "https://example.com" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar/baz", + "baseURL": "https://example.com" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar", "baseURL": "https://other.com" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar", + "baseURL": "https://example.com?query#hash" }], + "inputs": [{ "pathname": "/foo/bar", "baseURL": "http://example.com" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "bar": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/([^\\/]+?)" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar" }], + "inputs": [{ "pathname": "/foo/index.html" }], + "expected_match": { + "pathname": { "input": "/foo/index.html", "groups": { "bar": "index.html" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar" }], + "inputs": [{ "pathname": "/foo/bar/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_obj": { + "pathname": "/foo/*" + }, + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_obj": { + "pathname": "/foo/*" + }, + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_obj": { + "pathname": "/foo/*" + }, + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)" }], + "inputs": [{ "pathname": "/foo" }], + "expected_obj": { + "pathname": "/foo/*" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar(.*)" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "bar": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar(.*)" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "bar": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar(.*)" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "bar": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar(.*)" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar?" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "bar": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar?" }], + "inputs": [{ "pathname": "/foo" }], + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "bar": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar?" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar?" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar?" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar+" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "bar": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar+" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "bar": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar+" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar+" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar+" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar*" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "bar": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar*" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "bar": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar*" }], + "inputs": [{ "pathname": "/foo" }], + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "bar": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/:bar*" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/:bar*" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/foo" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "0": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/foo" }], + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "0": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)?" }], + "inputs": [{ "pathname": "/fo" }], + "expected_obj": { + "pathname": "/foo/*?" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*?" }], + "inputs": [{ "pathname": "/fo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/foo" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)+" }], + "inputs": [{ "pathname": "/fo" }], + "expected_obj": { + "pathname": "/foo/*+" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/*+" }], + "inputs": [{ "pathname": "/fo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": { "0": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": { + "pathname": { "input": "/foo/bar/baz", "groups": { "0": "bar/baz" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/foo" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "0": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/foo" }], + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "/foo", "groups": { "0": null } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": { + "pathname": { "input": "/foo/", "groups": { "0": "" } } + } + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/foobar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/(.*)*" }], + "inputs": [{ "pathname": "/fo" }], + "expected_obj": { + "pathname": "/foo/**" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/**" }], + "inputs": [{ "pathname": "/fo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}" }], + "inputs": [{ "pathname": "/foo" }], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}?" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}?" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}?" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": { + "pathname": { "input": "/foo", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}?" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}+" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}+" }], + "inputs": [{ "pathname": "/foo/bar/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}+" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}+" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}+" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}*" }], + "inputs": [{ "pathname": "/foo/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}*" }], + "inputs": [{ "pathname": "/foo/bar/bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar/bar", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}*" }], + "inputs": [{ "pathname": "/foo/bar/baz" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo{/bar}*" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": { + "pathname": { "input": "/foo", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/foo{/bar}*" }], + "inputs": [{ "pathname": "/foo/" }], + "expected_match": null + }, + { + "pattern": [{ "protocol": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "username": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "password": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "pathname": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "search": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hash": "(café)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "protocol": ":café" }], + "inputs": [{ "protocol": "foo" }], + "expected_match": { + "protocol": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "username": ":café" }], + "inputs": [{ "username": "foo" }], + "expected_match": { + "username": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "password": ":café" }], + "inputs": [{ "password": "foo" }], + "expected_match": { + "password": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "hostname": ":café" }], + "inputs": [{ "hostname": "foo" }], + "expected_match": { + "hostname": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "pathname": "/:café" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": { + "pathname": { "input": "/foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "search": ":café" }], + "inputs": [{ "search": "foo" }], + "expected_match": { + "search": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "hash": ":café" }], + "inputs": [{ "hash": "foo" }], + "expected_match": { + "hash": { "input": "foo", "groups": { "café": "foo" } } + } + }, + { + "pattern": [{ "protocol": ":\u2118" }], + "inputs": [{ "protocol": "foo" }], + "expected_match": { + "protocol": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "username": ":\u2118" }], + "inputs": [{ "username": "foo" }], + "expected_match": { + "username": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "password": ":\u2118" }], + "inputs": [{ "password": "foo" }], + "expected_match": { + "password": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "hostname": ":\u2118" }], + "inputs": [{ "hostname": "foo" }], + "expected_match": { + "hostname": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "pathname": "/:\u2118" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": { + "pathname": { "input": "/foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "search": ":\u2118" }], + "inputs": [{ "search": "foo" }], + "expected_match": { + "search": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "hash": ":\u2118" }], + "inputs": [{ "hash": "foo" }], + "expected_match": { + "hash": { "input": "foo", "groups": { "\u2118": "foo" } } + } + }, + { + "pattern": [{ "protocol": ":\u3400" }], + "inputs": [{ "protocol": "foo" }], + "expected_match": { + "protocol": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "username": ":\u3400" }], + "inputs": [{ "username": "foo" }], + "expected_match": { + "username": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "password": ":\u3400" }], + "inputs": [{ "password": "foo" }], + "expected_match": { + "password": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "hostname": ":\u3400" }], + "inputs": [{ "hostname": "foo" }], + "expected_match": { + "hostname": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "pathname": "/:\u3400" }], + "inputs": [{ "pathname": "/foo" }], + "expected_match": { + "pathname": { "input": "/foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "search": ":\u3400" }], + "inputs": [{ "search": "foo" }], + "expected_match": { + "search": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "hash": ":\u3400" }], + "inputs": [{ "hash": "foo" }], + "expected_match": { + "hash": { "input": "foo", "groups": { "\u3400": "foo" } } + } + }, + { + "pattern": [{ "protocol": "(.*)" }], + "inputs": [{ "protocol" : "café" }], + "expected_obj": { + "protocol": "*" + }, + "expected_match": null + }, + { + "pattern": [{ "protocol": "(.*)" }], + "inputs": [{ "protocol": "cafe" }], + "expected_obj": { + "protocol": "*" + }, + "expected_match": { + "protocol": { "input": "cafe", "groups": { "0": "cafe" }} + } + }, + { + "pattern": [{ "protocol": "foo-bar" }], + "inputs": [{ "protocol": "foo-bar" }], + "expected_match": { + "protocol": { "input": "foo-bar", "groups": {} } + } + }, + { + "pattern": [{ "username": "caf%C3%A9" }], + "inputs": [{ "username" : "café" }], + "expected_match": { + "username": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "username": "café" }], + "inputs": [{ "username" : "café" }], + "expected_obj": { + "username": "caf%C3%A9" + }, + "expected_match": { + "username": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "username": "caf%c3%a9" }], + "inputs": [{ "username" : "café" }], + "expected_match": null + }, + { + "pattern": [{ "password": "caf%C3%A9" }], + "inputs": [{ "password" : "café" }], + "expected_match": { + "password": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "password": "café" }], + "inputs": [{ "password" : "café" }], + "expected_obj": { + "password": "caf%C3%A9" + }, + "expected_match": { + "password": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "password": "caf%c3%a9" }], + "inputs": [{ "password" : "café" }], + "expected_match": null + }, + { + "pattern": [{ "hostname": "xn--caf-dma.com" }], + "inputs": [{ "hostname" : "café.com" }], + "expected_match": { + "hostname": { "input": "xn--caf-dma.com", "groups": {}} + } + }, + { + "pattern": [{ "hostname": "café.com" }], + "inputs": [{ "hostname" : "café.com" }], + "expected_obj": { + "hostname": "xn--caf-dma.com" + }, + "expected_match": { + "hostname": { "input": "xn--caf-dma.com", "groups": {}} + } + }, + { + "pattern": ["http://\uD83D\uDEB2.com/"], + "inputs": ["http://\uD83D\uDEB2.com/"], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http", + "hostname": "xn--h78h.com", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {}}, + "hostname": { "input": "xn--h78h.com", "groups": {}}, + "pathname": { "input": "/", "groups": {}} + } + }, + { + "pattern": ["http://\uD83D \uDEB2"], + "expected_obj": "error" + }, + { + "pattern": [{"hostname":"\uD83D \uDEB2"}], + "expected_obj": "error" + }, + { + "pattern": [{"pathname":"\uD83D \uDEB2"}], + "inputs": [], + "expected_obj": { + "pathname": "%EF%BF%BD%20%EF%BF%BD" + }, + "expected_match": null + }, + { + "pattern": [{"pathname":":\uD83D \uDEB2"}], + "expected_obj": "error" + }, + { + "pattern": [{"pathname":":a\uDB40\uDD00b"}], + "inputs": [], + "expected_obj": { + "pathname": ":a\uDB40\uDD00b" + }, + "expected_match": null + }, + { + "pattern": [{"pathname":"test/:a\uD801\uDC50b"}], + "inputs": [{"pathname":"test/foo"}], + "expected_obj": { + "pathname": "test/:a\uD801\uDC50b" + }, + "expected_match": { + "pathname": { "input": "test/foo", "groups": { "a\uD801\uDC50b": "foo" }} + } + }, + { + "pattern": [{"pathname":":\uD83D\uDEB2"}], + "expected_obj": "error" + }, + { + "pattern": [{ "port": "" }], + "inputs": [{ "protocol": "http", "port": "80" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "protocol": { "input": "http", "groups": { "0": "http" }} + } + }, + { + "pattern": [{ "protocol": "http", "port": "80" }], + "inputs": [{ "protocol": "http", "port": "80" }], + "exactly_empty_components": [ "port" ], + "expected_match": { + "protocol": { "input": "http", "groups": {}} + } + }, + { + "pattern": [{ "protocol": "http", "port": "80{20}?" }], + "inputs": [{ "protocol": "http", "port": "80" }], + "expected_match": null + }, + { + "pattern": [{ "protocol": "http", "port": "80 " }], + "inputs": [{ "protocol": "http", "port": "80" }], + "exactly_empty_components": ["port"], + "expected_match": { + "protocol": { "input": "http", "groups": {} } + } + }, + { + "pattern": [{ "protocol": "http", "port": "100000" }], + "inputs": [{ "protocol": "http", "port": "100000" }], + "expected_obj": "error" + }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "protocol": "http", "port": "80" }], + "expected_match": null + }, + { + "pattern": [{ "protocol": "http{s}?", "port": "80" }], + "inputs": [{ "protocol": "http", "port": "80" }], + "expected_match": null + }, + { + "pattern": [{ "port": "80" }], + "inputs": [{ "port": "80" }], + "expected_match": { + "port": { "input": "80", "groups": {}} + } + }, + { + "pattern": [{ "port": "(.*)" }], + "inputs": [{ "port": "invalid80" }], + "expected_obj": { + "port": "*" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "/foo/./bar" }], + "expected_match": { + "pathname": { "input": "/foo/bar", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo/baz" }], + "inputs": [{ "pathname": "/foo/bar/../baz" }], + "expected_match": { + "pathname": { "input": "/foo/baz", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/caf%C3%A9" }], + "inputs": [{ "pathname": "/café" }], + "expected_match": { + "pathname": { "input": "/caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/café" }], + "inputs": [{ "pathname": "/café" }], + "expected_obj": { + "pathname": "/caf%C3%A9" + }, + "expected_match": { + "pathname": { "input": "/caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/caf%c3%a9" }], + "inputs": [{ "pathname": "/café" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "foo/bar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [{ "pathname": "foo/bar", "baseURL": "https://example.com" }], + "expected_match": { + "protocol": { "input": "https", "groups": { "0": "https" }}, + "hostname": { "input": "example.com", "groups": { "0": "example.com" }}, + "pathname": { "input": "/foo/bar", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo/../bar" }], + "inputs": [{ "pathname": "/bar" }], + "expected_obj": { + "pathname": "/bar" + }, + "expected_match": { + "pathname": { "input": "/bar", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "./foo/bar", "baseURL": "https://example.com" }], + "inputs": [{ "pathname": "foo/bar", "baseURL": "https://example.com" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {}}, + "hostname": { "input": "example.com", "groups": {}}, + "pathname": { "input": "/foo/bar", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "", "baseURL": "https://example.com" }], + "inputs": [{ "pathname": "/", "baseURL": "https://example.com" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {}}, + "hostname": { "input": "example.com", "groups": {}}, + "pathname": { "input": "/", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "{/bar}", "baseURL": "https://example.com/foo/" }], + "inputs": [{ "pathname": "./bar", "baseURL": "https://example.com/foo/" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/bar" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "\\/bar", "baseURL": "https://example.com/foo/" }], + "inputs": [{ "pathname": "./bar", "baseURL": "https://example.com/foo/" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/bar" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "b", "baseURL": "https://example.com/foo/" }], + "inputs": [{ "pathname": "./b", "baseURL": "https://example.com/foo/" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/foo/b" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {}}, + "hostname": { "input": "example.com", "groups": {}}, + "pathname": { "input": "/foo/b", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "foo/bar" }], + "inputs": [ "https://example.com/foo/bar" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "foo/bar", "baseURL": "https://example.com" }], + "inputs": [ "https://example.com/foo/bar" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/foo/bar" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {}}, + "hostname": { "input": "example.com", "groups": {}}, + "pathname": { "input": "/foo/bar", "groups": {}} + } + }, + { + "pattern": [{ "pathname": ":name.html", "baseURL": "https://example.com" }], + "inputs": [ "https://example.com/foo.html"] , + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/:name.html" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {}}, + "hostname": { "input": "example.com", "groups": {}}, + "pathname": { "input": "/foo.html", "groups": { "name": "foo" }} + } + }, + { + "pattern": [{ "search": "q=caf%C3%A9" }], + "inputs": [{ "search": "q=café" }], + "expected_match": { + "search": { "input": "q=caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "search": "q=café" }], + "inputs": [{ "search": "q=café" }], + "expected_obj": { + "search": "q=caf%C3%A9" + }, + "expected_match": { + "search": { "input": "q=caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "search": "q=caf%c3%a9" }], + "inputs": [{ "search": "q=café" }], + "expected_match": null + }, + { + "pattern": [{ "hash": "caf%C3%A9" }], + "inputs": [{ "hash": "café" }], + "expected_match": { + "hash": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "hash": "café" }], + "inputs": [{ "hash": "café" }], + "expected_obj": { + "hash": "caf%C3%A9" + }, + "expected_match": { + "hash": { "input": "caf%C3%A9", "groups": {}} + } + }, + { + "pattern": [{ "hash": "caf%c3%a9" }], + "inputs": [{ "hash": "café" }], + "expected_match": null + }, + { + "pattern": [{ "protocol": "about", "pathname": "(blank|sourcedoc)" }], + "inputs": [ "about:blank" ], + "expected_match": { + "protocol": { "input": "about", "groups": {}}, + "pathname": { "input": "blank", "groups": { "0": "blank" }} + } + }, + { + "pattern": [{ "protocol": "data", "pathname": ":number([0-9]+)" }], + "inputs": [ "data:8675309" ], + "expected_match": { + "protocol": { "input": "data", "groups": {}}, + "pathname": { "input": "8675309", "groups": { "number": "8675309" }} + } + }, + { + "pattern": [{ "pathname": "/(\\m)" }], + "expected_obj": "error" + }, + { + "pattern": [{ "pathname": "/foo!" }], + "inputs": [{ "pathname": "/foo!" }], + "expected_match": { + "pathname": { "input": "/foo!", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo\\:" }], + "inputs": [{ "pathname": "/foo:" }], + "expected_match": { + "pathname": { "input": "/foo:", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo\\{" }], + "inputs": [{ "pathname": "/foo{" }], + "expected_obj": { + "pathname": "/foo%7B" + }, + "expected_match": { + "pathname": { "input": "/foo%7B", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo\\(" }], + "inputs": [{ "pathname": "/foo(" }], + "expected_match": { + "pathname": { "input": "/foo(", "groups": {}} + } + }, + { + "pattern": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "inputs": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "expected_match": { + "protocol": { "input": "javascript", "groups": {}}, + "pathname": { "input": "var x = 1;", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "var x = 1;" }], + "inputs": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "expected_obj": { + "pathname": "var%20x%20=%201;" + }, + "expected_match": null + }, + { + "pattern": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "inputs": [{ "baseURL": "javascript:var x = 1;" }], + "expected_match": { + "protocol": { "input": "javascript", "groups": {}}, + "pathname": { "input": "var x = 1;", "groups": {}} + } + }, + { + "pattern": [{ "protocol": "(data|javascript)", "pathname": "var x = 1;" }], + "inputs": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "expected_match": { + "protocol": { "input": "javascript", "groups": {"0": "javascript"}}, + "pathname": { "input": "var x = 1;", "groups": {}} + } + }, + { + "pattern": [{ "protocol": "(https|javascript)", "pathname": "var x = 1;" }], + "inputs": [{ "protocol": "javascript", "pathname": "var x = 1;" }], + "expected_obj": { + "pathname": "var%20x%20=%201;" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "var x = 1;" }], + "inputs": [{ "pathname": "var x = 1;" }], + "expected_obj": { + "pathname": "var%20x%20=%201;" + }, + "expected_match": { + "pathname": { "input": "var%20x%20=%201;", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [ "./foo/bar", "https://example.com" ], + "expected_match": { + "hostname": { "input": "example.com", "groups": { "0": "example.com" } }, + "pathname": { "input": "/foo/bar", "groups": {} }, + "protocol": { "input": "https", "groups": { "0": "https" } } + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }], + "inputs": [ { "pathname": "/foo/bar" }, "https://example.com" ], + "expected_match": "error" + }, + { + "pattern": [ "https://example.com:8080/foo?bar#baz" ], + "inputs": [{ "pathname": "/foo", "search": "bar", "hash": "baz", + "baseURL": "https://example.com:8080" }], + "expected_obj": { + "protocol": "https", + "username": "*", + "password": "*", + "hostname": "example.com", + "port": "8080", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "search": { "input": "bar", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [ "/foo?bar#baz", "https://example.com:8080" ], + "inputs": [{ "pathname": "/foo", "search": "bar", "hash": "baz", + "baseURL": "https://example.com:8080" }], + "expected_obj": { + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "search": { "input": "bar", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [ "/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "example.com/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "http{s}?://{*.}?example.com/:product/:endpoint" ], + "inputs": [ "https://sub.example.com/foo/bar" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http{s}?", + "hostname": "{*.}?example.com", + "pathname": "/:product/:endpoint" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "sub.example.com", "groups": { "0": "sub" } }, + "pathname": { "input": "/foo/bar", "groups": { "product": "foo", + "endpoint": "bar" } } + } + }, + { + "pattern": [ "https://example.com?foo" ], + "inputs": [ "https://example.com/?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com#foo" ], + "inputs": [ "https://example.com/#foo" ], + "exactly_empty_components": [ "port", "search" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/", + "hash": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "hash": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com:8080?foo" ], + "inputs": [ "https://example.com:8080/?foo" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "port": "8080", + "pathname": "/", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com:8080#foo" ], + "inputs": [ "https://example.com:8080/#foo" ], + "exactly_empty_components": [ "search" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "port": "8080", + "pathname": "/", + "hash": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "hash": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/?foo" ], + "inputs": [ "https://example.com/?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/#foo" ], + "inputs": [ "https://example.com/#foo" ], + "exactly_empty_components": [ "port", "search" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/", + "hash": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "hash": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/*?foo" ], + "inputs": [ "https://example.com/?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/*?foo" + }, + "expected_match": null + }, + { + "pattern": [ "https://example.com/*\\?foo" ], + "inputs": [ "https://example.com/?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/*", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "" } }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/:name?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/:name?foo" + }, + "expected_match": null + }, + { + "pattern": [ "https://example.com/:name\\?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/:name", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/bar", "groups": { "name": "bar" } }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/(bar)?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/(bar)?foo" + }, + "expected_match": null + }, + { + "pattern": [ "https://example.com/(bar)\\?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/(bar)", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/bar", "groups": { "0": "bar" } }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/{bar}?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/{bar}?foo" + }, + "expected_match": null + }, + { + "pattern": [ "https://example.com/{bar}\\?foo" ], + "inputs": [ "https://example.com/bar?foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/bar", + "search": "foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/bar", "groups": {} }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "https://example.com/" ], + "inputs": [ "https://example.com:8080/" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "port": "", + "pathname": "/" + }, + "expected_match": null + }, + { + "pattern": [ "data:foobar" ], + "inputs": [ "data:foobar" ], + "expected_obj": "error" + }, + { + "pattern": [ "data\\:foobar" ], + "inputs": [ "data:foobar" ], + "exactly_empty_components": [ "hostname", "port" ], + "expected_obj": { + "protocol": "data", + "pathname": "foobar" + }, + "expected_match": { + "protocol": { "input": "data", "groups": {} }, + "pathname": { "input": "foobar", "groups": {} } + } + }, + { + "pattern": [ "https://{sub.}?example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "{sub.}?example.com", + "pathname": "/foo" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} } + } + }, + { + "pattern": [ "https://{sub.}?example{.com/}foo" ], + "inputs": [ "https://example.com/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "{https://}example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "https://(sub.)?example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "(sub.)?example.com", + "pathname": "/foo" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": { "0": null } }, + "pathname": { "input": "/foo", "groups": {} } + } + }, + { + "pattern": [ "https://(sub.)?example(.com/)foo" ], + "inputs": [ "https://example.com/foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "(sub.)?example(.com/)foo", + "pathname": "*" + }, + "expected_match": null + }, + { + "pattern": [ "(https://)example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "https://{sub{.}}example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "https://(sub(?:.))?example.com/foo" ], + "inputs": [ "https://example.com/foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "(sub(?:.))?example.com", + "pathname": "/foo" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": { "0": null } }, + "pathname": { "input": "/foo", "groups": {} } + } + }, + { + "pattern": [ "file:///foo/bar" ], + "inputs": [ "file:///foo/bar" ], + "exactly_empty_components": [ "hostname", "port" ], + "expected_obj": { + "protocol": "file", + "pathname": "/foo/bar" + }, + "expected_match": { + "protocol": { "input": "file", "groups": {} }, + "pathname": { "input": "/foo/bar", "groups": {} } + } + }, + { + "pattern": [ "data:" ], + "inputs": [ "data:" ], + "exactly_empty_components": [ "hostname", "port", "pathname" ], + "expected_obj": { + "protocol": "data" + }, + "expected_match": { + "protocol": { "input": "data", "groups": {} } + } + }, + { + "pattern": [ "foo://bar" ], + "inputs": [ "foo://bad_url_browser_interop" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "foo", + "hostname": "bar" + }, + "expected_match": null + }, + { + "pattern": [ "(café)://foo" ], + "expected_obj": "error" + }, + { + "pattern": [ "https://example.com/foo?bar#baz" ], + "inputs": [{ "protocol": "https:", + "search": "?bar", + "hash": "#baz", + "baseURL": "http://example.com/foo" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": null + }, + { + "pattern": [{ "protocol": "http{s}?:", + "search": "?bar", + "hash": "#baz" }], + "inputs": [ "http://example.com/foo?bar#baz" ], + "expected_obj": { + "protocol": "http{s}?", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "example.com", "groups": { "0": "example.com" }}, + "pathname": { "input": "/foo", "groups": { "0": "/foo" }}, + "search": { "input": "bar", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [ "?bar#baz", "https://example.com/foo" ], + "inputs": [ "?bar#baz", "https://example.com/foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "search": { "input": "bar", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [ "?bar", "https://example.com/foo#baz" ], + "inputs": [ "?bar", "https://example.com/foo#snafu" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/foo", + "search": "bar", + "hash": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "search": { "input": "bar", "groups": {} } + } + }, + { + "pattern": [ "#baz", "https://example.com/foo?bar" ], + "inputs": [ "#baz", "https://example.com/foo?bar" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "search": { "input": "bar", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [ "#baz", "https://example.com/foo" ], + "inputs": [ "#baz", "https://example.com/foo" ], + "exactly_empty_components": [ "port", "search" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/foo", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/foo", "groups": {} }, + "hash": { "input": "baz", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "*" }], + "inputs": [ "foo", "data:data-urls-cannot-be-base-urls" ], + "expected_match": null + }, + { + "pattern": [{ "pathname": "*" }], + "inputs": [ "foo", "not|a|valid|url" ], + "expected_match": null + }, + { + "pattern": [ "https://foo\\:bar@example.com" ], + "inputs": [ "https://foo:bar@example.com" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "username": "foo", + "password": "bar", + "hostname": "example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "username": { "input": "foo", "groups": {} }, + "password": { "input": "bar", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "/" } } + } + }, + { + "pattern": [ "https://foo@example.com" ], + "inputs": [ "https://foo@example.com" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "username": "foo", + "hostname": "example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "username": { "input": "foo", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "/" } } + } + }, + { + "pattern": [ "https://\\:bar@example.com" ], + "inputs": [ "https://:bar@example.com" ], + "exactly_empty_components": [ "username", "port" ], + "expected_obj": { + "protocol": "https", + "password": "bar", + "hostname": "example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "password": { "input": "bar", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "/" } } + } + }, + { + "pattern": [ "https://:user::pass@example.com" ], + "inputs": [ "https://foo:bar@example.com" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "username": ":user", + "password": ":pass", + "hostname": "example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "username": { "input": "foo", "groups": { "user": "foo" } }, + "password": { "input": "bar", "groups": { "pass": "bar" } }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "/" } } + } + }, + { + "pattern": [ "https\\:foo\\:bar@example.com" ], + "inputs": [ "https:foo:bar@example.com" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "username": "foo", + "password": "bar", + "hostname": "example.com", + "pathname": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "username": { "input": "foo", "groups": {} }, + "password": { "input": "bar", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": { "0": "/" } } + } + }, + { + "pattern": [ "data\\:foo\\:bar@example.com" ], + "inputs": [ "data:foo:bar@example.com" ], + "exactly_empty_components": [ "hostname", "port" ], + "expected_obj": { + "protocol": "data", + "pathname": "foo\\:bar@example.com" + }, + "expected_match": { + "protocol": { "input": "data", "groups": {} }, + "pathname": { "input": "foo:bar@example.com", "groups": {} } + } + }, + { + "pattern": [ "https://foo{\\:}bar@example.com" ], + "inputs": [ "https://foo:bar@example.com" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "username": "foo%3Abar", + "hostname": "example.com" + }, + "expected_match": null + }, + { + "pattern": [ "data{\\:}channel.html", "https://example.com" ], + "inputs": [ "https://example.com/data:channel.html" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "pathname": "/data\\:channel.html", + "search": "*", + "hash": "*" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/data:channel.html", "groups": {} } + } + }, + { + "pattern": [ "http://[\\:\\:1]/" ], + "inputs": [ "http://[::1]/" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http", + "hostname": "[\\:\\:1]", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "[::1]", "groups": {} }, + "pathname": { "input": "/", "groups": {} } + } + }, + { + "pattern": [ "http://[\\:\\:1]:8080/" ], + "inputs": [ "http://[::1]:8080/" ], + "expected_obj": { + "protocol": "http", + "hostname": "[\\:\\:1]", + "port": "8080", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "[::1]", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/", "groups": {} } + } + }, + { + "pattern": [ "http://[\\:\\:a]/" ], + "inputs": [ "http://[::a]/" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http", + "hostname": "[\\:\\:a]", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "[::a]", "groups": {} }, + "pathname": { "input": "/", "groups": {} } + } + }, + { + "pattern": [ "http://[:address]/" ], + "inputs": [ "http://[::1]/" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http", + "hostname": "[:address]", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "[::1]", "groups": { "address": "::1" }}, + "pathname": { "input": "/", "groups": {} } + } + }, + { + "pattern": [ "http://[\\:\\:AB\\::num]/" ], + "inputs": [ "http://[::ab:1]/" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "protocol": "http", + "hostname": "[\\:\\:ab\\::num]", + "pathname": "/" + }, + "expected_match": { + "protocol": { "input": "http", "groups": {} }, + "hostname": { "input": "[::ab:1]", "groups": { "num": "1" }}, + "pathname": { "input": "/", "groups": {} } + } + }, + { + "pattern": [{ "hostname": "[\\:\\:AB\\::num]" }], + "inputs": [{ "hostname": "[::ab:1]" }], + "expected_obj": { + "hostname": "[\\:\\:ab\\::num]" + }, + "expected_match": { + "hostname": { "input": "[::ab:1]", "groups": { "num": "1" }} + } + }, + { + "pattern": [{ "hostname": "[\\:\\:xY\\::num]" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "{[\\:\\:ab\\::num]}" }], + "inputs": [{ "hostname": "[::ab:1]" }], + "expected_match": { + "hostname": { "input": "[::ab:1]", "groups": { "num": "1" }} + } + }, + { + "pattern": [{ "hostname": "{[\\:\\:fé\\::num]}" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "{[\\:\\::num\\:1]}" }], + "inputs": [{ "hostname": "[::ab:1]" }], + "expected_match": { + "hostname": { "input": "[::ab:1]", "groups": { "num": "ab" }} + } + }, + { + "pattern": [{ "hostname": "{[\\:\\::num\\:fé]}" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "[*\\:1]" }], + "inputs": [{ "hostname": "[::ab:1]" }], + "expected_match": { + "hostname": { "input": "[::ab:1]", "groups": { "0": "::ab" }} + } + }, + { + "pattern": [{ "hostname": "*\\:1]" }], + "expected_obj": "error" + }, + { + "pattern": [ "https://foo{{@}}example.com" ], + "inputs": [ "https://foo@example.com" ], + "expected_obj": "error" + }, + { + "pattern": [ "https://foo{@example.com" ], + "inputs": [ "https://foo@example.com" ], + "expected_obj": "error" + }, + { + "pattern": [ "data\\:text/javascript,let x = 100/:tens?5;" ], + "inputs": [ "data:text/javascript,let x = 100/5;" ], + "exactly_empty_components": [ "hostname", "port" ], + "expected_obj": { + "protocol": "data", + "pathname": "text/javascript,let x = 100/:tens?5;" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "protocol": { "input": "data", "groups": {} }, + "pathname": { "input": "text/javascript,let x = 100/5;", "groups": { "tens": null } } + } + }, + { + "pattern": [{ "pathname": "/:id/:id" }], + "expected_obj": "error" + }, + { + "pattern": [{ "pathname": "/foo", "baseURL": "" }], + "expected_obj": "error" + }, + { + "pattern": [ "/foo", "" ], + "expected_obj": "error" + }, + { + "pattern": [{ "pathname": "/foo" }, "https://example.com" ], + "expected_obj": "error" + }, + { + "pattern": [{ "pathname": ":name*" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "pathname": ":name+" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "pathname": ":name" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "protocol": ":name*" }], + "inputs": [{ "protocol": "foobar" }], + "expected_match": { + "protocol": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "protocol": ":name+" }], + "inputs": [{ "protocol": "foobar" }], + "expected_match": { + "protocol": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "protocol": ":name" }], + "inputs": [{ "protocol": "foobar" }], + "expected_match": { + "protocol": { "input": "foobar", "groups": { "name": "foobar" }} + } + }, + { + "pattern": [{ "hostname": "bad hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad#hostname" }], + "inputs": [{ "hostname": "bad" }], + "expected_obj": { + "hostname": "bad" + }, + "expected_match": { + "hostname": { "input": "bad", "groups": {} } + } + }, + { + "pattern": [{ "hostname": "bad%hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad/hostname" }], + "inputs": [{ "hostname": "bad" }], + "expected_obj": { + "hostname": "bad" + }, + "expected_match": { + "hostname": { "input": "bad", "groups": {} } + } + }, + { + "pattern": [{ "hostname": "bad\\:hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "badhostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad?hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad@hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad[hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad]hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad\\\\hostname" }], + "inputs": [{ "hostname": "badhostname" }], + "expected_obj": { + "hostname": "bad" + }, + "expected_match": null + }, + { + "pattern": [{ "hostname": "bad^hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad|hostname" }], + "expected_obj": "error" + }, + { + "pattern": [{ "hostname": "bad\nhostname" }], + "inputs": [{ "hostname": "badhostname" }], + "expected_obj": { + "hostname": "badhostname" + }, + "expected_match": { + "hostname": { "input": "badhostname", "groups": {} } + } + }, + { + "pattern": [{ "hostname": "bad\rhostname" }], + "inputs": [{ "hostname": "badhostname" }], + "expected_obj": { + "hostname": "badhostname" + }, + "expected_match": { + "hostname": { "input": "badhostname", "groups": {} } + } + }, + { + "pattern": [{ "hostname": "bad\thostname" }], + "inputs": [{ "hostname": "badhostname" }], + "expected_obj": { + "hostname": "badhostname" + }, + "expected_match": { + "hostname": { "input": "badhostname", "groups": {} } + } + }, + { + "pattern": [{}], + "inputs": ["https://example.com/"], + "expected_match": { + "protocol": { "input": "https", "groups": { "0": "https" }}, + "hostname": { "input": "example.com", "groups": { "0": "example.com" }}, + "pathname": { "input": "/", "groups": { "0": "/" }} + } + }, + { + "pattern": [], + "inputs": ["https://example.com/"], + "expected_match": { + "protocol": { "input": "https", "groups": { "0": "https" }}, + "hostname": { "input": "example.com", "groups": { "0": "example.com" }}, + "pathname": { "input": "/", "groups": { "0": "/" }} + } + }, + { + "pattern": [], + "inputs": [{}], + "expected_match": {} + }, + { + "pattern": [], + "inputs": [], + "expected_match": { "inputs": [{}] } + }, + { + "pattern": [{ "pathname": "(foo)(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "0": "foo", "1": "barbaz" }} + } + }, + { + "pattern": [{ "pathname": "{(foo)bar}(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "0": "foo", "1": "baz" }} + } + }, + { + "pattern": [{ "pathname": "(foo)?(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": "(foo)?*" + }, + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "0": "foo", "1": "barbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "f", "0": "oobarbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}(barbaz)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "foo", "0": "barbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}{(.*)}" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": "{:foo}(.*)" + }, + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "f", "0": "oobarbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}{(.*)bar}" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": ":foo{*bar}" + }, + "expected_match": null + }, + { + "pattern": [{ "pathname": "{:foo}{bar(.*)}" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": ":foo{bar*}" + }, + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "foo", "0": "baz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}:bar(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": ":foo:bar(.*)" + }, + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "f", "bar": "oobarbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}?(.*)" }], + "inputs": [{ "pathname": "foobarbaz" }], + "expected_obj": { + "pathname": ":foo?*" + }, + "expected_match": { + "pathname": { "input": "foobarbaz", "groups": { "foo": "f", "0": "oobarbaz" }} + } + }, + { + "pattern": [{ "pathname": "{:foo\\bar}" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": "{:foo\\.bar}" }], + "inputs": [{ "pathname": "foo.bar" }], + "expected_obj": { + "pathname": "{:foo.bar}" + }, + "expected_match": { + "pathname": { "input": "foo.bar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": "{:foo(foo)bar}" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": "{:foo}bar" }], + "inputs": [{ "pathname": "foobar" }], + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": ":foo\\bar" }], + "inputs": [{ "pathname": "foobar" }], + "expected_obj": { + "pathname": "{:foo}bar" + }, + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": ":foo{}(.*)" }], + "inputs": [{ "pathname": "foobar" }], + "expected_obj": { + "pathname": "{:foo}(.*)" + }, + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "f", "0": "oobar" }} + } + }, + { + "pattern": [{ "pathname": ":foo{}bar" }], + "inputs": [{ "pathname": "foobar" }], + "expected_obj": { + "pathname": "{:foo}bar" + }, + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": ":foo{}?bar" }], + "inputs": [{ "pathname": "foobar" }], + "expected_obj": { + "pathname": "{:foo}bar" + }, + "expected_match": { + "pathname": { "input": "foobar", "groups": { "foo": "foo" }} + } + }, + { + "pattern": [{ "pathname": "*{}**?" }], + "inputs": [{ "pathname": "foobar" }], + "expected_obj": { + "pathname": "*(.*)?" + }, + "//": "The `null` below is translated to undefined in the test harness.", + "expected_match": { + "pathname": { "input": "foobar", "groups": { "0": "foobar", "1": null }} + } + }, + { + "pattern": [{ "pathname": ":foo(baz)(.*)" }], + "inputs": [{ "pathname": "bazbar" }], + "expected_match": { + "pathname": { "input": "bazbar", "groups": { "foo": "baz", "0": "bar" }} + } + }, + { + "pattern": [{ "pathname": ":foo(baz)bar" }], + "inputs": [{ "pathname": "bazbar" }], + "expected_match": { + "pathname": { "input": "bazbar", "groups": { "foo": "baz" }} + } + }, + { + "pattern": [{ "pathname": "*/*" }], + "inputs": [{ "pathname": "foo/bar" }], + "expected_match": { + "pathname": { "input": "foo/bar", "groups": { "0": "foo", "1": "bar" }} + } + }, + { + "pattern": [{ "pathname": "*\\/*" }], + "inputs": [{ "pathname": "foo/bar" }], + "expected_obj": { + "pathname": "*/{*}" + }, + "expected_match": { + "pathname": { "input": "foo/bar", "groups": { "0": "foo", "1": "bar" }} + } + }, + { + "pattern": [{ "pathname": "*/{*}" }], + "inputs": [{ "pathname": "foo/bar" }], + "expected_match": { + "pathname": { "input": "foo/bar", "groups": { "0": "foo", "1": "bar" }} + } + }, + { + "pattern": [{ "pathname": "*//*" }], + "inputs": [{ "pathname": "foo/bar" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/:foo." }], + "inputs": [{ "pathname": "/bar." }], + "expected_match": { + "pathname": { "input": "/bar.", "groups": { "foo": "bar" } } + } + }, + { + "pattern": [{ "pathname": "/:foo.." }], + "inputs": [{ "pathname": "/bar.." }], + "expected_match": { + "pathname": { "input": "/bar..", "groups": { "foo": "bar" } } + } + }, + { + "pattern": [{ "pathname": "./foo" }], + "inputs": [{ "pathname": "./foo" }], + "expected_match": { + "pathname": { "input": "./foo", "groups": {}} + } + }, + { + "pattern": [{ "pathname": "../foo" }], + "inputs": [{ "pathname": "../foo" }], + "expected_match": { + "pathname": { "input": "../foo", "groups": {}} + } + }, + { + "pattern": [{ "pathname": ":foo./" }], + "inputs": [{ "pathname": "bar./" }], + "expected_match": { + "pathname": { "input": "bar./", "groups": { "foo": "bar" }} + } + }, + { + "pattern": [{ "pathname": ":foo../" }], + "inputs": [{ "pathname": "bar../" }], + "expected_match": { + "pathname": { "input": "bar../", "groups": { "foo": "bar" }} + } + }, + { + "pattern": [{ "pathname": "/:foo\\bar" }], + "inputs": [{ "pathname": "/bazbar" }], + "expected_obj": { + "pathname": "{/:foo}bar" + }, + "expected_match": { + "pathname": { "input": "/bazbar", "groups": { "foo": "baz" }} + } + }, + { + "pattern": [{ "pathname": "/foo/bar" }, { "ignoreCase": true }], + "inputs": [{ "pathname": "/FOO/BAR" }], + "expected_match": { + "pathname": { "input": "/FOO/BAR", "groups": {} } + } + }, + { + "pattern": [{ "ignoreCase": true }], + "inputs": [{ "pathname": "/FOO/BAR" }], + "expected_match": { + "pathname": { "input": "/FOO/BAR", "groups": { "0": "/FOO/BAR" } } + } + }, + { + "pattern": [ "https://example.com:8080/foo?bar#baz", + { "ignoreCase": true }], + "inputs": [{ "pathname": "/FOO", "search": "BAR", "hash": "BAZ", + "baseURL": "https://example.com:8080" }], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "port": "8080", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/FOO", "groups": {} }, + "search": { "input": "BAR", "groups": {} }, + "hash": { "input": "BAZ", "groups": {} } + } + }, + { + "pattern": [ "/foo?bar#baz", "https://example.com:8080", + { "ignoreCase": true }], + "inputs": [{ "pathname": "/FOO", "search": "BAR", "hash": "BAZ", + "baseURL": "https://example.com:8080" }], + "expected_obj": { + "protocol": "https", + "hostname": "example.com", + "port": "8080", + "pathname": "/foo", + "search": "bar", + "hash": "baz" + }, + "expected_match": { + "protocol": { "input": "https", "groups": {} }, + "hostname": { "input": "example.com", "groups": {} }, + "port": { "input": "8080", "groups": {} }, + "pathname": { "input": "/FOO", "groups": {} }, + "search": { "input": "BAR", "groups": {} }, + "hash": { "input": "BAZ", "groups": {} } + } + }, + { + "pattern": [ "/foo?bar#baz", { "ignoreCase": true }, + "https://example.com:8080" ], + "inputs": [{ "pathname": "/FOO", "search": "BAR", "hash": "BAZ", + "baseURL": "https://example.com:8080" }], + "expected_obj": "error" + }, + { + "pattern": [{ "search": "foo", "baseURL": "https://example.com/a/+/b" }], + "inputs": [{ "search": "foo", "baseURL": "https://example.com/a/+/b" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "pathname": "/a/\\+/b" + }, + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/a/+/b", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [{ "hash": "foo", "baseURL": "https://example.com/?q=*&v=?&hmm={}&umm=()" }], + "inputs": [{ "hash": "foo", "baseURL": "https://example.com/?q=*&v=?&hmm={}&umm=()" }], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "search": "q=\\*&v=\\?&hmm=\\{\\}&umm=\\(\\)" + }, + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "q=*&v=?&hmm={}&umm=()", "groups": {} }, + "hash": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [ "#foo", "https://example.com/?q=*&v=?&hmm={}&umm=()" ], + "inputs": [ "https://example.com/?q=*&v=?&hmm={}&umm=()#foo" ], + "exactly_empty_components": [ "port" ], + "expected_obj": { + "search": "q=\\*&v=\\?&hmm=\\{\\}&umm=\\(\\)", + "hash": "foo" + }, + "expected_match": { + "hostname": { "input": "example.com", "groups": {} }, + "pathname": { "input": "/", "groups": {} }, + "protocol": { "input": "https", "groups": {} }, + "search": { "input": "q=*&v=?&hmm={}&umm=()", "groups": {} }, + "hash": { "input": "foo", "groups": {} } + } + }, + { + "pattern": [{ "pathname": "/([[a-z]--a])" }], + "inputs": [{ "pathname": "/a" }], + "expected_match": null + }, + { + "pattern": [{ "pathname": "/([[a-z]--a])" }], + "inputs": [{ "pathname": "/z" }], + "expected_match": { + "pathname": { "input": "/z", "groups": { "0": "z" } } + } + }, + { + "pattern": [{ "pathname": "/([\\d&&[0-1]])" }], + "inputs": [{ "pathname": "/0" }], + "expected_match": { + "pathname": { "input": "/0", "groups": { "0": "0" } } + } + }, + { + "pattern": [{ "pathname": "/([\\d&&[0-1]])" }], + "inputs": [{ "pathname": "/3" }], + "expected_match": null + } +] diff --git a/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntests.js b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntests.js new file mode 100644 index 00000000000..761f96b6fd3 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/urlpattern/resources/urlpatterntests.js @@ -0,0 +1,188 @@ +const kComponents = [ + 'protocol', + 'username', + 'password', + 'hostname', + 'port', + 'password', + 'pathname', + 'search', + 'hash', +]; + +function runTests(data) { + for (let entry of data) { + test(function() { + if (entry.expected_obj === 'error') { + assert_throws_js(TypeError, _ => new URLPattern(...entry.pattern), + 'URLPattern() constructor'); + return; + } + + const pattern = new URLPattern(...entry.pattern); + + // If the expected_obj property is not present we will automatically + // fill it with the most likely expected values. + entry.expected_obj = entry.expected_obj || {}; + + // The compiled URLPattern object should have a property for each + // component exposing the compiled pattern string. + for (let component of kComponents) { + // If the test case explicitly provides an expected pattern string, + // then use that. This is necessary in cases where the original + // construction pattern gets canonicalized, etc. + let expected = entry.expected_obj[component]; + + // If there is no explicit expected pattern string, then compute + // the expected value based on the URLPattern constructor args. + if (expected == undefined) { + // First determine if there is a baseURL present in the pattern + // input. A baseURL can be the source for many component patterns. + let baseURL = null; + if (entry.pattern.length > 0 && entry.pattern[0].baseURL) { + baseURL = new URL(entry.pattern[0].baseURL); + } else if (entry.pattern.length > 1 && + typeof entry.pattern[1] === 'string') { + baseURL = new URL(entry.pattern[1]); + } + + const EARLIER_COMPONENTS = { + protocol: [], + hostname: ["protocol"], + port: ["protocol", "hostname"], + username: [], + password: [], + pathname: ["protocol", "hostname", "port"], + search: ["protocol", "hostname", "port", "pathname"], + hash: ["protocol", "hostname", "port", "pathname", "search"], + }; + + // We automatically populate the expected pattern string using + // the following options in priority order: + // + // 1. If the original input explicitly provided a pattern, then + // echo that back as the expected value. + // 2. If an "earlier" component is specified, then a wildcard + // will be used rather than inheriting from the base URL. + // 3. If the baseURL exists and provides a component value then + // use that for the expected pattern. + // 4. Otherwise fall back on the default pattern of `*` for an + // empty component pattern. + // + // Note that username and password are never inherited, and will only + // need to match if explicitly specified. + if (entry.exactly_empty_components && + entry.exactly_empty_components.includes(component)) { + expected = ''; + } else if (typeof entry.pattern[0] === 'object' && + entry.pattern[0][component]) { + expected = entry.pattern[0][component]; + } else if (typeof entry.pattern[0] === 'object' && + EARLIER_COMPONENTS[component].some(c => c in entry.pattern[0])) { + expected = '*'; + } else if (baseURL && component !== 'username' && component !== 'password') { + let base_value = baseURL[component]; + // Unfortunately some URL() getters include separator chars; e.g. + // the trailing `:` for the protocol. Strip those off if necessary. + if (component === 'protocol') + base_value = base_value.substring(0, base_value.length - 1); + else if (component === 'search' || component === 'hash') + base_value = base_value.substring(1, base_value.length); + expected = base_value; + } else { + expected = '*'; + } + } + + // Finally, assert that the compiled object property matches the + // expected property. + assert_equals(pattern[component], expected, + `compiled pattern property '${component}'`); + } + + if (entry.expected_match === 'error') { + assert_throws_js(TypeError, _ => pattern.test(...entry.inputs), + 'test() result'); + assert_throws_js(TypeError, _ => pattern.exec(...entry.inputs), + 'exec() result'); + return; + } + + // First, validate the test() method by converting the expected result to + // a truthy value. + assert_equals(pattern.test(...entry.inputs), !!entry.expected_match, + 'test() result'); + + // Next, start validating the exec() method. + const exec_result = pattern.exec(...entry.inputs); + + // On a failed match exec() returns null. + if (!entry.expected_match || typeof entry.expected_match !== "object") { + assert_equals(exec_result, entry.expected_match, 'exec() failed match result'); + return; + } + + if (!entry.expected_match.inputs) + entry.expected_match.inputs = entry.inputs; + + // Next verify the result.input is correct. This may be a structured + // URLPatternInit dictionary object or a URL string. + assert_equals(exec_result.inputs.length, + entry.expected_match.inputs.length, + 'exec() result.inputs.length'); + for (let i = 0; i < exec_result.inputs.length; ++i) { + const input = exec_result.inputs[i]; + const expected_input = entry.expected_match.inputs[i]; + if (typeof input === 'string') { + assert_equals(input, expected_input, `exec() result.inputs[${i}]`); + continue; + } + for (let component of kComponents) { + assert_equals(input[component], expected_input[component], + `exec() result.inputs[${i}][${component}]`); + } + } + + // Next we will compare the URLPatternComponentResult for each of these + // expected components. + for (let component of kComponents) { + let expected_obj = entry.expected_match[component]; + + // If the test expectations don't include a component object, then + // we auto-generate one. This is convenient for the many cases + // where the pattern has a default wildcard or empty string pattern + // for a component and the input is essentially empty. + if (!expected_obj) { + expected_obj = { input: '', groups: {} }; + + // Next, we must treat default wildcards differently than empty string + // patterns. The wildcard results in a capture group, but the empty + // string pattern does not. The expectation object must list which + // components should be empty instead of wildcards in + // |exactly_empty_components|. + if (!entry.exactly_empty_components || + !entry.exactly_empty_components.includes(component)) { + expected_obj.groups['0'] = ''; + } + } + // JSON does not allow us to use undefined directly, so the data file + // contains null instead. Translate to the expected undefined value + // here. + for (const key in expected_obj.groups) { + if (expected_obj.groups[key] === null) { + expected_obj.groups[key] = undefined; + } + } + assert_object_equals(exec_result[component], expected_obj, + `exec() result for ${component}`); + } + }, `Pattern: ${JSON.stringify(entry.pattern)} ` + + `Inputs: ${JSON.stringify(entry.inputs)}`); + } +} + +promise_test(async function() { + const response = await fetch('resources/urlpatterntestdata.json'); + const data = await response.json(); + runTests(data); +}, 'Loading data...'); diff --git a/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.html b/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.html new file mode 100644 index 00000000000..508ead19d50 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.html @@ -0,0 +1,15 @@ + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.js b/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.js new file mode 100644 index 00000000000..7d47d22609b --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/urlpattern/urlpattern.any.js @@ -0,0 +1,2 @@ +// META: global=window,worker +// META: script=resources/urlpatterntests.js