Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: roll WPT update for URL and harness #27822

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions test/common/wpt.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ class WPTRunner {
fetch(file) {
return resource.fetch(file);
},
location: {},
GLOBAL: {
isWindow() { return false; }
},
Expand Down Expand Up @@ -375,8 +374,6 @@ class WPTRunner {
// TODO(joyeecheung): we are not a window - work with the upstream to
// add a new scope for us.

const { Worker } = require('worker_threads');
sandbox.DedicatedWorker = Worker; // Pretend we are a Worker
return context;
}

Expand Down
4 changes: 2 additions & 2 deletions test/fixtures/wpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Last update:

- console: https://github.com/web-platform-tests/wpt/tree/9786a4b131/console
- encoding: https://github.com/web-platform-tests/wpt/tree/a093a659ed/encoding
- url: https://github.com/web-platform-tests/wpt/tree/75b0f336c5/url
- resources: https://github.com/web-platform-tests/wpt/tree/679a364421/resources
- url: https://github.com/web-platform-tests/wpt/tree/418f7fabeb/url
- resources: https://github.com/web-platform-tests/wpt/tree/e1fddfbf80/resources
- interfaces: https://github.com/web-platform-tests/wpt/tree/712c9f275e/interfaces
- html/webappapis/microtask-queuing: https://github.com/web-platform-tests/wpt/tree/0c3bed38df/html/webappapis/microtask-queuing
- html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/ddfe9c089b/html/webappapis/timers
Expand Down
210 changes: 152 additions & 58 deletions test/fixtures/wpt/resources/idlharness.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,29 @@ IdlArray.prototype.add_dependency_idls = function(raw_idls, options)
}.bind(this));

deps.forEach(function(name) {
new_options.only.push(name);
if (!new_options.only.includes(name)) {
new_options.only.push(name);
}

const follow_up = new Set();
for (const dep_type of ["inheritance", "implements", "includes"]) {
if (parsed[dep_type]) {
const inheriting = parsed[dep_type];
const inheritor = parsed.name || parsed.target;
const deps = [inheriting];
// For A includes B, we can ignore A unless B is being tested.
// For A includes B, we can ignore A, unless B (or some of its
// members) is being tested.
if (dep_type !== "includes"
|| (inheriting in this.members && !this.members[inheriting].untested)) {
|| inheriting in this.members && !this.members[inheriting].untested
|| this.partials.some(function(p) {
return p.name === inheriting;
})) {
deps.push(inheritor);
}
for (const dep of deps) {
new_options.only.push(dep);
if (!new_options.only.includes(dep)) {
new_options.only.push(dep);
}
all_deps.add(dep);
follow_up.add(dep);
}
Expand Down Expand Up @@ -718,9 +726,6 @@ function exposed_in(globals) {
self instanceof ServiceWorkerGlobalScope) {
return globals.has("ServiceWorker");
}
if ('NodeScope' in self) {
return true;
}
throw new IdlHarnessError("Unexpected global object");
}

Expand Down Expand Up @@ -1669,7 +1674,122 @@ IdlInterface.prototype.test_self = function()

}.bind(this), this.name + " interface: legacy window alias");
}
// TODO: Test named constructors if I find any interfaces that have them.

