From f64d5451dff75d6d6af78a8cd4a77d139cef3c58 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sun, 23 Mar 2025 20:35:39 +1300 Subject: [PATCH] LibWeb/Bindings: Do put OptionalNone as member in returned dictionaries Our handling of 'optional' return values was previously not correct in that we would always call 'create_data_property' for every single member of the returned dictionary, even if that property did not have a value (by falling back to JS::js_null). This was resulting in a massive number of test failures for URL pattern which was expecting 'undefined' as the member value, instead of 'null'. --- .../BindingsGenerator/IDLGenerators.cpp | 28 +- .../wpt-import/urlpattern/urlpattern.any.txt | 340 +++++++++--------- 2 files changed, 193 insertions(+), 175 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 2ac197f40dc..f12a2977671 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -2018,9 +2018,6 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const auto wrapped_value_name = ByteString::formatted("wrapped_{}", member_value_js_name); dictionary_generator.set("wrapped_value_name", wrapped_value_name); - dictionary_generator.append(R"~~~( - JS::Value @wrapped_value_name@; -)~~~"); // NOTE: This has similar semantics as 'required' in WebIDL. However, the spec does not put 'required' on // _returned_ dictionary members since with the way the spec is worded it has no normative effect to // do so. We could implement this without the 'GenerateAsRequired' extended attribute, but it would require @@ -2028,11 +2025,27 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const // determine whether the type is present or not (e.g through a has_value() on an Optional, or a null // check on a GC::Ptr). So to save some complexity in the generator, give ourselves a hint of what to do. bool is_optional = !member.extended_attributes.contains("GenerateAsRequired") && !member.default_value.has_value(); + if (is_optional) { + dictionary_generator.append(R"~~~( + Optional @wrapped_value_name@; +)~~~"); + } else { + dictionary_generator.append(R"~~~( + JS::Value @wrapped_value_name@; +)~~~"); + } generate_wrap_statement(dictionary_generator, ByteString::formatted("{}{}{}", value, type.is_nullable() ? "->" : ".", member.name.to_snakecase()), member.type, interface, ByteString::formatted("{} =", wrapped_value_name), WrappingReference::No, recursion_depth + 1, is_optional); - dictionary_generator.append(R"~~~( + if (is_optional) { + dictionary_generator.append(R"~~~( + if (@wrapped_value_name@.has_value()) + MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_fly_string, @wrapped_value_name@.release_value())); +)~~~"); + } else { + dictionary_generator.append(R"~~~( MUST(dictionary_object@recursion_depth@->create_data_property("@member_key@"_fly_string, @wrapped_value_name@)); )~~~"); + } } if (current_dictionary->parent_name.is_empty()) @@ -2061,11 +2074,16 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const } } - if ((type.is_nullable() || is_optional) && !is(type)) { + if (type.is_nullable() && !is(type)) { scoped_generator.append(R"~~~( } else { @result_expression@ JS::js_null(); } +)~~~"); + } else if (is_optional) { + // Optional return values should not be assigned any value (including null) if the value is not present. + scoped_generator.append(R"~~~( + } )~~~"); } } diff --git a/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt index 827f42129f8..0aa4e5e7cd7 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/urlpattern/urlpattern.any.txt @@ -2,123 +2,123 @@ Harness status: OK Found 350 tests -172 Pass -178 Fail +340 Pass +10 Fail Pass Loading data... -Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/ba"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/baz"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: ["https://example.com/foo/bar"] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: ["https://example.com/foo/bar/baz"] -Fail Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"hostname":"example.com","pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"hostname":"example.com","pathname":"/foo/bar"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/bar/baz","baseURL":"https://example.com"}] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?otherquery#otherhash"}] Inputs: [{"protocol":"https","hostname":"example.com","pathname":"/foo/bar","search":"otherquery","hash":"otherhash"}] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar"] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar?otherquery#otherhash"] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar?query#hash"] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://example.com/foo/bar/baz"] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: ["https://other.com/foo/bar"] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com"}] +Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar/baz","baseURL":"https://example.com"}] Pass Pattern: [{"pathname":"/foo/bar","baseURL":"https://example.com?query#hash"}] Inputs: [{"pathname":"/foo/bar","baseURL":"https://other.com"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/([^\\/]+?)"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/index.html"}] Pass Pattern: [{"pathname":"/foo/:bar"}] Inputs: [{"pathname":"/foo/bar/"}] Pass 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/"}] +Pass Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo/"}] +Pass Pattern: [{"pathname":"/foo/*"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/(.*)"}] Inputs: [{"pathname":"/foo"}] Pass 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/"}] +Pass Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/:bar(.*)"}] Inputs: [{"pathname":"/foo"}] -Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/bar"}] -Fail Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/:bar?"}] Inputs: [{"pathname":"/foobar"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/bar/baz"}] Pass Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo/:bar+"}] Inputs: [{"pathname":"/foo/"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo/:bar*"}] Inputs: [{"pathname":"/foo/"}] Pass 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/"}] +Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foo/"}] +Pass Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/*?"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/(.*)?"}] Inputs: [{"pathname":"/fo"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/bar/baz"}] Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo"}] -Fail Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/"}] -Fail Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/"}] +Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foo/"}] +Pass Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/*+"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/(.*)+"}] Inputs: [{"pathname":"/fo"}] Pass 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/"}] +Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/bar/baz"}] +Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foo/"}] +Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/foobar"}] Pass Pattern: [{"pathname":"/foo/(.*)*"}] Inputs: [{"pathname":"/fo"}] Pass Pattern: [{"pathname":"/foo/**"}] Inputs: [{"pathname":"/fo"}] -Fail Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/bar"}] Pass Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/bar/baz"}] Pass Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo{/bar}"}] Inputs: [{"pathname":"/foo/"}] -Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/bar"}] Pass Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo/bar/baz"}] -Fail Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo{/bar}?"}] Inputs: [{"pathname":"/foo"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar/bar"}] Pass Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo/bar/baz"}] Pass Pattern: [{"pathname":"/foo{/bar}+"}] Inputs: [{"pathname":"/foo"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar"}] +Pass Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar/bar"}] Pass Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/bar/baz"}] -Fail Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo"}] Pass Pattern: [{"pathname":"/foo{/bar}*"}] Inputs: [{"pathname":"/foo/"}] Pass Pattern: [{"protocol":"(café)"}] Inputs: undefined Pass Pattern: [{"username":"(café)"}] Inputs: undefined @@ -127,35 +127,35 @@ Pass Pattern: [{"hostname":"(café)"}] Inputs: undefined Pass Pattern: [{"pathname":"(café)"}] Inputs: undefined Pass Pattern: [{"search":"(café)"}] Inputs: undefined Pass 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"}] +Pass Pattern: [{"protocol":":café"}] Inputs: [{"protocol":"foo"}] +Pass Pattern: [{"username":":café"}] Inputs: [{"username":"foo"}] +Pass Pattern: [{"password":":café"}] Inputs: [{"password":"foo"}] +Pass Pattern: [{"hostname":":café"}] Inputs: [{"hostname":"foo"}] +Pass Pattern: [{"pathname":"/:café"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"search":":café"}] Inputs: [{"search":"foo"}] +Pass Pattern: [{"hash":":café"}] Inputs: [{"hash":"foo"}] +Pass Pattern: [{"protocol":":℘"}] Inputs: [{"protocol":"foo"}] +Pass Pattern: [{"username":":℘"}] Inputs: [{"username":"foo"}] +Pass Pattern: [{"password":":℘"}] Inputs: [{"password":"foo"}] +Pass Pattern: [{"hostname":":℘"}] Inputs: [{"hostname":"foo"}] +Pass Pattern: [{"pathname":"/:℘"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"search":":℘"}] Inputs: [{"search":"foo"}] +Pass Pattern: [{"hash":":℘"}] Inputs: [{"hash":"foo"}] +Pass Pattern: [{"protocol":":㐀"}] Inputs: [{"protocol":"foo"}] +Pass Pattern: [{"username":":㐀"}] Inputs: [{"username":"foo"}] +Pass Pattern: [{"password":":㐀"}] Inputs: [{"password":"foo"}] +Pass Pattern: [{"hostname":":㐀"}] Inputs: [{"hostname":"foo"}] +Pass Pattern: [{"pathname":"/:㐀"}] Inputs: [{"pathname":"/foo"}] +Pass Pattern: [{"search":":㐀"}] Inputs: [{"search":"foo"}] +Pass Pattern: [{"hash":":㐀"}] Inputs: [{"hash":"foo"}] Pass 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é"}] +Pass Pattern: [{"protocol":"(.*)"}] Inputs: [{"protocol":"cafe"}] +Pass Pattern: [{"protocol":"foo-bar"}] Inputs: [{"protocol":"foo-bar"}] +Pass Pattern: [{"username":"caf%C3%A9"}] Inputs: [{"username":"café"}] +Pass Pattern: [{"username":"café"}] Inputs: [{"username":"café"}] Pass Pattern: [{"username":"caf%c3%a9"}] Inputs: [{"username":"café"}] -Fail Pattern: [{"password":"caf%C3%A9"}] Inputs: [{"password":"café"}] -Fail Pattern: [{"password":"café"}] Inputs: [{"password":"café"}] +Pass Pattern: [{"password":"caf%C3%A9"}] Inputs: [{"password":"café"}] +Pass Pattern: [{"password":"café"}] Inputs: [{"password":"café"}] Pass 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"}] @@ -165,56 +165,56 @@ Pass Pattern: [{"hostname":"\ud83d \udeb2"}] Inputs: undefined Pass Pattern: [{"pathname":"\ud83d \udeb2"}] Inputs: [] Pass Pattern: [{"pathname":":\ud83d \udeb2"}] Inputs: undefined Pass Pattern: [{"pathname":":aU+dd00b"}] Inputs: [] -Fail Pattern: [{"pathname":"test/:aU+dc50b"}] Inputs: [{"pathname":"test/foo"}] +Pass Pattern: [{"pathname":"test/:aU+dc50b"}] Inputs: [{"pathname":"test/foo"}] Pass 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"}] +Pass Pattern: [{"port":""}] Inputs: [{"protocol":"http","port":"80"}] +Pass Pattern: [{"protocol":"http","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http","port":"80{20}?"}] Inputs: [{"protocol":"http","port":"80"}] -Fail Pattern: [{"protocol":"http","port":"80 "}] Inputs: [{"protocol":"http","port":"80"}] +Pass Pattern: [{"protocol":"http","port":"80 "}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http","port":"100000"}] Inputs: [{"protocol":"http","port":"100000"}] Pass Pattern: [{"port":"80"}] Inputs: [{"protocol":"http","port":"80"}] Pass Pattern: [{"protocol":"http{s}?","port":"80"}] Inputs: [{"protocol":"http","port":"80"}] -Fail Pattern: [{"port":"80"}] Inputs: [{"port":"80"}] +Pass 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é"}] +Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"/foo/./bar"}] +Pass Pattern: [{"pathname":"/foo/baz"}] Inputs: [{"pathname":"/foo/bar/../baz"}] +Pass Pattern: [{"pathname":"/caf%C3%A9"}] Inputs: [{"pathname":"/café"}] +Pass Pattern: [{"pathname":"/café"}] Inputs: [{"pathname":"/café"}] Pass Pattern: [{"pathname":"/caf%c3%a9"}] Inputs: [{"pathname":"/café"}] Pass 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"}] +Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: [{"pathname":"foo/bar","baseURL":"https://example.com"}] +Pass Pattern: [{"pathname":"/foo/../bar"}] Inputs: [{"pathname":"/bar"}] +Pass Pattern: [{"pathname":"./foo/bar","baseURL":"https://example.com"}] Inputs: [{"pathname":"foo/bar","baseURL":"https://example.com"}] +Pass Pattern: [{"pathname":"","baseURL":"https://example.com"}] Inputs: [{"pathname":"/","baseURL":"https://example.com"}] Pass Pattern: [{"pathname":"{/bar}","baseURL":"https://example.com/foo/"}] Inputs: [{"pathname":"./bar","baseURL":"https://example.com/foo/"}] Pass 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/"}] +Pass Pattern: [{"pathname":"b","baseURL":"https://example.com/foo/"}] Inputs: [{"pathname":"./b","baseURL":"https://example.com/foo/"}] Pass Pattern: [{"pathname":"foo/bar"}] Inputs: ["https://example.com/foo/bar"] Pass Pattern: [{"pathname":"foo/bar","baseURL":"https://example.com"}] Inputs: ["https://example.com/foo/bar"] Pass 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é"}] +Pass Pattern: [{"search":"q=caf%C3%A9"}] Inputs: [{"search":"q=café"}] +Pass Pattern: [{"search":"q=café"}] Inputs: [{"search":"q=café"}] Pass 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é"}] +Pass Pattern: [{"hash":"caf%C3%A9"}] Inputs: [{"hash":"café"}] +Pass Pattern: [{"hash":"café"}] Inputs: [{"hash":"café"}] Pass Pattern: [{"hash":"caf%c3%a9"}] Inputs: [{"hash":"café"}] Pass Pattern: [{"protocol":"about","pathname":"(blank|sourcedoc)"}] Inputs: ["about:blank"] Pass Pattern: [{"protocol":"data","pathname":":number([0-9]+)"}] Inputs: ["data:8675309"] Pass 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;"}] +Pass Pattern: [{"pathname":"/foo!"}] Inputs: [{"pathname":"/foo!"}] +Pass Pattern: [{"pathname":"/foo\\:"}] Inputs: [{"pathname":"/foo:"}] +Pass Pattern: [{"pathname":"/foo\\{"}] Inputs: [{"pathname":"/foo{"}] +Pass Pattern: [{"pathname":"/foo\\("}] Inputs: [{"pathname":"/foo("}] +Pass Pattern: [{"protocol":"javascript","pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] Pass 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;"}] +Pass Pattern: [{"protocol":"javascript","pathname":"var x = 1;"}] Inputs: [{"baseURL":"javascript:var x = 1;"}] +Pass Pattern: [{"protocol":"(data|javascript)","pathname":"var x = 1;"}] Inputs: [{"protocol":"javascript","pathname":"var x = 1;"}] Pass 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;"}] +Pass Pattern: [{"pathname":"var x = 1;"}] Inputs: [{"pathname":"var x = 1;"}] Pass Pattern: [{"pathname":"/foo/bar"}] Inputs: ["./foo/bar","https://example.com"] Pass 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: ["https://example.com:8080/foo?bar#baz"] Inputs: [{"pathname":"/foo","search":"bar","hash":"baz","baseURL":"https://example.com:8080"}] +Pass 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 Pass Pattern: ["http{s}?://{*.}?example.com/:product/:endpoint"] Inputs: ["https://sub.example.com/foo/bar"] @@ -268,13 +268,13 @@ Pass Pattern: ["http://[\\:\\:1]:8080/"] Inputs: ["http://[::1]:8080/"] Pass Pattern: ["http://[\\:\\:a]/"] Inputs: ["http://[::a]/"] Pass Pattern: ["http://[:address]/"] Inputs: ["http://[::1]/"] Pass Pattern: ["http://[\\:\\:AB\\::num]/"] Inputs: ["http://[::ab:1]/"] -Fail Pattern: [{"hostname":"[\\:\\:AB\\::num]"}] Inputs: [{"hostname":"[::ab:1]"}] +Pass Pattern: [{"hostname":"[\\:\\:AB\\::num]"}] Inputs: [{"hostname":"[::ab:1]"}] Pass Pattern: [{"hostname":"[\\:\\:xY\\::num]"}] Inputs: undefined -Fail Pattern: [{"hostname":"{[\\:\\:ab\\::num]}"}] Inputs: [{"hostname":"[::ab:1]"}] +Pass Pattern: [{"hostname":"{[\\:\\:ab\\::num]}"}] Inputs: [{"hostname":"[::ab:1]"}] Pass Pattern: [{"hostname":"{[\\:\\:fé\\::num]}"}] Inputs: undefined -Fail Pattern: [{"hostname":"{[\\:\\::num\\:1]}"}] Inputs: [{"hostname":"[::ab:1]"}] +Pass Pattern: [{"hostname":"{[\\:\\::num\\:1]}"}] Inputs: [{"hostname":"[::ab:1]"}] Pass Pattern: [{"hostname":"{[\\:\\::num\\:fé]}"}] Inputs: undefined -Fail Pattern: [{"hostname":"[*\\:1]"}] Inputs: [{"hostname":"[::ab:1]"}] +Pass Pattern: [{"hostname":"[*\\:1]"}] Inputs: [{"hostname":"[::ab:1]"}] Pass Pattern: [{"hostname":"*\\:1]"}] Inputs: undefined Pass Pattern: ["https://foo{{@}}example.com"] Inputs: ["https://foo@example.com"] Pass Pattern: ["https://foo{@example.com"] Inputs: ["https://foo@example.com"] @@ -283,16 +283,16 @@ Pass Pattern: [{"pathname":"/:id/:id"}] Inputs: undefined Pass Pattern: [{"pathname":"/foo","baseURL":""}] Inputs: undefined Pass 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"}] +Pass Pattern: [{"pathname":":name*"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":":name+"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":":name"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"protocol":":name*"}] Inputs: [{"protocol":"foobar"}] +Pass Pattern: [{"protocol":":name+"}] Inputs: [{"protocol":"foobar"}] +Pass Pattern: [{"protocol":":name"}] Inputs: [{"protocol":"foobar"}] Pass Pattern: [{"hostname":"bad hostname"}] Inputs: undefined -Fail Pattern: [{"hostname":"bad#hostname"}] Inputs: [{"hostname":"bad"}] +Pass Pattern: [{"hostname":"bad#hostname"}] Inputs: [{"hostname":"bad"}] Fail Pattern: [{"hostname":"bad%hostname"}] Inputs: undefined -Fail Pattern: [{"hostname":"bad/hostname"}] Inputs: [{"hostname":"bad"}] +Pass Pattern: [{"hostname":"bad/hostname"}] Inputs: [{"hostname":"bad"}] Fail Pattern: [{"hostname":"bad\\:hostname"}] Inputs: undefined Pass Pattern: [{"hostname":"badhostname"}] Inputs: undefined @@ -303,54 +303,54 @@ Pass Pattern: [{"hostname":"bad]hostname"}] Inputs: undefined Fail Pattern: [{"hostname":"bad\\\\hostname"}] Inputs: [{"hostname":"badhostname"}] Pass Pattern: [{"hostname":"bad^hostname"}] Inputs: undefined Pass 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"}] +Pass Pattern: [{"hostname":"bad\nhostname"}] Inputs: [{"hostname":"badhostname"}] +Pass Pattern: [{"hostname":"bad\rhostname"}] Inputs: [{"hostname":"badhostname"}] +Pass Pattern: [{"hostname":"bad\thostname"}] Inputs: [{"hostname":"badhostname"}] Pass Pattern: [{}] Inputs: ["https://example.com/"] Pass 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"}] +Pass Pattern: [] Inputs: [{}] +Pass Pattern: [] Inputs: [] +Pass Pattern: [{"pathname":"(foo)(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{(foo)bar}(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"(foo)?(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo}(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo}(barbaz)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo}{(.*)}"}] Inputs: [{"pathname":"foobarbaz"}] Pass 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"}] +Pass Pattern: [{"pathname":"{:foo}{bar(.*)}"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo}:bar(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo}?(.*)"}] Inputs: [{"pathname":"foobarbaz"}] +Pass Pattern: [{"pathname":"{:foo\\bar}"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":"{:foo\\.bar}"}] Inputs: [{"pathname":"foo.bar"}] +Pass Pattern: [{"pathname":"{:foo(foo)bar}"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":"{:foo}bar"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":":foo\\bar"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":":foo{}(.*)"}] Inputs: [{"pathname":"foobar"}] +Pass Pattern: [{"pathname":":foo{}bar"}] Inputs: [{"pathname":"foobar"}] +Pass 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"}] +Pass Pattern: [{"pathname":":foo(baz)(.*)"}] Inputs: [{"pathname":"bazbar"}] +Pass Pattern: [{"pathname":":foo(baz)bar"}] Inputs: [{"pathname":"bazbar"}] +Pass Pattern: [{"pathname":"*/*"}] Inputs: [{"pathname":"foo/bar"}] +Pass Pattern: [{"pathname":"*\\/*"}] Inputs: [{"pathname":"foo/bar"}] +Pass Pattern: [{"pathname":"*/{*}"}] Inputs: [{"pathname":"foo/bar"}] Pass 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: [{"pathname":"/:foo."}] Inputs: [{"pathname":"/bar."}] +Pass Pattern: [{"pathname":"/:foo.."}] Inputs: [{"pathname":"/bar.."}] +Pass Pattern: [{"pathname":"./foo"}] Inputs: [{"pathname":"./foo"}] +Pass Pattern: [{"pathname":"../foo"}] Inputs: [{"pathname":"../foo"}] +Pass Pattern: [{"pathname":":foo./"}] Inputs: [{"pathname":"bar./"}] +Pass Pattern: [{"pathname":":foo../"}] Inputs: [{"pathname":"bar../"}] +Pass Pattern: [{"pathname":"/:foo\\bar"}] Inputs: [{"pathname":"/bazbar"}] +Pass Pattern: [{"pathname":"/foo/bar"},{"ignoreCase":true}] Inputs: [{"pathname":"/FOO/BAR"}] +Pass Pattern: [{"ignoreCase":true}] Inputs: [{"pathname":"/FOO/BAR"}] +Pass Pattern: ["https://example.com:8080/foo?bar#baz",{"ignoreCase":true}] Inputs: [{"pathname":"/FOO","search":"BAR","hash":"BAZ","baseURL":"https://example.com:8080"}] +Pass 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=()"}] +Pass Pattern: [{"search":"foo","baseURL":"https://example.com/a/+/b"}] Inputs: [{"search":"foo","baseURL":"https://example.com/a/+/b"}] +Pass Pattern: [{"hash":"foo","baseURL":"https://example.com/?q=*&v=?&hmm={}&umm=()"}] Inputs: [{"hash":"foo","baseURL":"https://example.com/?q=*&v=?&hmm={}&umm=()"}] Pass Pattern: ["#foo","https://example.com/?q=*&v=?&hmm={}&umm=()"] Inputs: ["https://example.com/?q=*&v=?&hmm={}&umm=()#foo"] Pass 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"}] +Pass Pattern: [{"pathname":"/([[a-z]--a])"}] Inputs: [{"pathname":"/z"}] +Pass Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/0"}] Pass Pattern: [{"pathname":"/([\\d&&[0-1]])"}] Inputs: [{"pathname":"/3"}] \ No newline at end of file