From aec6de57aff3408504664d7c2b9f8b8171fbf309 Mon Sep 17 00:00:00 2001 From: Luke Bjerring Date: Mon, 9 Apr 2018 18:24:37 +0000 Subject: [PATCH] Bug 1448492 [wpt PR 10164] - Special-case idlharness.js errors as an assert_throw option, a=testonly Automatic update from web-platform-testsHandle idlharness.js expected errors as an IdlArray.assert_throw option (#10164) * Handle idlharness.js expected errors as an IdlArray.assert_throw option wpt-commits: 355c2d77c7ec01ee18fd9c5917cc845a558551e8 wpt-pr: 10164 wpt-commits: 355c2d77c7ec01ee18fd9c5917cc845a558551e8 wpt-pr: 10164 --- .../tests/resources/idlharness.js | 78 +++++++++++++++---- .../test/tests/idlharness/basic.html | 19 +++++ .../tests/resources/testharness.js | 7 ++ 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/testing/web-platform/tests/resources/idlharness.js b/testing/web-platform/tests/resources/idlharness.js index fb273dc54421..3ee5f349cbbf 100644 --- a/testing/web-platform/tests/resources/idlharness.js +++ b/testing/web-platform/tests/resources/idlharness.js @@ -123,6 +123,28 @@ var fround = })(); //@} +/// IdlHarnessError /// +// Entry point +self.IdlHarnessError = function(message) +//@{ +{ + /** + * Message to be printed as the error's toString invocation. + */ + this.message = message; +}; + +IdlHarnessError.prototype = Object.create(Error.prototype); + +//@} +IdlHarnessError.prototype.toString = function() +//@{ +{ + return this.message; +}; + +//@} + /// IdlArray /// // Entry point self.IdlArray = function() @@ -217,7 +239,7 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) if (options && options.only && options.except) { - throw "The only and except options can't be used together." + throw new IdlHarnessError("The only and except options can't be used together."); } function should_skip(name) @@ -280,7 +302,7 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options) } if (parsed_idl.name in this.members) { - throw "Duplicate identifier " + parsed_idl.name; + throw new IdlHarnessError("Duplicate identifier " + parsed_idl.name); } switch(parsed_idl.type) { @@ -374,7 +396,7 @@ IdlArray.prototype.recursively_get_implements = function(interface_name) ret = ret.concat(this.recursively_get_implements(ret[i])); if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) { - throw "Circular implements statements involving " + ret[i]; + throw new IdlHarnessError("Circular implements statements involving " + ret[i]); } } return ret; @@ -404,7 +426,7 @@ IdlArray.prototype.recursively_get_includes = function(interface_name) ret = ret.concat(this.recursively_get_includes(ret[i])); if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) { - throw "Circular includes statements involving " + ret[i]; + throw new IdlHarnessError("Circular includes statements involving " + ret[i]); } } return ret; @@ -533,7 +555,7 @@ IdlArray.prototype.is_json_type = function(type) function exposure_set(object, default_set) { var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed" }); if (exposed.length > 1 || exposed.length < 0) { - throw "Unexpected Exposed extended attributes on " + memberName + ": " + exposed; + throw new IdlHarnessError("Unexpected Exposed extended attributes on " + memberName + ": " + exposed); } if (exposed.length === 0) { @@ -567,7 +589,33 @@ function exposed_in(globals) { return globals.indexOf("Worker") >= 0 || globals.indexOf("ServiceWorker") >= 0; } - throw "Unexpected global object"; + throw new IdlHarnessError("Unexpected global object"); +} + +//@} +/** + * Asserts that the given error message is thrown for the given function. + * @param {string|IdlHarnessError} error Expected Error message. + * @param {Function} idlArrayFunc Function operating on an IdlArray that should throw. + */ +IdlArray.prototype.assert_throws = function(error, idlArrayFunc) +//@{ +{ + try { + idlArrayFunc.call(this, this); + throw new IdlHarnessError(`${idlArrayFunc} did not throw the expected IdlHarnessError`); + } catch (e) { + if (e instanceof AssertionError) { + throw e; + } + // Assertions for behaviour of the idlharness.js engine. + if (error instanceof IdlHarnessError) { + error = error.message; + } + if (e.message !== error) { + throw new IdlHarnessError(`${idlArrayFunc} threw ${e}, not the expected IdlHarnessError`); + } + } } //@} @@ -583,7 +631,7 @@ IdlArray.prototype.test = function() if (!(parsed_idl.name in this.members) || !(this.members[parsed_idl.name] instanceof IdlInterface)) { - throw "Partial interface " + parsed_idl.name + " with no original interface"; + throw new IdlHarnessError("Partial interface " + parsed_idl.name + " with no original interface"); } if (parsed_idl.extAttrs) { @@ -848,7 +896,7 @@ IdlArray.prototype.assert_type_is = function(value, type) if (!(type in this.members)) { - throw "Unrecognized type " + type; + throw new IdlHarnessError("Unrecognized type " + type); } if (this.members[type] instanceof IdlInterface) @@ -876,7 +924,7 @@ IdlArray.prototype.assert_type_is = function(value, type) } else { - throw "Type " + type + " isn't an interface or dictionary"; + throw new IdlHarnessError("Type " + type + " isn't an interface or dictionary"); } }; //@} @@ -1345,13 +1393,13 @@ IdlInterface.prototype.test_self = function() { var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; }); if (aliasAttrs.length > 1) { - throw "Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name; + throw new IdlHarnessError("Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name); } if (this.is_callback()) { - throw "Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name; + throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name); } if (this.exposureSet.indexOf("Window") === -1) { - throw "Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window"; + throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window"); } // TODO: when testing of [NoInterfaceObject] interfaces is supported, // check that it's not specified together with LegacyWindowAlias. @@ -1360,7 +1408,7 @@ IdlInterface.prototype.test_self = function() var rhs = aliasAttrs[0].rhs; if (!rhs) { - throw "Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier"; + throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier"); } var aliases; if (rhs.type === "identifier-list") { @@ -1730,7 +1778,7 @@ IdlInterface.prototype.test_member_const = function(member) //@{ { if (!this.has_constants()) { - throw "Internal error: test_member_const called without any constants"; + throw new IdlHarnessError("Internal error: test_member_const called without any constants"); } test(function() @@ -2288,7 +2336,7 @@ IdlInterface.prototype.test_object = function(desc) { if (!(current_interface.name in this.array.members)) { - throw "Interface " + current_interface.name + " not found (inherited by " + this.name + ")"; + throw new IdlHarnessError("Interface " + current_interface.name + " not found (inherited by " + this.name + ")"); } if (current_interface.prevent_multiple_testing && current_interface.already_tested) { diff --git a/testing/web-platform/tests/resources/test/tests/idlharness/basic.html b/testing/web-platform/tests/resources/test/tests/idlharness/basic.html index da3c3faaa1c2..f688f35629c7 100644 --- a/testing/web-platform/tests/resources/test/tests/idlharness/basic.html +++ b/testing/web-platform/tests/resources/test/tests/idlharness/basic.html @@ -29,6 +29,25 @@ test(function() { assert_equals(typeof WebIDL2.parse("interface Foo {};"), "object"); }, 'WebIDL2 parse method should produce an AST for correct WebIDL'); + test(function() { + let i = new IdlArray(); + i.add_untested_idls('partial interface A {};'); + i.assert_throws( new IdlHarnessError("Partial interface A with no original interface"), i.test); + }, 'assert_throws should handle IdlHarnessError'); + test(function() { + let i = new IdlArray(); + i.add_untested_idls('partial interface A {};'); + i.assert_throws( "Partial interface A with no original interface", i.test); + }, 'assert_throws should handle IdlHarnessError from message'); + test(function () { + try { + let i = new IdlArray(); + i.add_untested_idls('interface A {};'); + i.assert_throws( "Partial interface A with no original interface", i.test); + } catch (e) { + assert_true(e instanceof IdlHarnessError); + } + }, 'assert_throws should throw if no IdlHarnessError thrown'); diff --git a/testing/web-platform/tests/resources/testharness.js b/testing/web-platform/tests/resources/testharness.js index 23b8651bb13e..86ecc1ba252e 100644 --- a/testing/web-platform/tests/resources/testharness.js +++ b/testing/web-platform/tests/resources/testharness.js @@ -1247,6 +1247,13 @@ policies and contribution forms [3]. } expose(assert_readonly, "assert_readonly"); + /** + * Assert an Exception with the expected code is thrown. + * + * @param {object|number|string} code The expected exception code. + * @param {Function} func Function which should throw. + * @param {string} description Error description for the case that the error is not thrown. + */ function assert_throws(code, func, description) { try {