From 977929c06d50bcc8faaa1d1759d7e6ffd242f067 Mon Sep 17 00:00:00 2001 From: Simon Pieters Date: Fri, 6 Jul 2018 16:29:09 +0000 Subject: [PATCH] Bug 1467795 [wpt PR 11414] - [idlharness.js] Support subsetTestByKey in idlharness, a=testonly Automatic update from web-platform-tests[idlharness.js] Support subsetTestByKey in idlharness (#11414) Fixes #11413. -- wpt-commits: 9bf1daa3d8b4425f2354c3ca92c4cf0398d329dd wpt-pr: 11414 --- testing/web-platform/meta/MANIFEST.json | 33 +++++++- .../tests/common/subset-tests-by-key.js | 76 +++++++++++++++++ .../web-platform/tests/dom/interfaces.html | 3 + .../tests/html/dom/interfaces.https.html | 5 +- .../tests/resources/idlharness.js | 84 +++++++++++-------- 5 files changed, 162 insertions(+), 39 deletions(-) create mode 100644 testing/web-platform/tests/common/subset-tests-by-key.js diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index f54197e75ea4..59854695fe6d 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -193579,6 +193579,11 @@ {} ] ], + "common/subset-tests-by-key.js": [ + [ + {} + ] + ], "common/subset-tests.js": [ [ {} @@ -326967,7 +326972,11 @@ ], "dom/interfaces.html": [ [ - "/dom/interfaces.html", + "/dom/interfaces.html?exclude=Node", + {} + ], + [ + "/dom/interfaces.html?include=Node", {} ] ], @@ -341381,7 +341390,19 @@ ], "html/dom/interfaces.https.html": [ [ - "/html/dom/interfaces.https.html", + "/html/dom/interfaces.https.html?exclude=(Document|Window|HTML.*)", + { + "timeout": "long" + } + ], + [ + "/html/dom/interfaces.https.html?include=(Document|Window)", + { + "timeout": "long" + } + ], + [ + "/html/dom/interfaces.https.html?include=HTML.*", { "timeout": "long" } @@ -417214,6 +417235,10 @@ "e3593850f8098d3f3ff82c042deab15f51c66a52", "support" ], + "common/subset-tests-by-key.js": [ + "270a9b898f6ae0da4dac481a5157a890a79322b3", + "support" + ], "common/subset-tests.js": [ "0ec265b2167686390b1c0ef92575780d47c6b1a9", "support" @@ -562307,7 +562332,7 @@ "testharness" ], "dom/interfaces.html": [ - "5053c2d407ac6261313df3f9d9699f08e9f89d4d", + "46cfe52f726e7b5fdbe737470b05b34aaff2e358", "testharness" ], "dom/lists/DOMTokenList-Iterable.html": [ @@ -573915,7 +573940,7 @@ "support" ], "html/dom/interfaces.https.html": [ - "80050746d7869d52bfe7926fa259300ce05db79e", + "74c5559dd2e6ac17ba954943da006fb5fb484719", "testharness" ], "html/dom/interfaces.worker.js": [ diff --git a/testing/web-platform/tests/common/subset-tests-by-key.js b/testing/web-platform/tests/common/subset-tests-by-key.js new file mode 100644 index 000000000000..d87ea9f76ee2 --- /dev/null +++ b/testing/web-platform/tests/common/subset-tests-by-key.js @@ -0,0 +1,76 @@ +// Only test a subset of tests with ?include=Foo or ?exclude=Foo in the URL. +// Can be used together with +// Sample usage: +// for (const test of tests) { +// subsetTestByKey("Foo", async_test, test.fn, test.name); +// } +(function() { + var subTestKeyPattern = null; + var match; + var collectKeys = false; + var collectCounts = false; + var keys = {}; + var exclude = false; + if (location.search) { + match = /(?:^\?|&)(include|exclude)=([^&]+)?/.exec(location.search); + if (match) { + subTestKeyPattern = new RegExp(`^${match[2]}$`); + if (match[1] === 'exclude') { + exclude = true; + } + } + // Below is utility code to generate for copy/paste into tests. + // Sample usage: + // test.html?get-keys + match = /(?:^\?|&)get-keys(&get-counts)?(?:&|$)/.exec(location.search); + if (match) { + collectKeys = true; + if (match[1]) { + collectCounts = true; + } + add_completion_callback(() => { + var metas = []; + var template = ''; + if (collectCounts) { + template += ' '; + } + for (var key in keys) { + var meta = template.replace("%s", key); + if (collectCounts) { + meta = meta.replace("%s", keys[key]); + } + metas.push(meta); + } + var pre = document.createElement('pre'); + pre.textContent = metas.join('\n') + '\n'; + document.body.insertBefore(pre, document.body.firstChild); + document.getSelection().selectAllChildren(pre); + }); + } + } + function shouldRunSubTest(key) { + if (key && subTestKeyPattern) { + var found = subTestKeyPattern.test(key); + if (exclude) { + return !found; + } + return found; + } + return true; + } + function subsetTestByKey(key, testFunc, ...args) { + if (collectKeys) { + if (collectCounts && key in keys) { + keys[key]++; + } else { + keys[key] = 1; + } + } + if (shouldRunSubTest(key)) { + return testFunc(...args); + } + return null; + } + self.shouldRunSubTest = shouldRunSubTest; + self.subsetTestByKey = subsetTestByKey; +})(); diff --git a/testing/web-platform/tests/dom/interfaces.html b/testing/web-platform/tests/dom/interfaces.html index c0fab016ae75..21cef048cd93 100644 --- a/testing/web-platform/tests/dom/interfaces.html +++ b/testing/web-platform/tests/dom/interfaces.html @@ -1,8 +1,11 @@ DOM IDL tests + + + diff --git a/testing/web-platform/tests/html/dom/interfaces.https.html b/testing/web-platform/tests/html/dom/interfaces.https.html index 4cb509d9f940..165865d4daa5 100644 --- a/testing/web-platform/tests/html/dom/interfaces.https.html +++ b/testing/web-platform/tests/html/dom/interfaces.https.html @@ -1,10 +1,13 @@ - HTML IDL tests + + + + diff --git a/testing/web-platform/tests/resources/idlharness.js b/testing/web-platform/tests/resources/idlharness.js index 6e239730911e..9bedb4b5625e 100644 --- a/testing/web-platform/tests/resources/idlharness.js +++ b/testing/web-platform/tests/resources/idlharness.js @@ -48,6 +48,13 @@ policies and contribution forms [3]. */ (function(){ "use strict"; +// Support subsetTestByKey from /common/subset-tests-by-key.js, but make it optional +if (!('subsetTestByKey' in self)) { + self.subsetTestByKey = function(key, callback, ...args) { + return callback(...args); + } + self.shouldRunSubTest = () => true; +} /// Helpers /// function constValue (cnt) //@{ @@ -1393,7 +1400,7 @@ IdlInterface.prototype.test = function() } if (!this.exposed) { - test(function() { + subsetTestByKey(this.name, test, function() { assert_false(this.name in self); }.bind(this), this.name + " interface: existence and properties of interface object"); return; @@ -1419,7 +1426,7 @@ IdlInterface.prototype.test = function() IdlInterface.prototype.test_self = function() //@{ { - test(function() + subsetTestByKey(this.name, test, function() { // This function tests WebIDL as of 2015-01-13. @@ -1526,7 +1533,7 @@ IdlInterface.prototype.test_self = function() }.bind(this), this.name + " interface: existence and properties of interface object"); if (!this.is_callback()) { - test(function() { + subsetTestByKey(this.name, test, function() { // This function tests WebIDL as of 2014-10-25. // https://heycam.github.io/webidl/#es-interface-call @@ -1553,7 +1560,7 @@ IdlInterface.prototype.test_self = function() } if (!this.is_callback() || this.has_constants()) { - test(function() { + subsetTestByKey(this.name, test, function() { // This function tests WebIDL as of 2015-11-17. // https://heycam.github.io/webidl/#interface-object @@ -1578,7 +1585,7 @@ IdlInterface.prototype.test_self = function() if (this.has_extended_attribute("LegacyWindowAlias")) { - test(function() + subsetTestByKey(this.name, test, function() { var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; }); if (aliasAttrs.length > 1) { @@ -1630,7 +1637,7 @@ IdlInterface.prototype.test_self = function() } // TODO: Test named constructors if I find any interfaces that have them. - test(function() + subsetTestByKey(this.name, test, function() { // This function tests WebIDL as of 2015-01-21. // https://heycam.github.io/webidl/#interface-object @@ -1757,7 +1764,7 @@ IdlInterface.prototype.test_self = function() this.test_immutable_prototype("interface prototype object", self[this.name].prototype); } - test(function() + subsetTestByKey(this.name, test, function() { if (this.is_callback() && !this.has_constants()) { return; @@ -1793,7 +1800,7 @@ IdlInterface.prototype.test_self = function() }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property'); - test(function() + subsetTestByKey(this.name, test, function() { if (this.is_callback() && !this.has_constants()) { return; @@ -1860,7 +1867,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) return; } - test(function(t) { + subsetTestByKey(this.name, test, function(t) { var originalValue = Object.getPrototypeOf(obj); var newValue = Object.create(null); @@ -1883,7 +1890,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) "of " + type + " - setting to a new value via Object.setPrototypeOf " + "should throw a TypeError"); - test(function(t) { + subsetTestByKey(this.name, test, function(t) { var originalValue = Object.getPrototypeOf(obj); var newValue = Object.create(null); @@ -1910,7 +1917,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) "of " + type + " - setting to a new value via __proto__ " + "should throw a TypeError"); - test(function(t) { + subsetTestByKey(this.name, test, function(t) { var originalValue = Object.getPrototypeOf(obj); var newValue = Object.create(null); @@ -1931,7 +1938,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) "of " + type + " - setting to a new value via Reflect.setPrototypeOf " + "should return false"); - test(function() { + subsetTestByKey(this.name, test, function() { var originalValue = Object.getPrototypeOf(obj); Object.setPrototypeOf(obj, originalValue); @@ -1939,7 +1946,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) "of " + type + " - setting to its original value via Object.setPrototypeOf " + "should not throw"); - test(function() { + subsetTestByKey(this.name, test, function() { var originalValue = Object.getPrototypeOf(obj); obj.__proto__ = originalValue; @@ -1947,7 +1954,7 @@ IdlInterface.prototype.test_immutable_prototype = function(type, obj) "of " + type + " - setting to its original value via __proto__ " + "should not throw"); - test(function() { + subsetTestByKey(this.name, test, function() { var originalValue = Object.getPrototypeOf(obj); assert_true(Reflect.setPrototypeOf(obj, originalValue)); @@ -1964,7 +1971,7 @@ IdlInterface.prototype.test_member_const = function(member) throw new IdlHarnessError("Internal error: test_member_const called without any constants"); } - test(function() + subsetTestByKey(this.name, test, function() { assert_own_property(self, this.name, "self does not have own property " + format_value(this.name)); @@ -1990,7 +1997,7 @@ IdlInterface.prototype.test_member_const = function(member) // "In addition, a property with the same characteristics must // exist on the interface prototype object." - test(function() + subsetTestByKey(this.name, test, function() { assert_own_property(self, this.name, "self does not have own property " + format_value(this.name)); @@ -2021,7 +2028,10 @@ IdlInterface.prototype.test_member_const = function(member) IdlInterface.prototype.test_member_attribute = function(member) //@{ { - var a_test = async_test(this.name + " interface: attribute " + member.name); + if (!shouldRunSubTest(this.name)) { + return; + } + 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()) { @@ -2104,7 +2114,7 @@ IdlInterface.prototype.test_member_attribute = function(member) } }.bind(this)); - test(function () { + subsetTestByKey(this.name, test, function () { this.do_member_unscopable_asserts(member); }.bind(this), 'Unscopable handled correctly for ' + member.name + ' property on ' + this.name); }; @@ -2113,7 +2123,10 @@ IdlInterface.prototype.test_member_attribute = function(member) IdlInterface.prototype.test_member_operation = function(member) //@{ { - var a_test = async_test(this.name + " interface: operation " + member.name + + if (!shouldRunSubTest(this.name)) { + return; + } + var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: operation " + member.name + "(" + member.arguments.map( function(m) {return m.idlType.idlType; } ).join(", ") +")"); @@ -2172,7 +2185,7 @@ IdlInterface.prototype.test_member_operation = function(member) this.do_member_operation_asserts(memberHolderObject, member, a_test); }.bind(this)); - test(function () { + subsetTestByKey(this.name, test, function () { this.do_member_unscopable_asserts(member); }.bind(this), 'Unscopable handled correctly for ' + member.name + "(" + @@ -2302,7 +2315,7 @@ IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, mem var instanceName = memberHolderObject.constructor.name; if (member.has_extended_attribute("Default")) { var map = this.default_to_json_operation(); - test(function() { + subsetTestByKey(this.name, test, function() { var json = memberHolderObject.toJSON(); map.forEach(function(type, k) { assert_true(k in json, "property " + JSON.stringify(k) + " should be present in the output of " + this.name + ".prototype.toJSON()"); @@ -2315,7 +2328,7 @@ IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, mem }, this); }.bind(this), "Test default toJSON operation of " + instanceName); } else { - test(function() { + subsetTestByKey(this.name, test, function() { assert_true(this.array.is_json_type(member.idlType), JSON.stringify(member.idlType) + " is not an appropriate return value for the toJSON operation of " + instanceName); this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType); }.bind(this), "Test toJSON operation of " + instanceName); @@ -2328,7 +2341,7 @@ IdlInterface.prototype.test_member_iterable = function(member) { var interfaceName = this.name; var isPairIterator = member.idlType.length === 2; - test(function() + subsetTestByKey(this.name, test, function() { var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator); assert_true(descriptor.writable, "property should be writable"); @@ -2338,11 +2351,11 @@ IdlInterface.prototype.test_member_iterable = function(member) }, "Testing Symbol.iterator property of iterable interface " + interfaceName); if (isPairIterator) { - test(function() { + subsetTestByKey(this.name, test, function() { assert_equals(self[interfaceName].prototype[Symbol.iterator], self[interfaceName].prototype["entries"], "entries method is not the same as @@iterator"); }, "Testing pair iterable interface " + interfaceName); } else { - test(function() { + subsetTestByKey(this.name, test, function() { ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) { assert_equals(self[interfaceName].prototype[property], Array.prototype[property], property + " function is not the same as Array one"); }); @@ -2354,7 +2367,7 @@ IdlInterface.prototype.test_member_iterable = function(member) IdlInterface.prototype.test_member_stringifier = function(member) //@{ { - test(function() + subsetTestByKey(this.name, test, function() { if (this.is_callback() && !this.has_constants()) { return; @@ -2439,7 +2452,7 @@ IdlInterface.prototype.test_members = function() } if (!exposed_in(exposure_set(member, this.exposureSet))) { - test(function() { + subsetTestByKey(this.name, test, function() { // It's not exposed, so we shouldn't find it anywhere. assert_false(member.name in self[this.name], "The interface object must not have a property " + @@ -2560,7 +2573,7 @@ IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception if (!this.has_extended_attribute("NoInterfaceObject") && (typeof obj != expected_typeof || obj instanceof Object)) { - test(function() + subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); @@ -2582,7 +2595,7 @@ IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception // "The class string of a platform object that implements one or more // interfaces must be the identifier of the primary interface of the // platform object." - test(function() + subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); @@ -2600,6 +2613,9 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect { // TODO: Indexed and named properties, more checks on interface members this.already_tested = true; + if (!shouldRunSubTest(this.name)) { + return; + } for (var i = 0; i < this.members.length; i++) { @@ -2608,7 +2624,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect continue; } if (!exposed_in(exposure_set(member, this.exposureSet))) { - test(function() { + subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_false(member.name in obj); }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"'); @@ -2616,7 +2632,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect } if (member.type == "attribute" && member.isUnforgeable) { - var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"'); + var a_test = subsetTestByKey(this.name, 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"); @@ -2628,7 +2644,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect member.name && member.isUnforgeable) { - var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"'); + var a_test = subsetTestByKey(this.name, 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"); @@ -2648,7 +2664,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect { described_name += "(" + member.arguments.map(arg => arg.idlType.idlType).join(", ") + ")"; } - test(function() + subsetTestByKey(this.name, test, function() { assert_equals(exception, null, "Unexpected exception when evaluating object"); assert_equals(typeof obj, expected_typeof, "wrong typeof object"); @@ -2694,7 +2710,7 @@ 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) { - var a_test = async_test( this.name + " interface: calling " + member.name + + var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: calling " + member.name + "(" + member.arguments.map(function(m) { return m.idlType.idlType; }).join(", ") + ") on " + desc + " with too few arguments must throw TypeError"); a_test.step(function()