if (this.has_extended_attribute("NamedConstructor")) {
var constructors = this.extAttrs
.filter(function(attr) { return attr.name == "NamedConstructor"; });
if (constructors.length !== 1) {
throw new IdlHarnessError("Internal error: missing support for multiple NamedConstructor extended attributes");
}
var constructor = constructors[0];
var min_length = minOverloadLength([constructor]);

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "for every [NamedConstructor] extended attribute on an exposed
// interface, a corresponding property must exist on the ECMAScript
// global object. The name of the property is the
// [NamedConstructor]'s identifier, and its value is an object
// called a named constructor, ... . The property has the attributes
// { [[Writable]]: true, [[Enumerable]]: false,
// [[Configurable]]: true }."
var name = constructor.rhs.value;
assert_own_property(self, name);
var desc = Object.getOwnPropertyDescriptor(self, name);
assert_equals(desc.value, self[name], "wrong value in " + name + " property descriptor");
assert_true(desc.writable, name + " should be writable");
assert_false(desc.enumerable, name + " should not be enumerable");
assert_true(desc.configurable, name + " should be configurable");
assert_false("get" in desc, name + " should not have a getter");
assert_false("set" in desc, name + " should not have a setter");
}.bind(this), this.name + " interface: named constructor");

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "2. Let F be ! CreateBuiltinFunction(realm, steps,
// realm.[[Intrinsics]].[[%FunctionPrototype%]])."
var name = constructor.rhs.value;
var value = self[name];
assert_equals(typeof value, "function", "type of value in " + name + " property descriptor");
assert_not_equals(value, this.get_interface_object(), "wrong value in " + name + " property descriptor");
assert_equals(Object.getPrototypeOf(value), Function.prototype, "wrong value for " + name + "'s prototype");
}.bind(this), this.name + " interface: named constructor object");

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "7. Let proto be the interface prototype object of interface I
// in realm.
// "8. Perform ! DefinePropertyOrThrow(F, "prototype",
// PropertyDescriptor{
// [[Value]]: proto, [[Writable]]: false,
// [[Enumerable]]: false, [[Configurable]]: false
// })."
var name = constructor.rhs.value;
var expected = this.get_interface_object().prototype;
var desc = Object.getOwnPropertyDescriptor(self[name], "prototype");
assert_equals(desc.value, expected, "wrong value for " + name + ".prototype");
assert_false(desc.writable, "prototype should not be writable");
assert_false(desc.enumerable, "prototype should not be enumerable");
assert_false(desc.configurable, "prototype should not be configurable");
assert_false("get" in desc, "prototype should not have a getter");
assert_false("set" in desc, "prototype should not have a setter");
}.bind(this), this.name + " interface: named constructor prototype property");

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "3. Perform ! SetFunctionName(F, id)."
var name = constructor.rhs.value;
var desc = Object.getOwnPropertyDescriptor(self[name], "name");
assert_equals(desc.value, name, "wrong value for " + name + ".name");
assert_false(desc.writable, "name should not be writable");
assert_false(desc.enumerable, "name should not be enumerable");
assert_true(desc.configurable, "name should be configurable");
assert_false("get" in desc, "name should not have a getter");
assert_false("set" in desc, "name should not have a setter");
}.bind(this), this.name + " interface: named constructor name");

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "4. Initialize S to the effective overload set for constructors
// with identifier id on interface I and with argument count 0.
// "5. Let length be the length of the shortest argument list of
// the entries in S.
// "6. Perform ! SetFunctionLength(F, length)."
var name = constructor.rhs.value;
var desc = Object.getOwnPropertyDescriptor(self[name], "length");
assert_equals(desc.value, min_length, "wrong value for " + name + ".length");
assert_false(desc.writable, "length should not be writable");
assert_false(desc.enumerable, "length should not be enumerable");
assert_true(desc.configurable, "length should be configurable");
assert_false("get" in desc, "length should not have a getter");
assert_false("set" in desc, "length should not have a setter");
}.bind(this), this.name + " interface: named constructor length");

subsetTestByKey(this.name, test, function()
{
// This function tests WebIDL as of 2019-01-14.

// "1. Let steps be the following steps:
// " 1. If NewTarget is undefined, then throw a TypeError."
var name = constructor.rhs.value;
var args = constructor.arguments.map(function(arg) {
return create_suitable_object(arg.idlType);
});
assert_throws(new TypeError(), function() {
self[name](...args);
}.bind(this));
}.bind(this), this.name + " interface: named constructor without 'new'");
}

subsetTestByKey(this.name, test, function()
{
Expand Down Expand Up @@ -2304,22 +2424,7 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
}
}

IdlInterface.prototype.add_iterable_members = function(member)
{
this.members.push(new IdlInterfaceMember(
{ type: "operation", name: "entries", idlType: "iterator", arguments: []}));
this.members.push(new IdlInterfaceMember(
{ type: "operation", name: "keys", idlType: "iterator", arguments: []}));
this.members.push(new IdlInterfaceMember(
{ type: "operation", name: "values", idlType: "iterator", arguments: []}));
this.members.push(new IdlInterfaceMember(
{ type: "operation", name: "forEach", idlType: "void",
arguments:
[{ name: "callback", idlType: {idlType: "function"}},
{ name: "thisValue", idlType: {idlType: "any"}, optional: true}]}));
};

IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, member) {
IdlInterface.prototype.test_to_json_operation = function(desc, memberHolderObject, member) {
var instanceName = memberHolderObject && memberHolderObject.constructor.name
|| member.name + " object";
if (member.has_extended_attribute("Default")) {
Expand All @@ -2335,38 +2440,40 @@ IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, mem
this.array.assert_type_is(json[k], type);
delete json[k];
}, this);
}.bind(this), "Test default toJSON operation of " + instanceName);
}.bind(this), this.name + " interface: default toJSON operation on " + desc);
} else {
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);
}.bind(this), this.name + " interface: toJSON operation on " + desc);
}
};

