| <!DOCTYPE html> |
| <meta charset=utf-8> |
| <title>XPathNSResolver implements callback interface</title> |
| <link rel="help" href="https://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator"> |
| <link rel="help" href="https://heycam.github.io/webidl/#call-a-user-objects-operation"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/invalid_namespace_test.js"></script> |
| <div id=log></div> |
| <script> |
| "use strict"; |
| |
| test(() => { |
| let resolverCalls = 0; |
| document.evaluate("/foo:bar", document.documentElement, () => { |
| resolverCalls++; |
| return ""; |
| }); |
| |
| assert_equals(resolverCalls, 1); |
| }, "callable resolver"); |
| |
| test(() => { |
| let resolverCalls = 0; |
| const resolver = () => { |
| resolverCalls++; |
| return ""; |
| }; |
| |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| |
| assert_equals(resolverCalls, 2); |
| }, "callable resolver: result is not cached"); |
| |
| promise_test(t => { |
| const testError = { name: "test" }; |
| const resolver = () => { |
| throw testError; |
| }; |
| |
| return promise_rejects_exactly(t, testError, |
| invalid_namespace_test(t, resolver) |
| ); |
| }, "callable resolver: abrupt completion from Call"); |
| |
| test(() => { |
| let resolverCalls = 0; |
| const resolver = () => { |
| resolverCalls++; |
| return ""; |
| }; |
| |
| let resolverGets = 0; |
| Object.defineProperty(resolver, "lookupNamespaceURI", { |
| get() { |
| resolverGets++; |
| }, |
| }); |
| |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| |
| assert_equals(resolverCalls, 1); |
| assert_equals(resolverGets, 0); |
| }, "callable resolver: no 'lookupNamespaceURI' lookups"); |
| |
| test(() => { |
| let resolverCalls = 0; |
| document.evaluate("/foo:bar", document.documentElement, { |
| lookupNamespaceURI() { |
| resolverCalls++; |
| return ""; |
| }, |
| }); |
| |
| assert_equals(resolverCalls, 1); |
| }, "object resolver"); |
| |
| test(() => { |
| let thisValue, prefixArg; |
| const resolver = { |
| lookupNamespaceURI(prefix) { |
| thisValue = this; |
| prefixArg = prefix; |
| return ""; |
| }, |
| }; |
| |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| |
| assert_equals(thisValue, resolver); |
| assert_equals(prefixArg, "foo"); |
| }, "object resolver: this value and `prefix` argument"); |
| |
| test(() => { |
| let resolverCalls = 0; |
| const lookupNamespaceURI = () => { |
| resolverCalls++; |
| return ""; |
| }; |
| |
| let resolverGets = 0; |
| const resolver = { |
| get lookupNamespaceURI() { |
| resolverGets++; |
| return lookupNamespaceURI; |
| }, |
| }; |
| |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| document.evaluate("/foo:bar", document.documentElement, resolver); |
| |
| assert_equals(resolverCalls, 2); |
| assert_equals(resolverGets, 2); |
| }, "object resolver: 'lookupNamespaceURI' is not cached"); |
| |
| promise_test(t => { |
| const testError = { name: "test" }; |
| const resolver = { |
| get lookupNamespaceURI() { |
| throw testError; |
| }, |
| }; |
| |
| return promise_rejects_exactly(t, testError, |
| invalid_namespace_test(t, resolver) |
| ); |
| }, "object resolver: abrupt completion from Get"); |
| |
| promise_test(t => { |
| const resolver = { |
| lookupNamespaceURI: {}, |
| }; |
| |
| return promise_rejects_js(t, TypeError, |
| invalid_namespace_test(t, resolver) |
| ); |
| }, "object resolver: 'lookupNamespaceURI' is thruthy and not callable"); |
| |
| promise_test(t => { |
| return promise_rejects_js(t, TypeError, |
| invalid_namespace_test(t, {}) |
| ); |
| }, "object resolver: 'lookupNamespaceURI' is falsy and not callable"); |
| </script> |
| </body> |