Index: third_party/WebKit/LayoutTests/imported/web-platform-tests/resources/idlharness.js |
diff --git a/third_party/WebKit/LayoutTests/imported/web-platform-tests/resources/idlharness.js b/third_party/WebKit/LayoutTests/imported/web-platform-tests/resources/idlharness.js |
index 02304ca10600ac1e384bb3227e19a9531e3b3b9f..75ec97e771c069415e8cc63acdf2e184425a57da 100644 |
--- a/third_party/WebKit/LayoutTests/imported/web-platform-tests/resources/idlharness.js |
+++ b/third_party/WebKit/LayoutTests/imported/web-platform-tests/resources/idlharness.js |
@@ -69,6 +69,34 @@ function minOverloadLength(overloads) { |
.reduce(function(m, n) { return Math.min(m, n); }); |
} |
+function throwOrReject(a_test, operation, fn, obj, args, message, cb) { |
+ if (operation.idlType.generic !== "Promise") { |
+ assert_throws(new TypeError(), function() { |
+ fn.apply(obj, args); |
+ }, message); |
+ cb(); |
+ } else { |
+ try { |
+ promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(cb, cb); |
+ } catch (e){ |
+ a_test.step(function() { |
+ assert_unreached("Throws \"" + e + "\" instead of rejecting promise"); |
+ cb(); |
+ }); |
+ } |
+ } |
+} |
+ |
+function awaitNCallbacks(n, cb, ctx) { |
+ var counter = 0; |
+ return function() { |
+ counter++; |
+ if (counter >= n) { |
+ cb(); |
+ } |
+ }; |
+} |
+ |
/// IdlArray /// |
// Entry point |
self.IdlArray = function() |
@@ -544,8 +572,7 @@ IdlDictionary.prototype = Object.create(IdlObject.prototype); |
/// IdlInterface /// |
function IdlInterface(obj, is_callback) { |
/** |
- * obj is an object produced by the WebIDLParser.js "exception" or |
- * "interface" production, as appropriate. |
+ * obj is an object produced by the WebIDLParser.js "interface" production. |
*/ |
/** Self-explanatory. */ |
@@ -555,9 +582,9 @@ function IdlInterface(obj, is_callback) { |
this.array = obj.array; |
/** |
- * An indicator of whether we should run tests on the (exception) interface |
- * object and (exception) interface prototype object. Tests on members are |
- * controlled by .untested on each member, not this. |
+ * An indicator of whether we should run tests on the interface object and |
+ * interface prototype object. Tests on members are controlled by .untested |
+ * on each member, not this. |
*/ |
this.untested = obj.untested; |
@@ -944,12 +971,12 @@ IdlInterface.prototype.test_self = function() |
IdlInterface.prototype.test_member_const = function(member) |
//@{ |
{ |
+ if (!this.has_constants()) { |
+ throw "Internal error: test_member_const called without any constants"; |
+ } |
+ |
test(function() |
{ |
- if (this.is_callback() && !this.has_constants()) { |
- return; |
- } |
- |
assert_own_property(self, this.name, |
"self does not have own property " + format_value(this.name)); |
@@ -971,14 +998,11 @@ IdlInterface.prototype.test_member_const = function(member) |
assert_true(desc.enumerable, "property is not enumerable"); |
assert_false(desc.configurable, "property is configurable"); |
}.bind(this), this.name + " interface: constant " + member.name + " on interface object"); |
+ |
// "In addition, a property with the same characteristics must |
// exist on the interface prototype object." |
test(function() |
{ |
- if (this.is_callback() && !this.has_constants()) { |
- return; |
- } |
- |
assert_own_property(self, this.name, |
"self does not have own property " + format_value(this.name)); |
@@ -1031,6 +1055,10 @@ IdlInterface.prototype.test_member_attribute = function(member) |
"The prototype object must not have a property " + |
format_value(member.name)); |
+ var getter = Object.getOwnPropertyDescriptor(self, member.name).get; |
+ assert_equals(typeof(getter), "function", |
+ format_value(member.name) + " must have a getter"); |
+ |
// Try/catch around the get here, since it can legitimately throw. |
// If it does, we obviously can't check for equality with direct |
// invocation of the getter. |
@@ -1043,12 +1071,10 @@ IdlInterface.prototype.test_member_attribute = function(member) |
gotValue = false; |
} |
if (gotValue) { |
- var getter = Object.getOwnPropertyDescriptor(self, member.name).get; |
- assert_equals(typeof(getter), "function", |
- format_value(member.name) + " must have a getter"); |
assert_equals(propVal, getter.call(undefined), |
"Gets on a global should not require an explicit this"); |
} |
+ |
this.do_interface_attribute_asserts(self, member); |
} else { |
assert_true(member.name in self[this.name].prototype, |
@@ -1072,9 +1098,17 @@ IdlInterface.prototype.test_member_attribute = function(member) |
IdlInterface.prototype.test_member_operation = function(member) |
//@{ |
{ |
- test(function() |
+ var a_test = async_test(this.name + " interface: operation " + member.name + |
+ "(" + member.arguments.map( |
+ function(m) {return m.idlType.idlType; } ) |
+ +")"); |
+ a_test.step(function() |
{ |
+ // This function tests WebIDL as of 2015-12-29. |
+ // https://heycam.github.io/webidl/#es-operations |
+ |
if (this.is_callback() && !this.has_constants()) { |
+ a_test.done(); |
return; |
} |
@@ -1084,45 +1118,51 @@ IdlInterface.prototype.test_member_operation = function(member) |
if (this.is_callback()) { |
assert_false("prototype" in self[this.name], |
this.name + ' should not have a "prototype" property'); |
+ a_test.done(); |
return; |
} |
assert_own_property(self[this.name], "prototype", |
'interface "' + this.name + '" does not have own property "prototype"'); |
- // "For each unique identifier of an operation defined on the |
- // interface, there must be a corresponding property on the |
- // interface prototype object (if it is a regular operation) or |
- // the interface object (if it is a static operation), unless |
- // the effective overload set for that identifier and operation |
- // and with an argument count of 0 (for the ECMAScript language |
- // binding) has no entries." |
- // |
+ // "For each unique identifier of an exposed operation defined on the |
+ // interface, there must exist a corresponding property, unless the |
+ // effective overload set for that identifier and operation and with an |
+ // argument count of 0 has no entries." |
+ |
+ // TODO: Consider [Exposed]. |
+ |
+ // "The location of the property is determined as follows:" |
var memberHolderObject; |
+ // "* If the operation is static, then the property exists on the |
+ // interface object." |
if (member["static"]) { |
assert_own_property(self[this.name], member.name, |
"interface object missing static operation"); |
memberHolderObject = self[this.name]; |
+ // "* Otherwise, [...] if the interface was declared with the [Global] |
+ // or [PrimaryGlobal] extended attribute, then the property exists |
+ // on every object that implements the interface." |
} else if (this.is_global()) { |
assert_own_property(self, member.name, |
"global object missing non-static operation"); |
memberHolderObject = self; |
+ // "* Otherwise, the property exists solely on the interface’s |
+ // interface prototype object." |
} else { |
assert_own_property(self[this.name].prototype, member.name, |
"interface prototype object missing non-static operation"); |
memberHolderObject = self[this.name].prototype; |
} |
- |
- this.do_member_operation_asserts(memberHolderObject, member); |
- }.bind(this), this.name + " interface: operation " + member.name + |
- "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + |
- ")"); |
+ this.do_member_operation_asserts(memberHolderObject, member, a_test); |
+ }.bind(this)); |
}; |
//@} |
-IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member) |
+IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test) |
//@{ |
{ |
+ var done = a_test.done.bind(a_test); |
var operationUnforgeable = member.isUnforgeable; |
var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name); |
// "The property has attributes { [[Writable]]: B, |
@@ -1166,12 +1206,15 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject |
// have to skip this test for anything that on the proto chain of "self", |
// since that does in fact have implicit-this behavior. |
if (!member["static"]) { |
+ var cb; |
if (!this.is_global() && |
memberHolderObject[member.name] != self[member.name]) |
{ |
- assert_throws(new TypeError(), function() { |
- memberHolderObject[member.name].apply(null, args); |
- }, "calling operation with this = null didn't throw TypeError"); |
+ cb = awaitNCallbacks(2, done); |
+ throwOrReject(a_test, member, memberHolderObject[member.name], null, args, |
+ "calling operation with this = null didn't throw TypeError", cb); |
+ } else { |
+ cb = awaitNCallbacks(1, done); |
} |
// ". . . If O is not null and is also not a platform object |
@@ -1179,9 +1222,10 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject |
// |
// TODO: Test a platform object that implements some other |
// interface. (Have to be sure to get inheritance right.) |
- assert_throws(new TypeError(), function() { |
- memberHolderObject[member.name].apply({}, args); |
- }, "calling operation with this = {} didn't throw TypeError"); |
+ throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, |
+ "calling operation with this = {} didn't throw TypeError", cb); |
+ } else { |
+ done(); |
} |
} |
@@ -1400,14 +1444,15 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect |
member.name && |
member.isUnforgeable) |
{ |
- test(function() |
+ var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"'); |
+ a_test.step(function() |
{ |
assert_equals(exception, null, "Unexpected exception when evaluating object"); |
assert_equals(typeof obj, expected_typeof, "wrong typeof object"); |
assert_own_property(obj, member.name, |
"Doesn't have the unforgeable operation property"); |
- this.do_member_operation_asserts(obj, member); |
- }.bind(this), this.name + " interface: " + desc + ' must have own property "' + member.name + '"'); |
+ this.do_member_operation_asserts(obj, member, a_test); |
+ }.bind(this)); |
} |
else if ((member.type == "const" |
|| member.type == "attribute" |
@@ -1460,7 +1505,10 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect |
// TODO: Test passing arguments of the wrong type. |
if (member.type == "operation" && member.name && member.arguments.length) |
{ |
- test(function() |
+ var a_test = async_test( this.name + " interface: calling " + member.name + |
+ "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + |
+ ") on " + desc + " with too few arguments must throw TypeError"); |
+ a_test.step(function() |
{ |
assert_equals(exception, null, "Unexpected exception when evaluating object"); |
assert_equals(typeof obj, expected_typeof, "wrong typeof object"); |
@@ -1480,17 +1528,16 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect |
return m.type == "operation" && m.name == member.name; |
})); |
var args = []; |
+ var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test)); |
for (var i = 0; i < minLength; i++) { |
- assert_throws(new TypeError(), function() |
- { |
- obj[member.name].apply(obj, args); |
- }.bind(this), "Called with " + i + " arguments"); |
+ throwOrReject(a_test, member, obj[member.name], obj, args, "Called with " + i + " arguments", cb); |
args.push(create_suitable_object(member.arguments[i].idlType)); |
} |
- }.bind(this), this.name + " interface: calling " + member.name + |
- "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + |
- ") on " + desc + " with too few arguments must throw TypeError"); |
+ if (minLength === 0) { |
+ cb(); |
+ } |
+ }.bind(this)); |
} |
} |
}; |