IdlInterface.prototype.test_member_iterable = function(member)
{
var isPairIterator = member.idlType.length === 2;
subsetTestByKey(this.name, test, function()
{
var descriptor = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.iterator);
assert_true(descriptor.writable, "property should be writable");
assert_true(descriptor.configurable, "property should be configurable");
assert_false(descriptor.enumerable, "property should not be enumerable");
assert_equals(this.get_interface_object().prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name");
}.bind(this), "Testing Symbol.iterator property of iterable interface " + this.name);

if (isPairIterator) {
subsetTestByKey(this.name, test, function() {
assert_equals(this.get_interface_object().prototype[Symbol.iterator], this.get_interface_object().prototype["entries"], "entries method is not the same as @@iterator");
}.bind(this), "Testing pair iterable interface " + this.name);
} else {
subsetTestByKey(this.name, test, function() {
["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) {
assert_equals(this.get_interface_object().prototype[property], Array.prototype[property], property + " function is not the same as Array one");
var isPairIterator = member.idlType.length === 2;
var proto = this.get_interface_object().prototype;
var descriptor = Object.getOwnPropertyDescriptor(proto, Symbol.iterator);

assert_true(descriptor.writable, "@@iterator property should be writable");
assert_true(descriptor.configurable, "@@iterator property should be configurable");
assert_false(descriptor.enumerable, "@@iterator property should not be enumerable");
assert_equals(typeof descriptor.value, "function", "@@iterator property should be a function");
assert_equals(descriptor.value.length, 0, "@@iterator function object length should be 0");
assert_equals(descriptor.value.name, isPairIterator ? "entries" : "values", "@@iterator function object should have the right name");

if (isPairIterator) {
assert_equals(proto["entries"], proto[Symbol.iterator], "entries method should be the same as @@iterator method");
} else {
assert_equals(proto[Symbol.iterator], Array.prototype[Symbol.iterator], "@@iterator method should be the same as Array prototype's");
["entries", "keys", "values", "forEach", Symbol.iterator].forEach(function(property) {
var propertyName = property === Symbol.iterator ? "@@iterator" : property;
assert_equals(proto[property], Array.prototype[property], propertyName + " method should be the same as Array prototype's");
}.bind(this));
}.bind(this), "Testing value iterable interface " + this.name);
}
}
}.bind(this), this.name + " interface: iterable<" + member.idlType.map(function(t) { return t.idlType; }).join(", ") + ">");
};

IdlInterface.prototype.test_member_stringifier = function(member)
Expand Down Expand Up @@ -2432,19 +2539,6 @@ IdlInterface.prototype.test_member_stringifier = function(member)

IdlInterface.prototype.test_members = function()
{
for (var i = 0; i < this.members.length; i++)
{
var member = this.members[i];
switch (member.type) {
case "iterable":
this.add_iterable_members(member);
break;
// TODO: add setlike and maplike handling.
default:
break;
}
}

for (var i = 0; i < this.members.length; i++)
{
var member = this.members[i];
Expand Down Expand Up @@ -2743,7 +2837,7 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect
}

if (member.is_to_json_regular_operation()) {
this.test_to_json_operation(obj, member);
this.test_to_json_operation(desc, obj, member);
}
}
};
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/wpt/resources/sriharness.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,4 @@ SRIStyleTest.prototype.execute = function() {
container.appendChild(e);
this.customCallback(e, container);
};

24 changes: 16 additions & 8 deletions test/fixtures/wpt/resources/testdriver-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
function Actions() {
this.sourceTypes = new Map([["key", KeySource],
["pointer", PointerSource],
["general", GeneralSource]]);
["none", GeneralSource]]);
this.sources = new Map();
this.sourceOrder = [];
for (let sourceType of this.sourceTypes.keys()) {
Expand All @@ -17,11 +17,19 @@
for (let sourceType of this.sourceTypes.keys()) {
this.currentSources.set(sourceType, null);
}
this.createSource("general");
this.createSource("none");
this.tickIdx = 0;
}

Actions.prototype = {
ButtonType: {
LEFT: 0,
MIDDLE: 1,
RIGHT: 2,
BACK: 3,
FORWARD: 4,
},

/**
* Generate the action sequence suitable for passing to
* test_driver.action_sequence
Expand Down Expand Up @@ -62,7 +70,7 @@
* If no name is passed, a new source with the given type is
* created.
*
* @param {String} type - Source type ('general', 'key', or 'pointer')
* @param {String} type - Source type ('none', 'key', or 'pointer')
* @param {String?} name - Name of the source
* @returns {Source} Source object for that source.
*/
Expand Down Expand Up @@ -98,7 +106,7 @@
* @returns {Actions}
*/
addKeyboard: function(name, set=true) {
this.createSource("key", name, true);
this.createSource("key", name);
if (set) {
this.setKeyboard(name);
}
Expand All @@ -125,7 +133,7 @@
* @returns {Actions}
*/
addPointer: function(name, pointerType="mouse", set=true) {
this.createSource("pointer", name, true, {pointerType: pointerType});
this.createSource("pointer", name, {pointerType: pointerType});
if (set) {
this.setPointer(name);
}
Expand Down Expand Up @@ -187,7 +195,7 @@
* @returns {Actions}
*/
pause: function(duration) {
this.getSource("general").addPause(this, duration);
this.getSource("none").addPause(this, duration);
return this;
},

Expand Down Expand Up @@ -225,7 +233,7 @@
* pointer source
* @returns {Actions}
*/
pointerDown: function({button=0, sourceName=null}={}) {
pointerDown: function({button=this.ButtonType.LEFT, sourceName=null}={}) {
let source = this.getSource("pointer", sourceName);
source.pointerDown(this, button);
return this;
Expand All @@ -239,7 +247,7 @@
* source
* @returns {Actions}
*/
pointerUp: function({button=0, sourceName=null}={}) {
pointerUp: function({button=this.ButtonType.LEFT, sourceName=null}={}) {
let source = this.getSource("pointer", sourceName);
source.pointerUp(this, button);
return this;
Expand Down
Loading