From 4676cbf3a77f45175eb9b9491e5a71ec2ebda73b Mon Sep 17 00:00:00 2001 From: Dominique Hazael-Massieux Date: Fri, 6 Nov 2015 17:57:48 +0100 Subject: [PATCH 1/5] Adapt throw test for Promise-returning operations --- idlharness.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/idlharness.js b/idlharness.js index 9f324e089ebf72..b50b1dac77fd66 100644 --- a/idlharness.js +++ b/idlharness.js @@ -69,6 +69,22 @@ function minOverloadLength(overloads) { .reduce(function(m, n) { return Math.min(m, n); }); } +function throwOrReject(operation, fn, obj, args, message) { + if (operation.idlType.generic !== "Promise") { + assert_throws(new TypeError(), function() { + fn.apply(obj, args); + }, message); + } else { + fn.apply(obj, args).then( + function() { + assert_unreached(message); + }, + function(e) { + assert_true(e instanceof TypeError, message); + }); + } +} + /// IdlArray /// // Entry point self.IdlArray = function() @@ -1145,9 +1161,7 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject 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"); + throwOrReject(member, memberHolderObject[member.name], null, args, "calling operation with this = null didn't throw TypeError"); } // ". . . If O is not null and is also not a platform object @@ -1155,9 +1169,7 @@ 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(member, memberHolderObject[member.name], {}, args, "calling operation with this = {} didn't throw TypeError"); } } @@ -1457,10 +1469,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect })); var args = []; 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(member, obj[member.name], obj, args, "Called with " + i + " arguments"); args.push(create_suitable_object(member.arguments[i].idlType)); } From 97dece3259e71145b2a3902e13bf8236088c4c91 Mon Sep 17 00:00:00 2001 From: Dominique Hazael-Massieux Date: Thu, 26 Nov 2015 08:48:32 +0100 Subject: [PATCH 2/5] Fix whitespace indent --- idlharness.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/idlharness.js b/idlharness.js index b50b1dac77fd66..c2dda020473899 100644 --- a/idlharness.js +++ b/idlharness.js @@ -75,14 +75,12 @@ function throwOrReject(operation, fn, obj, args, message) { fn.apply(obj, args); }, message); } else { - fn.apply(obj, args).then( - function() { - assert_unreached(message); - }, - function(e) { - assert_true(e instanceof TypeError, message); - }); - } + fn.apply(obj, args).then(function() { + assert_unreached(message); + }, function(e) { + assert_true(e instanceof TypeError, message); + }); + } } /// IdlArray /// From 3cc0059cb21686f855c7156ce56c1073c68b2a7f Mon Sep 17 00:00:00 2001 From: Dominique Hazael-Massieux Date: Thu, 26 Nov 2015 11:33:39 +0100 Subject: [PATCH 3/5] Use promise_rejects to test rejection --- idlharness.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/idlharness.js b/idlharness.js index c2dda020473899..8fb462ea372114 100644 --- a/idlharness.js +++ b/idlharness.js @@ -75,11 +75,16 @@ function throwOrReject(operation, fn, obj, args, message) { fn.apply(obj, args); }, message); } else { - fn.apply(obj, args).then(function() { - assert_unreached(message); - }, function(e) { - assert_true(e instanceof TypeError, message); - }); + var test = async_test(operation.name + ": " + message); + var done = test.done.bind(test); + try { + promise_rejects(test, new TypeError(), fn.apply(obj, args)).then(done, done); + } catch (e){ + test.step(function() { + assert_unreached("Throws \"" + e + "\" instead of rejecting promise"); + test.done(); + }); + } } } From b01570d302349832ab0be5668dbea5b1b3bbb349 Mon Sep 17 00:00:00 2001 From: Dominique Hazael-Massieux Date: Thu, 7 Jan 2016 18:37:42 +0100 Subject: [PATCH 4/5] Use asynchronous test without creating a new test object per https://github.com/w3c/testharness.js/pull/161#issuecomment-159901984 and https://github.com/zqzhang --- idlharness.js | 70 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/idlharness.js b/idlharness.js index 8fb462ea372114..2f5bee7eb54444 100644 --- a/idlharness.js +++ b/idlharness.js @@ -69,25 +69,34 @@ function minOverloadLength(overloads) { .reduce(function(m, n) { return Math.min(m, n); }); } -function throwOrReject(operation, fn, obj, args, message) { +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 { - var test = async_test(operation.name + ": " + message); - var done = test.done.bind(test); try { - promise_rejects(test, new TypeError(), fn.apply(obj, args)).then(done, done); + promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(cb, cb); } catch (e){ - test.step(function() { + a_test.step(function() { assert_unreached("Throws \"" + e + "\" instead of rejecting promise"); - test.done(); + cb(); }); } } } +function awaitNCallbacks(n, cb, ctx) { + var counter = 0; + return function() { + counter++; + if (counter >= n) { + cb(); + } + }; +} + /// IdlArray /// // Entry point self.IdlArray = function() @@ -1067,9 +1076,13 @@ 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() { if (this.is_callback() && !this.has_constants()) { + a_test.done(); return; } @@ -1079,6 +1092,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; } @@ -1107,17 +1121,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, @@ -1161,10 +1173,14 @@ 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]) { - throwOrReject(member, memberHolderObject[member.name], 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 @@ -1172,7 +1188,9 @@ 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.) - throwOrReject(member, memberHolderObject[member.name], {}, 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(); } } @@ -1391,14 +1409,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" @@ -1451,7 +1470,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"); @@ -1471,14 +1493,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++) { - throwOrReject(member, obj[member.name], obj, args, "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)); } } }; From ce10680e24c52a0fcda0cfb730902fc8987e7db0 Mon Sep 17 00:00:00 2001 From: Dominique Hazael-Massieux Date: Wed, 13 Jan 2016 08:47:35 +0100 Subject: [PATCH 5/5] Fix indents Per @zqzhang feedback --- idlharness.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/idlharness.js b/idlharness.js index 2f5bee7eb54444..2bbf69c7904c7f 100644 --- a/idlharness.js +++ b/idlharness.js @@ -1077,8 +1077,9 @@ IdlInterface.prototype.test_member_operation = function(member) //@{ { var a_test = async_test(this.name + " interface: operation " + member.name + - "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + - ")"); + "(" + member.arguments.map( + function(m) {return m.idlType.idlType; } ) + +")"); a_test.step(function() { if (this.is_callback() && !this.has_constants()) { @@ -1178,7 +1179,8 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject memberHolderObject[member.name] != self[member.name]) { cb = awaitNCallbacks(2, done); - throwOrReject(a_test, member, memberHolderObject[member.name], null, args, "calling operation with this = null didn't throw TypeError", cb); + throwOrReject(a_test, member, memberHolderObject[member.name], null, args, + "calling operation with this = null didn't throw TypeError", cb); } else { cb = awaitNCallbacks(1, done); } @@ -1188,7 +1190,8 @@ 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.) - throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, "calling operation with this = {} didn't throw TypeError", cb); + throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, + "calling operation with this = {} didn't throw TypeError", cb); } else { done(); }