Skip to content

Commit

Permalink
Introduce IdlInterface#should_have_interface_object() method (web-pla…
Browse files Browse the repository at this point in the history
  • Loading branch information
shvaikalesh authored Jul 3, 2020
1 parent b1d24b1 commit 2979a22
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 24 deletions.
3 changes: 1 addition & 2 deletions dom/idlharness.window.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ idl_test(
DOMTokenList: ['document.body.classList'],
XPathEvaluator: ['new XPathEvaluator()'],
XPathExpression: ['document.createExpression("//*")'],
// Skipped due to https://github.com/web-platform-tests/wpt/issues/18827:
// XPathNSResolver: ['document.createNSResolver(document.body)'],
XPathNSResolver: ['document.createNSResolver(document.body)'],
XPathResult: ['document.evaluate("//*", document.body)'],
});
}
Expand Down
51 changes: 29 additions & 22 deletions resources/idlharness.js
Original file line number Diff line number Diff line change
Expand Up @@ -1409,15 +1409,28 @@ IdlInterface.prototype.get_interface_object_owner = function()
return legacyNamespace ? self[legacyNamespace] : self;
};

IdlInterface.prototype.should_have_interface_object = function()
{
// "For every interface that is exposed in a given ECMAScript global
// environment and:
// * is a callback interface that has constants declared on it, or
// * is a non-callback interface that is not declared with the
// [NoInterfaceObject] extended attribute,
// a corresponding property MUST exist on the ECMAScript global object.

return this.is_callback() ? this.has_constants() : !this.has_extended_attribute("NoInterfaceObject");
};

IdlInterface.prototype.assert_interface_object_exists = function()
{
var owner = this.get_legacy_namespace() || "self";
assert_own_property(self[owner], this.name, owner + " does not have own property " + format_value(this.name));
};

IdlInterface.prototype.get_interface_object = function() {
if (this.has_extended_attribute("NoInterfaceObject")) {
throw new IdlHarnessError(this.name + " has no interface object due to NoInterfaceObject");
if (!this.should_have_interface_object()) {
var reason = this.is_callback() ? "lack of declared constants" : "declared [NoInterfaceObject] attribute";
throw new IdlHarnessError(this.name + " has no interface object due to " + reason);
}

return this.get_interface_object_owner()[this.name];
Expand Down Expand Up @@ -1607,20 +1620,14 @@ IdlInterface.prototype.test_self = function()
{
// This function tests WebIDL as of 2015-01-13.

// "For every interface that is exposed in a given ECMAScript global
// environment and:
// * is a callback interface that has constants declared on it, or
// * is a non-callback interface that is not declared with the
// [NoInterfaceObject] extended attribute,
// a corresponding property MUST exist on the ECMAScript global object.
if (!this.should_have_interface_object()) {
return;
}

// The name of the property is the identifier of the interface, and its
// value is an object called the interface object.
// The property has the attributes { [[Writable]]: true,
// [[Enumerable]]: false, [[Configurable]]: true }."
if (this.is_callback() && !this.has_constants()) {
return;
}

// TODO: Should we test here that the property is actually writable
// etc., or trust getOwnPropertyDescriptor?
this.assert_interface_object_exists();
Expand Down Expand Up @@ -1704,7 +1711,7 @@ IdlInterface.prototype.test_self = function()
}
}.bind(this), this.name + " interface: existence and properties of interface object");

if (!this.is_callback()) {
if (this.should_have_interface_object() && !this.is_callback()) {
subsetTestByKey(this.name, test, function() {
// This function tests WebIDL as of 2014-10-25.
// https://heycam.github.io/webidl/#es-interface-call
Expand All @@ -1729,7 +1736,7 @@ IdlInterface.prototype.test_self = function()
}.bind(this), this.name + " interface object length");
}

if (!this.is_callback() || this.has_constants()) {
if (this.should_have_interface_object()) {
subsetTestByKey(this.name, test, function() {
// This function tests WebIDL as of 2015-11-17.
// https://heycam.github.io/webidl/#interface-object
Expand Down Expand Up @@ -1926,7 +1933,7 @@ IdlInterface.prototype.test_self = function()
// This function tests WebIDL as of 2015-01-21.
// https://heycam.github.io/webidl/#interface-object

if (this.is_callback() && !this.has_constants()) {
if (!this.should_have_interface_object()) {
return;
}

Expand Down Expand Up @@ -2050,7 +2057,7 @@ IdlInterface.prototype.test_self = function()

subsetTestByKey(this.name, test, function()
{
if (this.is_callback() && !this.has_constants()) {
if (!this.should_have_interface_object()) {
return;
}

Expand Down Expand Up @@ -2085,7 +2092,7 @@ IdlInterface.prototype.test_self = function()

subsetTestByKey(this.name, test, function()
{
if (this.is_callback() && !this.has_constants()) {
if (!this.should_have_interface_object()) {
return;
}

Expand Down Expand Up @@ -2326,8 +2333,8 @@ IdlInterface.prototype.test_member_attribute = function(member)
var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: attribute " + member.name);
a_test.step(function()
{
if (this.is_callback() && !this.has_constants()) {
a_test.done()
if (!this.should_have_interface_object()) {
a_test.done();
return;
}

Expand Down Expand Up @@ -2422,7 +2429,7 @@ IdlInterface.prototype.test_member_operation = function(member)
// This function tests WebIDL as of 2015-12-29.
// https://heycam.github.io/webidl/#es-operations

if (this.is_callback() && !this.has_constants()) {
if (!this.should_have_interface_object()) {
a_test.done();
return;
}
Expand Down Expand Up @@ -2665,7 +2672,7 @@ IdlInterface.prototype.test_member_stringifier = function(member)
{
subsetTestByKey(this.name, test, function()
{
if (this.is_callback() && !this.has_constants()) {
if (!this.should_have_interface_object()) {
return;
}

Expand Down Expand Up @@ -2859,7 +2866,7 @@ IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception
// interface object, or the object is from a different global environment
// (not instanceof Object). TODO: test in this case that its prototype at
// least looks correct, even if we can't test that it's actually correct.
if (!this.has_extended_attribute("NoInterfaceObject")
if (this.should_have_interface_object()
&& (typeof obj != expected_typeof || obj instanceof Object))
{
subsetTestByKey(this.name, test, function()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<title>IdlInterface.prototype.should_have_interface_object()</title>
<div id="log"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
<script src="../../../idl-helper.js"></script>
<script>
"use strict";
test(function() {
var i = interfaceFrom("callback interface A { const unsigned short B = 0; };");
assert_true(i.should_have_interface_object());
}, "callback interface with a constant");

test(function() {
var i = interfaceFrom("callback interface A { void b(); sequence<any> c(); };");
assert_false(i.should_have_interface_object());
}, "callback interface without a constant");

test(function() {
var i = interfaceFrom("[NoInterfaceObject] interface A { };");
assert_false(i.should_have_interface_object());
}, "non-callback interface with [NoInterfaceObject]");

test(function() {
var i = interfaceFrom("interface A { };");
assert_true(i.should_have_interface_object());
}, "non-callback interface without [NoInterfaceObject]");
</script>

0 comments on commit 2979a22

Please sign in to comment.