Skip to content

Commit

Permalink
Merge pull request web-platform-tests#161 from w3c/promise-throw
Browse files Browse the repository at this point in the history
Adapt throw test for Promise-returning operations
  • Loading branch information
Zhiqiang Zhang committed Jan 13, 2016
2 parents 154ec10 + ce10680 commit 72dd676
Showing 1 changed file with 63 additions and 24 deletions.
87 changes: 63 additions & 24 deletions idlharness.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -1070,12 +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;
}

Expand All @@ -1085,6 +1118,7 @@ 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;
}

Expand Down Expand Up @@ -1120,17 +1154,15 @@ IdlInterface.prototype.test_member_operation = function(member)
"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,
Expand Down Expand Up @@ -1174,22 +1206,26 @@ 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
// that implements interface I, throw a TypeError."
//
// 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();
}
}

Expand Down Expand Up @@ -1408,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"
Expand Down Expand Up @@ -1468,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");
Expand All @@ -1488,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));
}
}
};
Expand Down

0 comments on commit 72dd676

Please sign in to comment.