Skip to content

Commit

Permalink
URLPattern: Implement compare() method.
Browse files Browse the repository at this point in the history
This CL adds a prototype URLPattern.compare() to provide a natural
ordering to URLPattern objects.  This was based on feedback from routing
framework authors and there is some discussion in:

whatwg/urlpattern#61

The general algorithm is to compare the two URLPattern objects component
by component in order from hash through protocol.  Each component
pattern is then compared Part by Part.  The PartType, Modifier, and
text contents are then used to determine which Part is "more specific".

Bug: 1232795
Change-Id: I8474cd7d7689e657c9c74c552ad630cdcdd86c95
  • Loading branch information
wanderview authored and chromium-wpt-export-bot committed Jul 26, 2021
1 parent 939731a commit 39c7c20
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 0 deletions.
132 changes: 132 additions & 0 deletions urlpattern/resources/urlpattern-compare-test-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
[
{
"left": { "pathname": "/foo/a" },
"right": { "pathname": "/foo/b" },
"expected": -1
},
{
"left": { "pathname": "/foo/b" },
"right": { "pathname": "/foo/bar" },
"expected": -1
},
{
"left": { "pathname": "/foo/bar" },
"right": { "pathname": "/foo/:bar" },
"expected": 1
},
{
"left": { "pathname": "/foo/" },
"right": { "pathname": "/foo/:bar" },
"expected": 1
},
{
"left": { "pathname": "/foo/:bar" },
"right": { "pathname": "/foo/*" },
"expected": 1
},
{
"left": { "pathname": "/foo/{bar}" },
"right": { "pathname": "/foo/(bar)" },
"expected": 1
},
{
"left": { "pathname": "/foo/{bar}" },
"right": { "pathname": "/foo/{bar}+" },
"expected": 1
},
{
"left": { "pathname": "/foo/{bar}+" },
"right": { "pathname": "/foo/{bar}?" },
"expected": 1
},
{
"left": { "pathname": "/foo/{bar}?" },
"right": { "pathname": "/foo/{bar}*" },
"expected": 1
},
{
"left": { "pathname": "/foo/(123)" },
"right": { "pathname": "/foo/(12)" },
"expected": 1
},
{
"left": { "pathname": "/foo/:b" },
"right": { "pathname": "/foo/:a" },
"expected": 0
},
{
"left": { "pathname": "*/foo" },
"right": { "pathname": "*" },
"expected": 1
},
{
"left": { "protocol": "https", "pathname": "*/foo" },
"right": { "protocol": "https" },
"expected": 1
},
{
"left": { "protocol": "https" },
"right": { "protocol": "https", "pathname": "*" },
"expected": 0
},
{
"left": { "hash": "b", "search": "a" },
"right": { "hash": "a", "search": "b" },
"expected": 1
},
{
"left": { "search": "b", "pathname": "a" },
"right": { "search": "a", "pathname": "b" },
"expected": 1
},
{
"left": { "pathname": "b", "port": "1" },
"right": { "pathname": "a", "port": "2" },
"expected": 1
},
{
"left": { "port": "2", "hostname": "a" },
"right": { "port": "1", "hostname": "b" },
"expected": 1
},
{
"left": { "hostname": "b", "password": "a" },
"right": { "hostname": "a", "password": "b" },
"expected": 1
},
{
"left": { "password": "b", "username": "a" },
"right": { "password": "a", "username": "b" },
"expected": 1
},
{
"left": { "username": "b", "protocol": "a" },
"right": { "username": "a", "protocol": "b" },
"expected": 1
},
{
"left": { "port": "9" },
"right": { "port": "100" },
"expected": 1
},
{
"left": { "pathname": "foo/:bar?/baz" },
"right": { "pathname": "foo/{:bar}?/baz" },
"expected": -1
},
{
"left": { "pathname": "foo/:bar?/baz" },
"right": { "pathname": "foo{/:bar}?/baz" },
"expected": 0
},
{
"left": { "pathname": "foo/:bar?/baz" },
"right": { "pathname": "fo{o/:bar}?/baz" },
"expected": 1
},
{
"left": { "pathname": "foo/:bar?/baz" },
"right": { "pathname": "foo{/:bar/}?baz" },
"expected": -1
}
]
25 changes: 25 additions & 0 deletions urlpattern/resources/urlpattern-compare-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function runTests(data) {
for (let entry of data) {
test(function() {
const left = new URLPattern(entry.left);
const right = new URLPattern(entry.right);

assert_equals(URLPattern.compare(left, right), entry.expected);

// We have to coerce to an integer here in order to avoid asserting
// that `+0` is `-0`.
const reverse_expected = ~~(entry.expected * -1);
assert_equals(URLPattern.compare(right, left), reverse_expected, "reverse order");

assert_equals(URLPattern.compare(left, left), 0, "left equality");
assert_equals(URLPattern.compare(right, right), 0, "right equality");
}, `Pattern: ${JSON.stringify(entry.left)} ` +
`Inputs: ${JSON.stringify(entry.right)}`);
}
}

promise_test(async function() {
const response = await fetch('resources/urlpattern-compare-test-data.json');
const data = await response.json();
runTests(data);
}, 'Loading data...');
2 changes: 2 additions & 0 deletions urlpattern/urlpattern-compare.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// META: global=window,worker
// META: script=resources/urlpattern-compare-tests.js
2 changes: 2 additions & 0 deletions urlpattern/urlpattern-compare.https.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// META: global=window,worker
// META: script=resources/urlpattern-compare-tests.js

0 comments on commit 39c7c20

Please sign in to comment.