Bug 1700421 [wpt PR 28192] - URLPattern: Allow a second argument to test()/exec(...
[gecko.git] / testing / web-platform / tests / urlpattern / urlpattern.https.any.js
blobf56223bf648e7fdd50ca030db02e6f56b3179071
1 // META: global=window,worker
3 const kComponents = [
4   'protocol',
5   'username',
6   'password',
7   'hostname',
8   'password',
9   'pathname',
10   'search',
11   'hash',
14 function runTests(data) {
15   for (let entry of data) {
16     test(function() {
17       if (entry.error) {
18         assert_throws_js(TypeError, _ => new URLPattern(entry.pattern),
19                          'URLPattern() constructor');
20         return;
21       }
23       const pattern = new URLPattern(entry.pattern);
25       // If the expected_obj property is not present we will automatically
26       // fill it with the most likely expected values.
27       entry.expected_obj = entry.expected_obj || {};
29       // The compiled URLPattern object should have a property for each
30       // component exposing the compiled pattern string.
31       for (let component of kComponents) {
32         // If the test case explicitly provides an expected pattern string,
33         // then use that.  This is necessary in cases where the original
34         // construction pattern gets canonicalized, etc.
35         let expected = entry.expected_obj[component];
37         // If there is no explicit expected pattern string, then compute
38         // the expected value based on the URLPattern constructor args.
39         if (!expected) {
40           // First determine if there is a baseURL present in the pattern
41           // input.  A baseURL can be the source for many component patterns.
42           let baseURL = null;
43           if (entry.pattern.baseURL)
44             baseURL = new URL(entry.pattern.baseURL);
46           // We automatically populate the expected pattern string using
47           // the following options in priority order:
48           //
49           //  1. If the original input explicitly provided a pattern, then
50           //     echo that back as the expected value.
51           //  2. If the baseURL exists and provides a component value then
52           //     use that for the expected pattern.  Note, the baseURL
53           //     does not provide search/hash component values.
54           //  3. Otherwise fall back on the default pattern of `*` for an
55           //     empty component pattern.
56           if (entry.pattern[component]) {
57             expected = entry.pattern[component];
58           } else if (baseURL &&
59                      component !== 'search' && component !== 'hash') {
60             let base_value = baseURL[component];
61             // Unfortunately the URL() protocol getter includes a trailing `:`
62             // that is not used by URLPattern.  Strip that off in necessary.
63             if (component === 'protocol')
64               base_value = base_value.substring(0, base_value.length - 1);
65             expected = base_value;
66           } else {
67             expected = '*';
68           }
69         }
71         // Finally, assert that the compiled object property matches the
72         // expected property.
73         assert_equals(pattern[component], expected,
74                       `compiled pattern property '${component}'`);
75       }
77       // First, validate the test() method by converting the expected result to
78       // a truthy value.
79       if (entry.inputBaseURL) {
80         assert_equals(pattern.test(entry.input, entry.inputBaseURL),
81                       !!entry.expected_match, 'test() result');
82       } else {
83         assert_equals(pattern.test(entry.input),
84                       !!entry.expected_match, 'test() result');
85       }
87       // Next, start validating the exec() method.
88       let result = entry.inputBaseURL
89                  ? pattern.exec(entry.input, entry.inputBaseURL)
90                  : pattern.exec(entry.input);
92       // On a failed match exec() returns null.
93       if (!entry.expected_match) {
94         assert_equals(result, entry.expected_match, 'exec() failed match result');
95         return;
96       }
98       // Next verify the result.input is correct.  This may be a structured
99       // URLPatternInit dictionary object or a URL string.
100       if (typeof entry.expected_match.input === 'object') {
101         assert_object_equals(result.input, entry.expected_match.input,
102                              'exec() result.input');
103       } else {
104         assert_equals(result.input, entry.expected_match.input,
105                       'exec() result.input');
106       }
108       // Next we will compare the URLPatternComponentResult for each of these
109       // expected components.
110       for (let component of kComponents) {
111         let expected_obj = entry.expected_match[component];
113         // If the test expectations don't include a component object, then
114         // we auto-generate one.  This is convenient for the many cases
115         // where the pattern has a default wildcard or empty string pattern
116         // for a component and the input is essentially empty.
117         if (!expected_obj) {
118           expected_obj = { input: '', groups: {} };
120           // Next, we must treat default wildcards differently than empty string
121           // patterns.  The wildcard results in a capture group, but the empty
122           // string pattern does not.  The expectation object must list which
123           // components should be empty instead of wildcards in
124           // |exactly_empty_components|.
125           if (!entry.expected_match.exactly_empty_components ||
126               !entry.expected_match.exactly_empty_components.includes(component)) {
127             expected_obj.groups['0'] = '';
128           }
129         }
130         assert_object_equals(result[component], expected_obj,
131                              `exec() result for ${component}`);
132       }
133     }, `Pattern: ${JSON.stringify(entry.pattern)} ` +
134        `Input: ${JSON.stringify(entry.input)} ` +
135        `InputBaseURL: ${JSON.stringify(entry.inputBaseURL)}`);
136   }
139 promise_test(async function() {
140   const response = await fetch('resources/urlpatterntestdata.json');
141   const data = await response.json();
142   runTests(data);
143 }, 'Loading data...');