Bug 1473360 [wpt PR 11776] - Handle (+ test) 'namespace' in idlharness, a=testonly

Automatic update from web-platform-testsHandle (+ test) 'namespace' in idlharness (#11776)

--

wpt-commits: 4bb0586b21c65abfcf78afad408d7e2a04ab6bd0
wpt-pr: 11776
This commit is contained in:
Luke Bjerring 2018-07-25 17:37:33 +00:00 committed by James Graham
parent 7df0d370e8
commit 84c6bf5ad5
4 changed files with 417 additions and 11 deletions

View File

@ -70,6 +70,11 @@ function constValue (cnt)
function minOverloadLength(overloads)
//@{
{
// "The value of the Function objects “length” property is
// a Number determined as follows:
// ". . .
// "Return the length of the shortest argument list of the
// entries in S."
if (!overloads.length) {
return 0;
}
@ -365,7 +370,8 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options)
parsed_idls.forEach(function(parsed_idl)
{
if (parsed_idl.partial && ["interface", "dictionary"].includes(parsed_idl.type))
if (parsed_idl.partial
&& ["interface", "dictionary", "namespace"].includes(parsed_idl.type))
{
if (should_skip(parsed_idl.name))
{
@ -459,6 +465,10 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls, options)
new IdlInterface(parsed_idl, /* is_callback = */ true, /* is_mixin = */ false);
break;
case "namespace":
this.members[parsed_idl.name] = new IdlNamespace(parsed_idl);
break;
default:
throw parsed_idl.name + ": " + parsed_idl.type + " not yet supported";
}
@ -845,7 +855,8 @@ IdlArray.prototype.collapse_partials = function()
{
const originalExists = parsed_idl.name in this.members
&& (this.members[parsed_idl.name] instanceof IdlInterface
|| this.members[parsed_idl.name] instanceof IdlDictionary);
|| this.members[parsed_idl.name] instanceof IdlDictionary
|| this.members[parsed_idl.name] instanceof IdlNamespace);
let partialTestName = parsed_idl.name;
if (!parsed_idl.untested) {
@ -2254,15 +2265,13 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
// behavior is as follows . . ."
assert_equals(typeof memberHolderObject[member.name], "function",
"property must be a function");
// "The value of the Function objects “length” property is
// a Number determined as follows:
// ". . .
// "Return the length of the shortest argument list of the
// entries in S."
assert_equals(memberHolderObject[member.name].length,
minOverloadLength(this.members.filter(function(m) {
return m.type == "operation" && m.name == member.name;
})),
const ctors = this.members.filter(function(m) {
return m.type == "operation" && m.name == member.name;
});
assert_equals(
memberHolderObject[member.name].length,
minOverloadLength(ctors),
"property has wrong .length");
// Make some suitable arguments
@ -3011,6 +3020,136 @@ function IdlTypedef(obj)
IdlTypedef.prototype = Object.create(IdlObject.prototype);
/// IdlNamespace ///
function IdlNamespace(obj)
//@{
{
this.name = obj.name;
this.extAttrs = obj.extAttrs;
this.untested = obj.untested;
/** A back-reference to our IdlArray. */
this.array = obj.array;
/** An array of IdlInterfaceMembers. */
this.members = obj.members.map(m => new IdlInterfaceMember(m));
}
//@}
IdlNamespace.prototype = Object.create(IdlObject.prototype);
IdlNamespace.prototype.do_member_operation_asserts = function (memberHolderObject, member, a_test)
//@{
{
var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);
assert_false("get" in desc, "property should not have a getter");
assert_false("set" in desc, "property should not have a setter");
assert_equals(
desc.writable,
!member.isUnforgeable,
"property should be writable if and only if not unforgeable");
assert_true(desc.enumerable, "property should be enumerable");
assert_equals(
desc.configurable,
!member.isUnforgeable,
"property should be configurable if and only if not unforgeable");
assert_equals(
typeof memberHolderObject[member.name],
"function",
"property must be a function");
assert_equals(
memberHolderObject[member.name].length,
minOverloadLength(this.members.filter(function(m) {
return m.type == "operation" && m.name == member.name;
})),
"operation has wrong .length");
a_test.done();
}
//@}
IdlNamespace.prototype.test_member_operation = function(member)
//@{
{
if (!shouldRunSubTest(this.name)) {
return;
}
var args = member.arguments.map(function(a) {
var s = a.idlType.idlType;
if (a.variadic) {
s += '...';
}
return s;
}).join(", ");
var a_test = subsetTestByKey(
this.name,
async_test,
this.name + ' namespace: operation ' + member.name + '(' + args + ')');
a_test.step(function() {
assert_own_property(
self[this.name],
member.name,
'namespace object missing operation ' + format_value(member.name));
this.do_member_operation_asserts(self[this.name], member, a_test);
}.bind(this));
};
//@}
IdlNamespace.prototype.test_member_attribute = function (member)
//@{
{
if (!shouldRunSubTest(this.name)) {
return;
}
var a_test = subsetTestByKey(
this.name,
async_test,
this.name + ' namespace: attribute ' + member.name);
a_test.step(function()
{
assert_own_property(
self[this.name],
member.name,
this.name + ' does not have property ' + format_value(member.name));
var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);
assert_equals(desc.set, undefined, "setter must be undefined for namespace members");
a_test.done();
}.bind(this));
};
//@}
IdlNamespace.prototype.test = function ()
//@{
{
/**
* TODO(lukebjerring): Assert:
* - "Note that unlike interfaces or dictionaries, namespaces do not create types."
* - "Of the extended attributes defined in this specification, only the
* [Exposed] and [SecureContext] extended attributes are applicable to namespaces."
* - "Namespaces must be annotated with the [Exposed] extended attribute."
*/
for (const v of Object.values(this.members)) {
switch (v.type) {
case 'operation':
this.test_member_operation(v);
break;
case 'attribute':
this.test_member_attribute(v);
break;
default:
throw 'Invalid namespace member ' + v.name + ': ' + v.type + ' not supported';
}
};
};
//@}
}());
/**

View File

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="variant" content="">
<meta name="variant" content="?keep-promise">
<title>idlharness: namespace attribute</title>
<script src="../../../../variants.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
</head>
<body>
<p>Verify the series of sub-tests that are executed for namespace attributes.</p>
<script>
"use strict";
self.foo = {
truth: true
};
var idlArray = new IdlArray();
idlArray.add_idls(
`namespace foo {
readonly attribute bool truth;
readonly attribute bool lies;
};`);
idlArray.test();
</script>
<script type="text/json" id="expected">
{
"summarized_status": {
"status_string": "OK",
"message": null
},
"summarized_tests": [
{
"name": "foo namespace: attribute truth",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "foo namespace: attribute lies",
"status_string": "FAIL",
"properties": {},
"message": "assert_own_property: foo does not have property \"lies\" expected property \"lies\" missing"
}
],
"type": "complete"
}
</script>
</body>
</html>

View File

@ -0,0 +1,99 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="variant" content="">
<meta name="variant" content="?keep-promise">
<title>idlharness: namespace operation</title>
<script src="../../../../variants.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
</head>
<body>
<p>Verify the series of sub-tests that are executed for namespace operations.</p>
<script>
"use strict";
self.foo = {
Truth: function() {},
};
Object.defineProperty(self.foo, "Truth", { writable: true });
self.bar = {
Truth: function() {},
}
Object.defineProperty(self.bar, "Truth", {
writable: false,
configurable: false,
});
self.baz = {
LongStory: function(hero, ...details) {
return `${hero} went and ${details.join(', then')}`
},
ShortStory: function(...details) {
return `${details.join('. ')}`;
},
};
var idlArray = new IdlArray();
idlArray.add_idls(
`namespace foo {
void Truth();
void Lies();
};
namespace bar {
[Unforgeable]
void Truth();
};
namespace baz {
DOMString LongStory(any hero, DOMString... details);
DOMString ShortStory(DOMString... details);
};`);
idlArray.test();
</script>
<script type="text/json" id="expected">
{
"summarized_status": {
"status_string": "OK",
"message": null
},
"summarized_tests": [
{
"name": "bar namespace: operation Truth()",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "baz namespace: operation LongStory(any, DOMString...)",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "baz namespace: operation ShortStory(DOMString...)",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "foo namespace: operation Truth()",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "foo namespace: operation Lies()",
"status_string": "FAIL",
"properties": {},
"message": "assert_own_property: namespace object missing operation \"Lies\" expected property \"Lies\" missing"
}
],
"type": "complete"
}
</script>
</body>
</html>

View File

@ -0,0 +1,113 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="variant" content="">
<meta name="variant" content="?keep-promise">
<title>idlharness: Partial namespace</title>
<script src="/resources/test/variants.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
</head>
<body>
<p>Verify the series of sub-tests that are executed for "partial" namespace objects.</p>
<script>
"use strict";
// No original existence
(() => {
const idlArray = new IdlArray();
idlArray.add_idls('partial namespace A {};');
idlArray.test();
})();
// Valid exposure (Note: Worker -> {Shared,Dedicated,Service}Worker)
(() => {
const idlArray = new IdlArray();
idlArray.add_untested_idls(`
[Exposed=(Worker)]
namespace B {};
[Exposed=(DedicatedWorker, ServiceWorker, SharedWorker)]
namespace C {};`);
idlArray.add_idls(`
[Exposed=(DedicatedWorker, ServiceWorker, SharedWorker)]
partial namespace B {};
[Exposed=(Worker)]
partial namespace C {};`);
idlArray.collapse_partials();
})();
// Invalid exposure
(() => {
const idlArray = new IdlArray();
idlArray.add_untested_idls(`
[Exposed=(Window, ServiceWorker)]
namespace D {};`);
idlArray.add_idls(`
[Exposed=(DedicatedWorker)]
partial namespace D {};`);
idlArray.collapse_partials();
})();
</script>
<script type="text/json" id="expected">
{
"summarized_status": {
"status_string": "OK",
"message": null
},
"summarized_tests": [
{
"name": "Partial namespace A: original namespace defined",
"status_string": "FAIL",
"properties": {},
"message": "assert_true: Original namespace should be defined expected true got false"
},
{
"name": "Partial namespace B: original namespace defined",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "Partial namespace B: valid exposure set",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "Partial namespace C: original namespace defined",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "Partial namespace C: valid exposure set",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "Partial namespace D: original namespace defined",
"status_string": "PASS",
"properties": {},
"message": null
},
{
"name": "Partial namespace D: valid exposure set",
"status_string": "FAIL",
"properties": {},
"message": "Partial D namespace is exposed to 'DedicatedWorker', the original namespace is not."
}
],
"type": "complete"
}
</script>
</body>
</html>