How to use dep_chain method in wpt

Best JavaScript code snippet using wpt

idlharness.js

Source:idlharness.js Github

copy

Full Screen

1/*2Distributed under both the W3C Test Suite License [1] and the W3C33-clause BSD License [2]. To contribute to a W3C Test Suite, see the4policies and contribution forms [3].5[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license6[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license7[3] http://www.w3.org/2004/10/27-testcases8*/9/* For user documentation see docs/_writing-tests/idlharness.md */10/**11 * Notes for people who want to edit this file (not just use it as a library):12 *13 * Most of the interesting stuff happens in the derived classes of IdlObject,14 * especially IdlInterface. The entry point for all IdlObjects is .test(),15 * which is called by IdlArray.test(). An IdlObject is conceptually just16 * "thing we want to run tests on", and an IdlArray is an array of IdlObjects17 * with some additional data thrown in.18 *19 * The object model is based on what WebIDLParser.js produces, which is in turn20 * based on its pegjs grammar. If you want to figure out what properties an21 * object will have from WebIDLParser.js, the best way is to look at the22 * grammar:23 *24 * https://github.com/darobin/webidl.js/blob/master/lib/grammar.peg25 *26 * So for instance:27 *28 * // interface definition29 * interface30 * = extAttrs:extendedAttributeList? S? "interface" S name:identifier w herit:ifInheritance? w "{" w mem:ifMember* w "}" w ";" w31 * { return { type: "interface", name: name, inheritance: herit, members: mem, extAttrs: extAttrs }; }32 *33 * This means that an "interface" object will have a .type property equal to34 * the string "interface", a .name property equal to the identifier that the35 * parser found, an .inheritance property equal to either null or the result of36 * the "ifInheritance" production found elsewhere in the grammar, and so on.37 * After each grammatical production is a JavaScript function in curly braces38 * that gets called with suitable arguments and returns some JavaScript value.39 *40 * (Note that the version of WebIDLParser.js we use might sometimes be41 * out-of-date or forked.)42 *43 * The members and methods of the classes defined by this file are all at least44 * briefly documented, hopefully.45 */46(function(){47"use strict";48/// Helpers ///49function constValue (cnt)50//@{51{52 if (cnt.type === "null") return null;53 if (cnt.type === "NaN") return NaN;54 if (cnt.type === "Infinity") return cnt.negative ? -Infinity : Infinity;55 if (cnt.type === "number") return +cnt.value;56 return cnt.value;57}58//@}59function minOverloadLength(overloads)60//@{61{62 if (!overloads.length) {63 return 0;64 }65 return overloads.map(function(attr) {66 return attr.arguments ? attr.arguments.filter(function(arg) {67 return !arg.optional && !arg.variadic;68 }).length : 0;69 })70 .reduce(function(m, n) { return Math.min(m, n); });71}72//@}73function throwOrReject(a_test, operation, fn, obj, args, message, cb)74//@{75{76 if (operation.idlType.generic !== "Promise") {77 assert_throws(new TypeError(), function() {78 fn.apply(obj, args);79 }, message);80 cb();81 } else {82 try {83 promise_rejects(a_test, new TypeError(), fn.apply(obj, args), message).then(cb, cb);84 } catch (e){85 a_test.step(function() {86 assert_unreached("Throws \"" + e + "\" instead of rejecting promise");87 cb();88 });89 }90 }91}92//@}93function awaitNCallbacks(n, cb, ctx)94//@{95{96 var counter = 0;97 return function() {98 counter++;99 if (counter >= n) {100 cb();101 }102 };103}104//@}105var fround =106//@{107(function(){108 if (Math.fround) return Math.fround;109 var arr = new Float32Array(1);110 return function fround(n) {111 arr[0] = n;112 return arr[0];113 };114})();115//@}116/// IdlHarnessError ///117// Entry point118self.IdlHarnessError = function(message)119//@{120{121 /**122 * Message to be printed as the error's toString invocation.123 */124 this.message = message;125};126IdlHarnessError.prototype = Object.create(Error.prototype);127//@}128IdlHarnessError.prototype.toString = function()129//@{130{131 return this.message;132};133//@}134/// IdlArray ///135// Entry point136self.IdlArray = function()137//@{138{139 /**140 * A map from strings to the corresponding named IdlObject, such as141 * IdlInterface or IdlException. These are the things that test() will run142 * tests on.143 */144 this.members = {};145 /**146 * A map from strings to arrays of strings. The keys are interface or147 * exception names, and are expected to also exist as keys in this.members148 * (otherwise they'll be ignored). This is populated by add_objects() --149 * see documentation at the start of the file. The actual tests will be150 * run by calling this.members[name].test_object(obj) for each obj in151 * this.objects[name]. obj is a string that will be eval'd to produce a152 * JavaScript value, which is supposed to be an object implementing the153 * given IdlObject (interface, exception, etc.).154 */155 this.objects = {};156 /**157 * When adding multiple collections of IDLs one at a time, an earlier one158 * might contain a partial interface or implements statement that depends159 * on a later one. Save these up and handle them right before we run160 * tests.161 *162 * .partials is simply an array of objects from WebIDLParser.js'163 * "partialinterface" production. .implements maps strings to arrays of164 * strings, such that165 *166 * A implements B;167 * A implements C;168 * D implements E;169 *170 * results in { A: ["B", "C"], D: ["E"] }.171 */172 this.partials = [];173 this["implements"] = {};174 this["includes"] = {};175};176//@}177IdlArray.prototype.add_idls = function(raw_idls, options)178//@{179{180 /** Entry point. See documentation at beginning of file. */181 this.internal_add_idls(WebIDL2.parse(raw_idls), options);182};183//@}184IdlArray.prototype.add_untested_idls = function(raw_idls, options)185//@{186{187 /** Entry point. See documentation at beginning of file. */188 var parsed_idls = WebIDL2.parse(raw_idls);189 for (var i = 0; i < parsed_idls.length; i++)190 {191 parsed_idls[i].untested = true;192 if ("members" in parsed_idls[i])193 {194 for (var j = 0; j < parsed_idls[i].members.length; j++)195 {196 parsed_idls[i].members[j].untested = true;197 }198 }199 }200 this.internal_add_idls(parsed_idls, options);201};202//@}203IdlArray.prototype.internal_add_idls = function(parsed_idls, options)204//@{205{206 /**207 * Internal helper called by add_idls() and add_untested_idls().208 *209 * parsed_idls is an array of objects that come from WebIDLParser.js's210 * "definitions" production. The add_untested_idls() entry point211 * additionally sets an .untested property on each object (and its212 * .members) so that they'll be skipped by test() -- they'll only be213 * used for base interfaces of tested interfaces, return types, etc.214 *215 * options is a dictionary that can have an only or except member which are216 * arrays. If only is given then only members, partials and interface217 * targets listed will be added, and if except is given only those that218 * aren't listed will be added. Only one of only and except can be used.219 */220 if (options && options.only && options.except)221 {222 throw new IdlHarnessError("The only and except options can't be used together.");223 }224 function should_skip(name)225 {226 if (options && options.only && options.only.indexOf(name) == -1)227 {228 return true;229 }230 if (options && options.except && options.except.indexOf(name) != -1)231 {232 return true;233 }234 return false;235 }236 parsed_idls.forEach(function(parsed_idl)237 {238 if (parsed_idl.partial && ["interface", "dictionary"].includes(parsed_idl.type))239 {240 if (should_skip(parsed_idl.name))241 {242 return;243 }244 this.partials.push(parsed_idl);245 return;246 }247 if (parsed_idl.type == "implements")248 {249 if (should_skip(parsed_idl.target))250 {251 return;252 }253 if (!(parsed_idl.target in this["implements"]))254 {255 this["implements"][parsed_idl.target] = [];256 }257 this["implements"][parsed_idl.target].push(parsed_idl["implements"]);258 return;259 }260 if (parsed_idl.type == "includes")261 {262 if (should_skip(parsed_idl.target))263 {264 return;265 }266 if (!(parsed_idl.target in this["includes"]))267 {268 this["includes"][parsed_idl.target] = [];269 }270 this["includes"][parsed_idl.target].push(parsed_idl["includes"]);271 return;272 }273 parsed_idl.array = this;274 if (should_skip(parsed_idl.name))275 {276 return;277 }278 if (parsed_idl.name in this.members)279 {280 throw new IdlHarnessError("Duplicate identifier " + parsed_idl.name);281 }282 switch(parsed_idl.type)283 {284 case "interface":285 this.members[parsed_idl.name] =286 new IdlInterface(parsed_idl, /* is_callback = */ false, /* is_mixin = */ false);287 break;288 case "interface mixin":289 this.members[parsed_idl.name] =290 new IdlInterface(parsed_idl, /* is_callback = */ false, /* is_mixin = */ true);291 break;292 case "dictionary":293 // Nothing to test, but we need the dictionary info around for type294 // checks295 this.members[parsed_idl.name] = new IdlDictionary(parsed_idl);296 break;297 case "typedef":298 this.members[parsed_idl.name] = new IdlTypedef(parsed_idl);299 break;300 case "callback":301 // TODO302 console.log("callback not yet supported");303 break;304 case "enum":305 this.members[parsed_idl.name] = new IdlEnum(parsed_idl);306 break;307 case "callback interface":308 this.members[parsed_idl.name] =309 new IdlInterface(parsed_idl, /* is_callback = */ true, /* is_mixin = */ false);310 break;311 default:312 throw parsed_idl.name + ": " + parsed_idl.type + " not yet supported";313 }314 }.bind(this));315};316//@}317IdlArray.prototype.add_objects = function(dict)318//@{319{320 /** Entry point. See documentation at beginning of file. */321 for (var k in dict)322 {323 if (k in this.objects)324 {325 this.objects[k] = this.objects[k].concat(dict[k]);326 }327 else328 {329 this.objects[k] = dict[k];330 }331 }332};333//@}334IdlArray.prototype.prevent_multiple_testing = function(name)335//@{336{337 /** Entry point. See documentation at beginning of file. */338 this.members[name].prevent_multiple_testing = true;339};340//@}341IdlArray.prototype.recursively_get_implements = function(interface_name)342//@{343{344 /**345 * Helper function for test(). Returns an array of things that implement346 * interface_name, so if the IDL contains347 *348 * A implements B;349 * B implements C;350 * B implements D;351 *352 * then recursively_get_implements("A") should return ["B", "C", "D"].353 */354 var ret = this["implements"][interface_name];355 if (ret === undefined)356 {357 return [];358 }359 for (var i = 0; i < this["implements"][interface_name].length; i++)360 {361 ret = ret.concat(this.recursively_get_implements(ret[i]));362 if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i]))363 {364 throw new IdlHarnessError("Circular implements statements involving " + ret[i]);365 }366 }367 return ret;368};369//@}370IdlArray.prototype.recursively_get_includes = function(interface_name)371//@{372{373 /**374 * Helper function for test(). Returns an array of things that implement375 * interface_name, so if the IDL contains376 *377 * A includes B;378 * B includes C;379 * B includes D;380 *381 * then recursively_get_includes("A") should return ["B", "C", "D"].382 */383 var ret = this["includes"][interface_name];384 if (ret === undefined)385 {386 return [];387 }388 for (var i = 0; i < this["includes"][interface_name].length; i++)389 {390 ret = ret.concat(this.recursively_get_includes(ret[i]));391 if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i]))392 {393 throw new IdlHarnessError("Circular includes statements involving " + ret[i]);394 }395 }396 return ret;397};398//@}399IdlArray.prototype.is_json_type = function(type)400//@{401{402 /**403 * Checks whether type is a JSON type as per404 * https://heycam.github.io/webidl/#dfn-json-types405 */406 var idlType = type.idlType;407 if (type.generic == "Promise") { return false; }408 // nullable and annotated types don't need to be handled separately,409 // as webidl2 doesn't represent them wrapped-up (as they're described410 // in WebIDL).411 // union and record types412 if (type.union || type.generic == "record") {413 return idlType.every(this.is_json_type, this);414 }415 // sequence types416 if (type.generic == "sequence" || type.generic == "FrozenArray") {417 return this.is_json_type(idlType);418 }419 if (typeof idlType != "string") { throw new Error("Unexpected type " + JSON.stringify(idlType)); }420 switch (idlType)421 {422 // Numeric types423 case "byte":424 case "octet":425 case "short":426 case "unsigned short":427 case "long":428 case "unsigned long":429 case "long long":430 case "unsigned long long":431 case "float":432 case "double":433 case "unrestricted float":434 case "unrestricted double":435 // boolean436 case "boolean":437 // string types438 case "DOMString":439 case "ByteString":440 case "USVString":441 // object type442 case "object":443 return true;444 case "Error":445 case "DOMException":446 case "Int8Array":447 case "Int16Array":448 case "Int32Array":449 case "Uint8Array":450 case "Uint16Array":451 case "Uint32Array":452 case "Uint8ClampedArray":453 case "Float32Array":454 case "ArrayBuffer":455 case "DataView":456 case "any":457 return false;458 default:459 var thing = this.members[idlType];460 if (!thing) { throw new Error("Type " + idlType + " not found"); }461 if (thing instanceof IdlEnum) { return true; }462 if (thing instanceof IdlTypedef) {463 return this.is_json_type(thing.idlType);464 }465 // dictionaries where all of their members are JSON types466 if (thing instanceof IdlDictionary) {467 var stack = thing.get_inheritance_stack();468 var map = new Map();469 while (stack.length)470 {471 stack.pop().members.forEach(function(m) {472 map.set(m.name, m.idlType)473 });474 }475 return Array.from(map.values()).every(this.is_json_type, this);476 }477 // interface types that have a toJSON operation declared on themselves or478 // one of their inherited or consequential interfaces.479 if (thing instanceof IdlInterface) {480 var base;481 while (thing)482 {483 if (thing.has_to_json_regular_operation()) { return true; }484 var mixins = this.implements[thing.name] || this.includes[thing.name];485 if (mixins) {486 mixins = mixins.map(function(id) {487 var mixin = this.members[id];488 if (!mixin) {489 throw new Error("Interface " + id + " not found (implemented by " + thing.name + ")");490 }491 return mixin;492 }, this);493 if (mixins.some(function(m) { return m.has_to_json_regular_operation() } )) { return true; }494 }495 if (!thing.base) { return false; }496 base = this.members[thing.base];497 if (!base) {498 throw new Error("Interface " + thing.base + " not found (inherited by " + thing.name + ")");499 }500 thing = base;501 }502 return false;503 }504 return false;505 }506};507function exposure_set(object, default_set) {508 var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed" });509 if (exposed.length > 1) {510 throw new IdlHarnessError(511 `Multiple 'Exposed' extended attributes on ${object.name}`);512 }513 if (exposed.length === 0) {514 return default_set;515 }516 var set = exposed[0].rhs.value;517 // Could be a list or a string.518 if (typeof set == "string") {519 set = [ set ];520 }521 return set;522}523function exposed_in(globals) {524 if ('document' in self) {525 return globals.indexOf("Window") >= 0;526 }527 if ('DedicatedWorkerGlobalScope' in self &&528 self instanceof DedicatedWorkerGlobalScope) {529 return globals.indexOf("Worker") >= 0 ||530 globals.indexOf("DedicatedWorker") >= 0;531 }532 if ('SharedWorkerGlobalScope' in self &&533 self instanceof SharedWorkerGlobalScope) {534 return globals.indexOf("Worker") >= 0 ||535 globals.indexOf("SharedWorker") >= 0;536 }537 if ('ServiceWorkerGlobalScope' in self &&538 self instanceof ServiceWorkerGlobalScope) {539 return globals.indexOf("Worker") >= 0 ||540 globals.indexOf("ServiceWorker") >= 0;541 }542 throw new IdlHarnessError("Unexpected global object");543}544//@}545/**546 * Asserts that the given error message is thrown for the given function.547 * @param {string|IdlHarnessError} error Expected Error message.548 * @param {Function} idlArrayFunc Function operating on an IdlArray that should throw.549 */550IdlArray.prototype.assert_throws = function(error, idlArrayFunc)551//@{552{553 try {554 idlArrayFunc.call(this, this);555 } catch (e) {556 if (e instanceof AssertionError) {557 throw e;558 }559 // Assertions for behaviour of the idlharness.js engine.560 if (error instanceof IdlHarnessError) {561 error = error.message;562 }563 if (e.message !== error) {564 throw new IdlHarnessError(`${idlArrayFunc} threw "${e}", not the expected IdlHarnessError "${error}"`);565 }566 return;567 }568 throw new IdlHarnessError(`${idlArrayFunc} did not throw the expected IdlHarnessError`);569}570//@}571IdlArray.prototype.test = function()572//@{573{574 /** Entry point. See documentation at beginning of file. */575 // First merge in all the partial interfaces and implements statements we576 // encountered.577 this.partials.forEach(function(parsed_idl)578 {579 if (!(parsed_idl.name in this.members)580 || !(this.members[parsed_idl.name] instanceof IdlInterface581 || this.members[parsed_idl.name] instanceof IdlDictionary))582 {583 throw new IdlHarnessError(`Partial ${parsed_idl.type} ${parsed_idl.name} with no original ${parsed_idl.type}`);584 }585 if (parsed_idl.extAttrs)586 {587 parsed_idl.extAttrs.forEach(function(extAttr)588 {589 this.members[parsed_idl.name].extAttrs.push(extAttr);590 }.bind(this));591 }592 parsed_idl.members.forEach(function(member)593 {594 this.members[parsed_idl.name].members.push(new IdlInterfaceMember(member));595 }.bind(this));596 }.bind(this));597 this.partials = [];598 for (var lhs in this["implements"])599 {600 this.recursively_get_implements(lhs).forEach(function(rhs)601 {602 var errStr = lhs + " implements " + rhs + ", but ";603 if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";604 if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";605 if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";606 if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";607 this.members[rhs].members.forEach(function(member)608 {609 this.members[lhs].members.push(new IdlInterfaceMember(member));610 }.bind(this));611 }.bind(this));612 }613 this["implements"] = {};614 for (var lhs in this["includes"])615 {616 this.recursively_get_includes(lhs).forEach(function(rhs)617 {618 var errStr = lhs + " includes " + rhs + ", but ";619 if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";620 if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";621 if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";622 if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";623 this.members[rhs].members.forEach(function(member)624 {625 this.members[lhs].members.push(new IdlInterfaceMember(member));626 }.bind(this));627 }.bind(this));628 }629 this["includes"] = {};630 // Assert B defined for A : B631 for (var member of Object.values(this.members).filter(m => m.base)) {632 const lhs = member.name;633 const rhs = member.base;634 if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`);635 const lhs_is_interface = this.members[lhs] instanceof IdlInterface;636 const rhs_is_interface = this.members[rhs] instanceof IdlInterface;637 if (rhs_is_interface != lhs_is_interface) {638 if (!lhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${lhs} is not an interface.`);639 if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`);640 }641 // Check for circular dependencies.642 member.get_inheritance_stack();643 }644 Object.getOwnPropertyNames(this.members).forEach(function(memberName) {645 var member = this.members[memberName];646 if (!(member instanceof IdlInterface)) {647 return;648 }649 var globals = exposure_set(member, ["Window"]);650 member.exposed = exposed_in(globals);651 member.exposureSet = globals;652 }.bind(this));653 // Now run test() on every member, and test_object() for every object.654 for (var name in this.members)655 {656 this.members[name].test();657 if (name in this.objects)658 {659 this.objects[name].forEach(function(str)660 {661 this.members[name].test_object(str);662 }.bind(this));663 }664 }665};666//@}667IdlArray.prototype.assert_type_is = function(value, type)668//@{669{670 if (type.idlType in this.members671 && this.members[type.idlType] instanceof IdlTypedef) {672 this.assert_type_is(value, this.members[type.idlType].idlType);673 return;674 }675 if (type.union) {676 for (var i = 0; i < type.idlType.length; i++) {677 try {678 this.assert_type_is(value, type.idlType[i]);679 // No AssertionError, so we match one type in the union680 return;681 } catch(e) {682 if (e instanceof AssertionError) {683 // We didn't match this type, let's try some others684 continue;685 }686 throw e;687 }688 }689 // TODO: Is there a nice way to list the union's types in the message?690 assert_true(false, "Attribute has value " + format_value(value)691 + " which doesn't match any of the types in the union");692 }693 /**694 * Helper function that tests that value is an instance of type according695 * to the rules of WebIDL. value is any JavaScript value, and type is an696 * object produced by WebIDLParser.js' "type" production. That production697 * is fairly elaborate due to the complexity of WebIDL's types, so it's698 * best to look at the grammar to figure out what properties it might have.699 */700 if (type.idlType == "any")701 {702 // No assertions to make703 return;704 }705 if (type.nullable && value === null)706 {707 // This is fine708 return;709 }710 if (type.array)711 {712 // TODO: not supported yet713 return;714 }715 if (type.sequence)716 {717 assert_true(Array.isArray(value), "should be an Array");718 if (!value.length)719 {720 // Nothing we can do.721 return;722 }723 this.assert_type_is(value[0], type.idlType);724 return;725 }726 if (type.generic === "Promise") {727 assert_true("then" in value, "Attribute with a Promise type should have a then property");728 // TODO: Ideally, we would check on project fulfillment729 // that we get the right type730 // but that would require making the type check async731 return;732 }733 if (type.generic === "FrozenArray") {734 assert_true(Array.isArray(value), "Value should be array");735 assert_true(Object.isFrozen(value), "Value should be frozen");736 if (!value.length)737 {738 // Nothing we can do.739 return;740 }741 this.assert_type_is(value[0], type.idlType);742 return;743 }744 type = type.idlType;745 switch(type)746 {747 case "void":748 assert_equals(value, undefined);749 return;750 case "boolean":751 assert_equals(typeof value, "boolean");752 return;753 case "byte":754 assert_equals(typeof value, "number");755 assert_equals(value, Math.floor(value), "should be an integer");756 assert_true(-128 <= value && value <= 127, "byte " + value + " should be in range [-128, 127]");757 return;758 case "octet":759 assert_equals(typeof value, "number");760 assert_equals(value, Math.floor(value), "should be an integer");761 assert_true(0 <= value && value <= 255, "octet " + value + " should be in range [0, 255]");762 return;763 case "short":764 assert_equals(typeof value, "number");765 assert_equals(value, Math.floor(value), "should be an integer");766 assert_true(-32768 <= value && value <= 32767, "short " + value + " should be in range [-32768, 32767]");767 return;768 case "unsigned short":769 assert_equals(typeof value, "number");770 assert_equals(value, Math.floor(value), "should be an integer");771 assert_true(0 <= value && value <= 65535, "unsigned short " + value + " should be in range [0, 65535]");772 return;773 case "long":774 assert_equals(typeof value, "number");775 assert_equals(value, Math.floor(value), "should be an integer");776 assert_true(-2147483648 <= value && value <= 2147483647, "long " + value + " should be in range [-2147483648, 2147483647]");777 return;778 case "unsigned long":779 assert_equals(typeof value, "number");780 assert_equals(value, Math.floor(value), "should be an integer");781 assert_true(0 <= value && value <= 4294967295, "unsigned long " + value + " should be in range [0, 4294967295]");782 return;783 case "long long":784 assert_equals(typeof value, "number");785 return;786 case "unsigned long long":787 case "DOMTimeStamp":788 assert_equals(typeof value, "number");789 assert_true(0 <= value, "unsigned long long should be positive");790 return;791 case "float":792 assert_equals(typeof value, "number");793 assert_equals(value, fround(value), "float rounded to 32-bit float should be itself");794 assert_not_equals(value, Infinity);795 assert_not_equals(value, -Infinity);796 assert_not_equals(value, NaN);797 return;798 case "DOMHighResTimeStamp":799 case "double":800 assert_equals(typeof value, "number");801 assert_not_equals(value, Infinity);802 assert_not_equals(value, -Infinity);803 assert_not_equals(value, NaN);804 return;805 case "unrestricted float":806 assert_equals(typeof value, "number");807 assert_equals(value, fround(value), "unrestricted float rounded to 32-bit float should be itself");808 return;809 case "unrestricted double":810 assert_equals(typeof value, "number");811 return;812 case "DOMString":813 assert_equals(typeof value, "string");814 return;815 case "ByteString":816 assert_equals(typeof value, "string");817 assert_regexp_match(value, /^[\x00-\x7F]*$/);818 return;819 case "USVString":820 assert_equals(typeof value, "string");821 assert_regexp_match(value, /^([\x00-\ud7ff\ue000-\uffff]|[\ud800-\udbff][\udc00-\udfff])*$/);822 return;823 case "object":824 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");825 return;826 }827 if (!(type in this.members))828 {829 throw new IdlHarnessError("Unrecognized type " + type);830 }831 if (this.members[type] instanceof IdlInterface)832 {833 // We don't want to run the full834 // IdlInterface.prototype.test_instance_of, because that could result835 // in an infinite loop. TODO: This means we don't have tests for836 // NoInterfaceObject interfaces, and we also can't test objects that837 // come from another self.838 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");839 if (value instanceof Object840 && !this.members[type].has_extended_attribute("NoInterfaceObject")841 && type in self)842 {843 assert_true(value instanceof self[type], "instanceof " + type);844 }845 }846 else if (this.members[type] instanceof IdlEnum)847 {848 assert_equals(typeof value, "string");849 }850 else if (this.members[type] instanceof IdlDictionary)851 {852 // TODO: Test when we actually have something to test this on853 }854 else855 {856 throw new IdlHarnessError("Type " + type + " isn't an interface or dictionary");857 }858};859//@}860/// IdlObject ///861function IdlObject() {}862IdlObject.prototype.test = function()863//@{864{865 /**866 * By default, this does nothing, so no actual tests are run for IdlObjects867 * that don't define any (e.g., IdlDictionary at the time of this writing).868 */869};870//@}871IdlObject.prototype.has_extended_attribute = function(name)872//@{873{874 /**875 * This is only meaningful for things that support extended attributes,876 * such as interfaces, exceptions, and members.877 */878 return this.extAttrs.some(function(o)879 {880 return o.name == name;881 });882};883//@}884/// IdlDictionary ///885// Used for IdlArray.prototype.assert_type_is886function IdlDictionary(obj)887//@{888{889 /**890 * obj is an object produced by the WebIDLParser.js "dictionary"891 * production.892 */893 /** Self-explanatory. */894 this.name = obj.name;895 /** A back-reference to our IdlArray. */896 this.array = obj.array;897 /** An array of objects produced by the "dictionaryMember" production. */898 this.members = obj.members;899 /**900 * The name (as a string) of the dictionary type we inherit from, or null901 * if there is none.902 */903 this.base = obj.inheritance;904}905//@}906IdlDictionary.prototype = Object.create(IdlObject.prototype);907IdlDictionary.prototype.get_inheritance_stack = function() {908 return IdlInterface.prototype.get_inheritance_stack.call(this);909};910/// IdlInterface ///911function IdlInterface(obj, is_callback, is_mixin)912//@{913{914 /**915 * obj is an object produced by the WebIDLParser.js "interface" production.916 */917 /** Self-explanatory. */918 this.name = obj.name;919 /** A back-reference to our IdlArray. */920 this.array = obj.array;921 /**922 * An indicator of whether we should run tests on the interface object and923 * interface prototype object. Tests on members are controlled by .untested924 * on each member, not this.925 */926 this.untested = obj.untested;927 /** An array of objects produced by the "ExtAttr" production. */928 this.extAttrs = obj.extAttrs;929 /** An array of IdlInterfaceMembers. */930 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m); });931 if (this.has_extended_attribute("Unforgeable")) {932 this.members933 .filter(function(m) { return !m["static"] && (m.type == "attribute" || m.type == "operation"); })934 .forEach(function(m) { return m.isUnforgeable = true; });935 }936 /**937 * The name (as a string) of the type we inherit from, or null if there is938 * none.939 */940 this.base = obj.inheritance;941 this._is_callback = is_callback;942 this._is_mixin = is_mixin;943}944//@}945IdlInterface.prototype = Object.create(IdlObject.prototype);946IdlInterface.prototype.is_callback = function()947//@{948{949 return this._is_callback;950};951//@}952IdlInterface.prototype.is_mixin = function()953//@{954{955 return this._is_mixin;956};957//@}958IdlInterface.prototype.has_constants = function()959//@{960{961 return this.members.some(function(member) {962 return member.type === "const";963 });964};965//@}966IdlInterface.prototype.get_unscopables = function()967{968 return this.members.filter(function(member) {969 return member.isUnscopable;970 });971};972IdlInterface.prototype.is_global = function()973//@{974{975 return this.extAttrs.some(function(attribute) {976 return attribute.name === "Global";977 });978};979//@}980IdlInterface.prototype.has_to_json_regular_operation = function() {981 return this.members.some(function(m) {982 return m.is_to_json_regular_operation();983 });984};985IdlInterface.prototype.has_default_to_json_regular_operation = function() {986 return this.members.some(function(m) {987 return m.is_to_json_regular_operation() && m.has_extended_attribute("Default");988 });989};990IdlInterface.prototype.get_inheritance_stack = function() {991 /**992 * See https://heycam.github.io/webidl/#create-an-inheritance-stack993 *994 * Returns an array of IdlInterface objects which contains itself995 * and all of its inherited interfaces.996 *997 * So given:998 *999 * A : B {};1000 * B : C {};1001 * C {};1002 *1003 * then A.get_inheritance_stack() should return [A, B, C],1004 * and B.get_inheritance_stack() should return [B, C].1005 *1006 * Note: as dictionary inheritance is expressed identically by the AST,1007 * this works just as well for getting a stack of inherited dictionaries.1008 */1009 var stack = [this];1010 var idl_interface = this;1011 while (idl_interface.base) {1012 var base = this.array.members[idl_interface.base];1013 if (!base) {1014 throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")");1015 } else if (stack.indexOf(base) > -1) {1016 stack.push(base);1017 let dep_chain = stack.map(i => i.name).join(',');1018 throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`);1019 }1020 idl_interface = base;1021 stack.push(idl_interface);1022 }1023 return stack;1024};1025/**1026 * Implementation of1027 * https://heycam.github.io/webidl/#default-tojson-operation1028 * for testing purposes.1029 *1030 * Collects the IDL types of the attributes that meet the criteria1031 * for inclusion in the default toJSON operation for easy1032 * comparison with actual value1033 */1034IdlInterface.prototype.default_to_json_operation = function(callback) {1035 var map = new Map(), isDefault = false;1036 this.traverse_inherited_and_consequential_interfaces(function(I) {1037 if (I.has_default_to_json_regular_operation()) {1038 isDefault = true;1039 I.members.forEach(function(m) {1040 if (!m.static && m.type == "attribute" && I.array.is_json_type(m.idlType)) {1041 map.set(m.name, m.idlType);1042 }1043 });1044 } else if (I.has_to_json_regular_operation()) {1045 isDefault = false;1046 }1047 });1048 return isDefault ? map : null;1049};1050/**1051 * Traverses inherited interfaces from the top down1052 * and imeplemented interfaces inside out.1053 * Invokes |callback| on each interface.1054 *1055 * This is an abstract implementation of the traversal1056 * algorithm specified in:1057 * https://heycam.github.io/webidl/#collect-attribute-values1058 * Given the following inheritance tree:1059 *1060 * F1061 * |1062 * C E - I1063 * | |1064 * B - D1065 * |1066 * G - A - H - J1067 *1068 * Invoking traverse_inherited_and_consequential_interfaces() on A1069 * would traverse the tree in the following order:1070 * C -> B -> F -> E -> I -> D -> A -> G -> H -> J1071 */1072IdlInterface.prototype.traverse_inherited_and_consequential_interfaces = function(callback) {1073 if (typeof callback != "function") {1074 throw new TypeError();1075 }1076 var stack = this.get_inheritance_stack();1077 _traverse_inherited_and_consequential_interfaces(stack, callback);1078};1079function _traverse_inherited_and_consequential_interfaces(stack, callback) {1080 var I = stack.pop();1081 callback(I);1082 var mixins = I.array["implements"][I.name] || I.array["includes"][I.name];1083 if (mixins) {1084 mixins.forEach(function(id) {1085 var mixin = I.array.members[id];1086 if (!mixin) {1087 throw new Error("Interface " + id + " not found (implemented by " + I.name + ")");1088 }1089 var interfaces = mixin.get_inheritance_stack();1090 _traverse_inherited_and_consequential_interfaces(interfaces, callback);1091 });1092 }1093 if (stack.length > 0) {1094 _traverse_inherited_and_consequential_interfaces(stack, callback);1095 }1096}1097IdlInterface.prototype.test = function()1098//@{1099{1100 if (this.has_extended_attribute("NoInterfaceObject") || this.is_mixin())1101 {1102 // No tests to do without an instance. TODO: We should still be able1103 // to run tests on the prototype object, if we obtain one through some1104 // other means.1105 return;1106 }1107 if (!this.exposed) {1108 test(function() {1109 assert_false(this.name in self);1110 }.bind(this), this.name + " interface: existence and properties of interface object");1111 return;1112 }1113 if (!this.untested)1114 {1115 // First test things to do with the exception/interface object and1116 // exception/interface prototype object.1117 this.test_self();1118 }1119 // Then test things to do with its members (constants, fields, attributes,1120 // operations, . . .). These are run even if .untested is true, because1121 // members might themselves be marked as .untested. This might happen to1122 // interfaces if the interface itself is untested but a partial interface1123 // that extends it is tested -- then the interface itself and its initial1124 // members will be marked as untested, but the members added by the partial1125 // interface are still tested.1126 this.test_members();1127};1128//@}1129IdlInterface.prototype.test_self = function()1130//@{1131{1132 test(function()1133 {1134 // This function tests WebIDL as of 2015-01-13.1135 // "For every interface that is exposed in a given ECMAScript global1136 // environment and:1137 // * is a callback interface that has constants declared on it, or1138 // * is a non-callback interface that is not declared with the1139 // [NoInterfaceObject] extended attribute,1140 // a corresponding property MUST exist on the ECMAScript global object.1141 // The name of the property is the identifier of the interface, and its1142 // value is an object called the interface object.1143 // The property has the attributes { [[Writable]]: true,1144 // [[Enumerable]]: false, [[Configurable]]: true }."1145 if (this.is_callback() && !this.has_constants()) {1146 return;1147 }1148 // TODO: Should we test here that the property is actually writable1149 // etc., or trust getOwnPropertyDescriptor?1150 assert_own_property(self, this.name,1151 "self does not have own property " + format_value(this.name));1152 var desc = Object.getOwnPropertyDescriptor(self, this.name);1153 assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter");1154 assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter");1155 assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable");1156 assert_false(desc.enumerable, "self's property " + format_value(this.name) + " should not be enumerable");1157 assert_true(desc.configurable, "self's property " + format_value(this.name) + " should be configurable");1158 if (this.is_callback()) {1159 // "The internal [[Prototype]] property of an interface object for1160 // a callback interface must be the Function.prototype object."1161 assert_equals(Object.getPrototypeOf(self[this.name]), Function.prototype,1162 "prototype of self's property " + format_value(this.name) + " is not Object.prototype");1163 return;1164 }1165 // "The interface object for a given non-callback interface is a1166 // function object."1167 // "If an object is defined to be a function object, then it has1168 // characteristics as follows:"1169 // Its [[Prototype]] internal property is otherwise specified (see1170 // below).1171 // "* Its [[Get]] internal property is set as described in ECMA-2621172 // section 9.1.8."1173 // Not much to test for this.1174 // "* Its [[Construct]] internal property is set as described in1175 // ECMA-262 section 19.2.2.3."1176 // Tested below if no constructor is defined. TODO: test constructors1177 // if defined.1178 // "* Its @@hasInstance property is set as described in ECMA-2621179 // section 19.2.3.8, unless otherwise specified."1180 // TODO1181 // ES6 (rev 30) 19.1.3.6:1182 // "Else, if O has a [[Call]] internal method, then let builtinTag be1183 // "Function"."1184 assert_class_string(self[this.name], "Function", "class string of " + this.name);1185 // "The [[Prototype]] internal property of an interface object for a1186 // non-callback interface is determined as follows:"1187 var prototype = Object.getPrototypeOf(self[this.name]);1188 if (this.base) {1189 // "* If the interface inherits from some other interface, the1190 // value of [[Prototype]] is the interface object for that other1191 // interface."1192 var has_interface_object =1193 !this.array1194 .members[this.base]1195 .has_extended_attribute("NoInterfaceObject");1196 if (has_interface_object) {1197 assert_own_property(self, this.base,1198 'should inherit from ' + this.base +1199 ', but self has no such property');1200 assert_equals(prototype, self[this.base],1201 'prototype of ' + this.name + ' is not ' +1202 this.base);1203 }1204 } else {1205 // "If the interface doesn't inherit from any other interface, the1206 // value of [[Prototype]] is %FunctionPrototype% ([ECMA-262],1207 // section 6.1.7.4)."1208 assert_equals(prototype, Function.prototype,1209 "prototype of self's property " + format_value(this.name) + " is not Function.prototype");1210 }1211 if (!this.has_extended_attribute("Constructor")) {1212 // "The internal [[Call]] method of the interface object behaves as1213 // follows . . .1214 //1215 // "If I was not declared with a [Constructor] extended attribute,1216 // then throw a TypeError."1217 assert_throws(new TypeError(), function() {1218 self[this.name]();1219 }.bind(this), "interface object didn't throw TypeError when called as a function");1220 assert_throws(new TypeError(), function() {1221 new self[this.name]();1222 }.bind(this), "interface object didn't throw TypeError when called as a constructor");1223 }1224 }.bind(this), this.name + " interface: existence and properties of interface object");1225 if (!this.is_callback()) {1226 test(function() {1227 // This function tests WebIDL as of 2014-10-25.1228 // https://heycam.github.io/webidl/#es-interface-call1229 assert_own_property(self, this.name,1230 "self does not have own property " + format_value(this.name));1231 // "Interface objects for non-callback interfaces MUST have a1232 // property named “length” with attributes { [[Writable]]: false,1233 // [[Enumerable]]: false, [[Configurable]]: true } whose value is1234 // a Number."1235 assert_own_property(self[this.name], "length");1236 var desc = Object.getOwnPropertyDescriptor(self[this.name], "length");1237 assert_false("get" in desc, this.name + ".length should not have a getter");1238 assert_false("set" in desc, this.name + ".length should not have a setter");1239 assert_false(desc.writable, this.name + ".length should not be writable");1240 assert_false(desc.enumerable, this.name + ".length should not be enumerable");1241 assert_true(desc.configurable, this.name + ".length should be configurable");1242 var constructors = this.extAttrs1243 .filter(function(attr) { return attr.name == "Constructor"; });1244 var expected_length = minOverloadLength(constructors);1245 assert_equals(self[this.name].length, expected_length, "wrong value for " + this.name + ".length");1246 }.bind(this), this.name + " interface object length");1247 }1248 if (!this.is_callback() || this.has_constants()) {1249 test(function() {1250 // This function tests WebIDL as of 2015-11-17.1251 // https://heycam.github.io/webidl/#interface-object1252 assert_own_property(self, this.name,1253 "self does not have own property " + format_value(this.name));1254 // "All interface objects must have a property named “name” with1255 // attributes { [[Writable]]: false, [[Enumerable]]: false,1256 // [[Configurable]]: true } whose value is the identifier of the1257 // corresponding interface."1258 assert_own_property(self[this.name], "name");1259 var desc = Object.getOwnPropertyDescriptor(self[this.name], "name");1260 assert_false("get" in desc, this.name + ".name should not have a getter");1261 assert_false("set" in desc, this.name + ".name should not have a setter");1262 assert_false(desc.writable, this.name + ".name should not be writable");1263 assert_false(desc.enumerable, this.name + ".name should not be enumerable");1264 assert_true(desc.configurable, this.name + ".name should be configurable");1265 assert_equals(self[this.name].name, this.name, "wrong value for " + this.name + ".name");1266 }.bind(this), this.name + " interface object name");1267 }1268 if (this.has_extended_attribute("LegacyWindowAlias")) {1269 test(function()1270 {1271 var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; });1272 if (aliasAttrs.length > 1) {1273 throw new IdlHarnessError("Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name);1274 }1275 if (this.is_callback()) {1276 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name);1277 }1278 if (this.exposureSet.indexOf("Window") === -1) {1279 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window");1280 }1281 // TODO: when testing of [NoInterfaceObject] interfaces is supported,1282 // check that it's not specified together with LegacyWindowAlias.1283 // TODO: maybe check that [LegacyWindowAlias] is not specified on a partial interface.1284 var rhs = aliasAttrs[0].rhs;1285 if (!rhs) {1286 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier");1287 }1288 var aliases;1289 if (rhs.type === "identifier-list") {1290 aliases = rhs.value;1291 } else { // rhs.type === identifier1292 aliases = [ rhs.value ];1293 }1294 // OK now actually check the aliases...1295 var alias;1296 if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) {1297 for (alias of aliases) {1298 assert_true(alias in self, alias + " should exist");1299 assert_equals(self[alias], self[this.name], "self." + alias + " should be the same value as self." + this.name);1300 var desc = Object.getOwnPropertyDescriptor(self, alias);1301 assert_equals(desc.value, self[this.name], "wrong value in " + alias + " property descriptor");1302 assert_true(desc.writable, alias + " should be writable");1303 assert_false(desc.enumerable, alias + " should not be enumerable");1304 assert_true(desc.configurable, alias + " should be configurable");1305 assert_false('get' in desc, alias + " should not have a getter");1306 assert_false('set' in desc, alias + " should not have a setter");1307 }1308 } else {1309 for (alias of aliases) {1310 assert_false(alias in self, alias + " should not exist");1311 }1312 }1313 }.bind(this), this.name + " interface: legacy window alias");1314 }1315 // TODO: Test named constructors if I find any interfaces that have them.1316 test(function()1317 {1318 // This function tests WebIDL as of 2015-01-21.1319 // https://heycam.github.io/webidl/#interface-object1320 if (this.is_callback() && !this.has_constants()) {1321 return;1322 }1323 assert_own_property(self, this.name,1324 "self does not have own property " + format_value(this.name));1325 if (this.is_callback()) {1326 assert_false("prototype" in self[this.name],1327 this.name + ' should not have a "prototype" property');1328 return;1329 }1330 // "An interface object for a non-callback interface must have a1331 // property named “prototype” with attributes { [[Writable]]: false,1332 // [[Enumerable]]: false, [[Configurable]]: false } whose value is an1333 // object called the interface prototype object. This object has1334 // properties that correspond to the regular attributes and regular1335 // operations defined on the interface, and is described in more detail1336 // in section 4.5.4 below."1337 assert_own_property(self[this.name], "prototype",1338 'interface "' + this.name + '" does not have own property "prototype"');1339 var desc = Object.getOwnPropertyDescriptor(self[this.name], "prototype");1340 assert_false("get" in desc, this.name + ".prototype should not have a getter");1341 assert_false("set" in desc, this.name + ".prototype should not have a setter");1342 assert_false(desc.writable, this.name + ".prototype should not be writable");1343 assert_false(desc.enumerable, this.name + ".prototype should not be enumerable");1344 assert_false(desc.configurable, this.name + ".prototype should not be configurable");1345 // Next, test that the [[Prototype]] of the interface prototype object1346 // is correct. (This is made somewhat difficult by the existence of1347 // [NoInterfaceObject].)1348 // TODO: Aryeh thinks there's at least other place in this file where1349 // we try to figure out if an interface prototype object is1350 // correct. Consolidate that code.1351 // "The interface prototype object for a given interface A must have an1352 // internal [[Prototype]] property whose value is returned from the1353 // following steps:1354 // "If A is declared with the [Global] extended1355 // attribute, and A supports named properties, then return the named1356 // properties object for A, as defined in §3.6.4 Named properties1357 // object.1358 // "Otherwise, if A is declared to inherit from another interface, then1359 // return the interface prototype object for the inherited interface.1360 // "Otherwise, if A is declared with the [LegacyArrayClass] extended1361 // attribute, then return %ArrayPrototype%.1362 // "Otherwise, return %ObjectPrototype%.1363 //1364 // "In the ECMAScript binding, the DOMException type has some additional1365 // requirements:1366 //1367 // "Unlike normal interface types, the interface prototype object1368 // for DOMException must have as its [[Prototype]] the intrinsic1369 // object %ErrorPrototype%."1370 //1371 if (this.name === "Window") {1372 assert_class_string(Object.getPrototypeOf(self[this.name].prototype),1373 'WindowProperties',1374 'Class name for prototype of Window' +1375 '.prototype is not "WindowProperties"');1376 } else {1377 var inherit_interface, inherit_interface_has_interface_object;1378 if (this.base) {1379 inherit_interface = this.base;1380 inherit_interface_has_interface_object =1381 !this.array1382 .members[inherit_interface]1383 .has_extended_attribute("NoInterfaceObject");1384 } else if (this.has_extended_attribute('LegacyArrayClass')) {1385 inherit_interface = 'Array';1386 inherit_interface_has_interface_object = true;1387 } else if (this.name === "DOMException") {1388 inherit_interface = 'Error';1389 inherit_interface_has_interface_object = true;1390 } else {1391 inherit_interface = 'Object';1392 inherit_interface_has_interface_object = true;1393 }1394 if (inherit_interface_has_interface_object) {1395 assert_own_property(self, inherit_interface,1396 'should inherit from ' + inherit_interface + ', but self has no such property');1397 assert_own_property(self[inherit_interface], 'prototype',1398 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property');1399 assert_equals(Object.getPrototypeOf(self[this.name].prototype),1400 self[inherit_interface].prototype,1401 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype');1402 } else {1403 // We can't test that we get the correct object, because this is the1404 // only way to get our hands on it. We only test that its class1405 // string, at least, is correct.1406 assert_class_string(Object.getPrototypeOf(self[this.name].prototype),1407 inherit_interface + 'Prototype',1408 'Class name for prototype of ' + this.name +1409 '.prototype is not "' + inherit_interface + 'Prototype"');1410 }1411 }1412 // "The class string of an interface prototype object is the1413 // concatenation of the interface’s identifier and the string1414 // “Prototype”."1415 // Skip these tests for now due to a specification issue about1416 // prototype name.1417 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=282441418 // assert_class_string(self[this.name].prototype, this.name + "Prototype",1419 // "class string of " + this.name + ".prototype");1420 // String() should end up calling {}.toString if nothing defines a1421 // stringifier.1422 if (!this.has_stringifier()) {1423 // assert_equals(String(self[this.name].prototype), "[object " + this.name + "Prototype]",1424 // "String(" + this.name + ".prototype)");1425 }1426 }.bind(this), this.name + " interface: existence and properties of interface prototype object");1427 // "If the interface is declared with the [Global]1428 // extended attribute, or the interface is in the set of inherited1429 // interfaces for any other interface that is declared with one of these1430 // attributes, then the interface prototype object must be an immutable1431 // prototype exotic object."1432 // https://heycam.github.io/webidl/#interface-prototype-object1433 if (this.is_global()) {1434 this.test_immutable_prototype("interface prototype object", self[this.name].prototype);1435 }1436 test(function()1437 {1438 if (this.is_callback() && !this.has_constants()) {1439 return;1440 }1441 assert_own_property(self, this.name,1442 "self does not have own property " + format_value(this.name));1443 if (this.is_callback()) {1444 assert_false("prototype" in self[this.name],1445 this.name + ' should not have a "prototype" property');1446 return;1447 }1448 assert_own_property(self[this.name], "prototype",1449 'interface "' + this.name + '" does not have own property "prototype"');1450 // "If the [NoInterfaceObject] extended attribute was not specified on1451 // the interface, then the interface prototype object must also have a1452 // property named “constructor” with attributes { [[Writable]]: true,1453 // [[Enumerable]]: false, [[Configurable]]: true } whose value is a1454 // reference to the interface object for the interface."1455 assert_own_property(self[this.name].prototype, "constructor",1456 this.name + '.prototype does not have own property "constructor"');1457 var desc = Object.getOwnPropertyDescriptor(self[this.name].prototype, "constructor");1458 assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter");1459 assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter");1460 assert_true(desc.writable, this.name + ".prototype.constructor should be writable");1461 assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable");1462 assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable");1463 assert_equals(self[this.name].prototype.constructor, self[this.name],1464 this.name + '.prototype.constructor is not the same object as ' + this.name);1465 }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');1466 test(function()1467 {1468 if (this.is_callback() && !this.has_constants()) {1469 return;1470 }1471 assert_own_property(self, this.name,1472 "self does not have own property " + format_value(this.name));1473 if (this.is_callback()) {1474 assert_false("prototype" in self[this.name],1475 this.name + ' should not have a "prototype" property');1476 return;1477 }1478 assert_own_property(self[this.name], "prototype",1479 'interface "' + this.name + '" does not have own property "prototype"');1480 // If the interface has any member declared with the [Unscopable] extended1481 // attribute, then there must be a property on the interface prototype object1482 // whose name is the @@unscopables symbol, which has the attributes1483 // { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true },1484 // and whose value is an object created as follows...1485 var unscopables = this.get_unscopables().map(m => m.name);1486 var proto = self[this.name].prototype;1487 if (unscopables.length != 0) {1488 assert_own_property(1489 proto, Symbol.unscopables,1490 this.name + '.prototype should have an @@unscopables property');1491 var desc = Object.getOwnPropertyDescriptor(proto, Symbol.unscopables);1492 assert_false("get" in desc,1493 this.name + ".prototype[Symbol.unscopables] should not have a getter");1494 assert_false("set" in desc, this.name + ".prototype[Symbol.unscopables] should not have a setter");1495 assert_false(desc.writable, this.name + ".prototype[Symbol.unscopables] should not be writable");1496 assert_false(desc.enumerable, this.name + ".prototype[Symbol.unscopables] should not be enumerable");1497 assert_true(desc.configurable, this.name + ".prototype[Symbol.unscopables] should be configurable");1498 assert_equals(desc.value, proto[Symbol.unscopables],1499 this.name + '.prototype[Symbol.unscopables] should be in the descriptor');1500 assert_equals(typeof desc.value, "object",1501 this.name + '.prototype[Symbol.unscopables] should be an object');1502 assert_equals(Object.getPrototypeOf(desc.value), null,1503 this.name + '.prototype[Symbol.unscopables] should have a null prototype');1504 assert_equals(Object.getOwnPropertySymbols(desc.value).length,1505 0,1506 this.name + '.prototype[Symbol.unscopables] should have the right number of symbol-named properties');1507 // Check that we do not have _extra_ unscopables. Checking that we1508 // have all the ones we should will happen in the per-member tests.1509 var observed = Object.getOwnPropertyNames(desc.value);1510 for (var prop of observed) {1511 assert_not_equals(unscopables.indexOf(prop),1512 -1,1513 this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"');1514 }1515 } else {1516 assert_equals(Object.getOwnPropertyDescriptor(self[this.name].prototype, Symbol.unscopables),1517 undefined,1518 this.name + '.prototype should not have @@unscopables');1519 }1520 }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property');1521};1522//@}1523IdlInterface.prototype.test_immutable_prototype = function(type, obj)1524//@{1525{1526 if (typeof Object.setPrototypeOf !== "function") {1527 return;1528 }1529 test(function(t) {1530 var originalValue = Object.getPrototypeOf(obj);1531 var newValue = Object.create(null);1532 t.add_cleanup(function() {1533 try {1534 Object.setPrototypeOf(obj, originalValue);1535 } catch (err) {}1536 });1537 assert_throws(new TypeError(), function() {1538 Object.setPrototypeOf(obj, newValue);1539 });1540 assert_equals(1541 Object.getPrototypeOf(obj),1542 originalValue,1543 "original value not modified"1544 );1545 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1546 "of " + type + " - setting to a new value via Object.setPrototypeOf " +1547 "should throw a TypeError");1548 test(function(t) {1549 var originalValue = Object.getPrototypeOf(obj);1550 var newValue = Object.create(null);1551 t.add_cleanup(function() {1552 var setter = Object.getOwnPropertyDescriptor(1553 Object.prototype, '__proto__'1554 ).set;1555 try {1556 setter.call(obj, originalValue);1557 } catch (err) {}1558 });1559 assert_throws(new TypeError(), function() {1560 obj.__proto__ = newValue;1561 });1562 assert_equals(1563 Object.getPrototypeOf(obj),1564 originalValue,1565 "original value not modified"1566 );1567 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1568 "of " + type + " - setting to a new value via __proto__ " +1569 "should throw a TypeError");1570 test(function(t) {1571 var originalValue = Object.getPrototypeOf(obj);1572 var newValue = Object.create(null);1573 t.add_cleanup(function() {1574 try {1575 Reflect.setPrototypeOf(obj, originalValue);1576 } catch (err) {}1577 });1578 assert_false(Reflect.setPrototypeOf(obj, newValue));1579 assert_equals(1580 Object.getPrototypeOf(obj),1581 originalValue,1582 "original value not modified"1583 );1584 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1585 "of " + type + " - setting to a new value via Reflect.setPrototypeOf " +1586 "should return false");1587 test(function() {1588 var originalValue = Object.getPrototypeOf(obj);1589 Object.setPrototypeOf(obj, originalValue);1590 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1591 "of " + type + " - setting to its original value via Object.setPrototypeOf " +1592 "should not throw");1593 test(function() {1594 var originalValue = Object.getPrototypeOf(obj);1595 obj.__proto__ = originalValue;1596 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1597 "of " + type + " - setting to its original value via __proto__ " +1598 "should not throw");1599 test(function() {1600 var originalValue = Object.getPrototypeOf(obj);1601 assert_true(Reflect.setPrototypeOf(obj, originalValue));1602 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1603 "of " + type + " - setting to its original value via Reflect.setPrototypeOf " +1604 "should return true");1605};1606//@}1607IdlInterface.prototype.test_member_const = function(member)1608//@{1609{1610 if (!this.has_constants()) {1611 throw new IdlHarnessError("Internal error: test_member_const called without any constants");1612 }1613 test(function()1614 {1615 assert_own_property(self, this.name,1616 "self does not have own property " + format_value(this.name));1617 // "For each constant defined on an interface A, there must be1618 // a corresponding property on the interface object, if it1619 // exists."1620 assert_own_property(self[this.name], member.name);1621 // "The value of the property is that which is obtained by1622 // converting the constant’s IDL value to an ECMAScript1623 // value."1624 assert_equals(self[this.name][member.name], constValue(member.value),1625 "property has wrong value");1626 // "The property has attributes { [[Writable]]: false,1627 // [[Enumerable]]: true, [[Configurable]]: false }."1628 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);1629 assert_false("get" in desc, "property should not have a getter");1630 assert_false("set" in desc, "property should not have a setter");1631 assert_false(desc.writable, "property should not be writable");1632 assert_true(desc.enumerable, "property should be enumerable");1633 assert_false(desc.configurable, "property should not be configurable");1634 }.bind(this), this.name + " interface: constant " + member.name + " on interface object");1635 // "In addition, a property with the same characteristics must1636 // exist on the interface prototype object."1637 test(function()1638 {1639 assert_own_property(self, this.name,1640 "self does not have own property " + format_value(this.name));1641 if (this.is_callback()) {1642 assert_false("prototype" in self[this.name],1643 this.name + ' should not have a "prototype" property');1644 return;1645 }1646 assert_own_property(self[this.name], "prototype",1647 'interface "' + this.name + '" does not have own property "prototype"');1648 assert_own_property(self[this.name].prototype, member.name);1649 assert_equals(self[this.name].prototype[member.name], constValue(member.value),1650 "property has wrong value");1651 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);1652 assert_false("get" in desc, "property should not have a getter");1653 assert_false("set" in desc, "property should not have a setter");1654 assert_false(desc.writable, "property should not be writable");1655 assert_true(desc.enumerable, "property should be enumerable");1656 assert_false(desc.configurable, "property should not be configurable");1657 }.bind(this), this.name + " interface: constant " + member.name + " on interface prototype object");1658};1659//@}1660IdlInterface.prototype.test_member_attribute = function(member)1661//@{1662 {1663 var a_test = async_test(this.name + " interface: attribute " + member.name);1664 a_test.step(function()1665 {1666 if (this.is_callback() && !this.has_constants()) {1667 a_test.done()1668 return;1669 }1670 assert_own_property(self, this.name,1671 "self does not have own property " + format_value(this.name));1672 assert_own_property(self[this.name], "prototype",1673 'interface "' + this.name + '" does not have own property "prototype"');1674 if (member["static"]) {1675 assert_own_property(self[this.name], member.name,1676 "The interface object must have a property " +1677 format_value(member.name));1678 a_test.done();1679 } else if (this.is_global()) {1680 assert_own_property(self, member.name,1681 "The global object must have a property " +1682 format_value(member.name));1683 assert_false(member.name in self[this.name].prototype,1684 "The prototype object should not have a property " +1685 format_value(member.name));1686 var getter = Object.getOwnPropertyDescriptor(self, member.name).get;1687 assert_equals(typeof(getter), "function",1688 format_value(member.name) + " must have a getter");1689 // Try/catch around the get here, since it can legitimately throw.1690 // If it does, we obviously can't check for equality with direct1691 // invocation of the getter.1692 var gotValue;1693 var propVal;1694 try {1695 propVal = self[member.name];1696 gotValue = true;1697 } catch (e) {1698 gotValue = false;1699 }1700 if (gotValue) {1701 assert_equals(propVal, getter.call(undefined),1702 "Gets on a global should not require an explicit this");1703 }1704 // do_interface_attribute_asserts must be the last thing we do,1705 // since it will call done() on a_test.1706 this.do_interface_attribute_asserts(self, member, a_test);1707 } else {1708 assert_true(member.name in self[this.name].prototype,1709 "The prototype object must have a property " +1710 format_value(member.name));1711 if (!member.has_extended_attribute("LenientThis")) {1712 if (member.idlType.generic !== "Promise") {1713 assert_throws(new TypeError(), function() {1714 self[this.name].prototype[member.name];1715 }.bind(this), "getting property on prototype object must throw TypeError");1716 // do_interface_attribute_asserts must be the last thing we1717 // do, since it will call done() on a_test.1718 this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test);1719 } else {1720 promise_rejects(a_test, new TypeError(),1721 self[this.name].prototype[member.name])1722 .then(function() {1723 // do_interface_attribute_asserts must be the last1724 // thing we do, since it will call done() on a_test.1725 this.do_interface_attribute_asserts(self[this.name].prototype,1726 member, a_test);1727 }.bind(this));1728 }1729 } else {1730 assert_equals(self[this.name].prototype[member.name], undefined,1731 "getting property on prototype object must return undefined");1732 // do_interface_attribute_asserts must be the last thing we do,1733 // since it will call done() on a_test.1734 this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test);1735 }1736 }1737 }.bind(this));1738 test(function () {1739 this.do_member_unscopable_asserts(member);1740 }.bind(this), 'Unscopable handled correctly for ' + member.name + ' property on ' + this.name);1741};1742//@}1743IdlInterface.prototype.test_member_operation = function(member)1744//@{1745{1746 var a_test = async_test(this.name + " interface: operation " + member.name +1747 "(" + member.arguments.map(1748 function(m) {return m.idlType.idlType; } ).join(", ")1749 +")");1750 a_test.step(function()1751 {1752 // This function tests WebIDL as of 2015-12-29.1753 // https://heycam.github.io/webidl/#es-operations1754 if (this.is_callback() && !this.has_constants()) {1755 a_test.done();1756 return;1757 }1758 assert_own_property(self, this.name,1759 "self does not have own property " + format_value(this.name));1760 if (this.is_callback()) {1761 assert_false("prototype" in self[this.name],1762 this.name + ' should not have a "prototype" property');1763 a_test.done();1764 return;1765 }1766 assert_own_property(self[this.name], "prototype",1767 'interface "' + this.name + '" does not have own property "prototype"');1768 // "For each unique identifier of an exposed operation defined on the1769 // interface, there must exist a corresponding property, unless the1770 // effective overload set for that identifier and operation and with an1771 // argument count of 0 has no entries."1772 // TODO: Consider [Exposed].1773 // "The location of the property is determined as follows:"1774 var memberHolderObject;1775 // "* If the operation is static, then the property exists on the1776 // interface object."1777 if (member["static"]) {1778 assert_own_property(self[this.name], member.name,1779 "interface object missing static operation");1780 memberHolderObject = self[this.name];1781 // "* Otherwise, [...] if the interface was declared with the [Global]1782 // extended attribute, then the property exists1783 // on every object that implements the interface."1784 } else if (this.is_global()) {1785 assert_own_property(self, member.name,1786 "global object missing non-static operation");1787 memberHolderObject = self;1788 // "* Otherwise, the property exists solely on the interface’s1789 // interface prototype object."1790 } else {1791 assert_own_property(self[this.name].prototype, member.name,1792 "interface prototype object missing non-static operation");1793 memberHolderObject = self[this.name].prototype;1794 }1795 this.do_member_operation_asserts(memberHolderObject, member, a_test);1796 }.bind(this));1797 test(function () {1798 this.do_member_unscopable_asserts(member);1799 }.bind(this),1800 'Unscopable handled correctly for ' + member.name + "(" +1801 member.arguments.map(1802 function(m) {return m.idlType.idlType; } ).join(", ")1803 + ")" + ' on ' + this.name);1804};1805IdlInterface.prototype.do_member_unscopable_asserts = function(member)1806{1807 // Check that if the member is unscopable then it's in the1808 // @@unscopables object properly.1809 if (!member.isUnscopable) {1810 return;1811 }1812 var unscopables = self[this.name].prototype[Symbol.unscopables];1813 var prop = member.name;1814 var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop);1815 assert_equals(typeof propDesc, "object",1816 this.name + '.prototype[Symbol.unscopables].' + prop + ' must exist')1817 assert_false("get" in propDesc,1818 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no getter');1819 assert_false("set" in propDesc,1820 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no setter');1821 assert_true(propDesc.writable,1822 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be writable');1823 assert_true(propDesc.enumerable,1824 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be enumerable');1825 assert_true(propDesc.configurable,1826 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be configurable');1827 assert_equals(propDesc.value, true,1828 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have the value `true`');1829};1830//@}1831IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test)1832//@{1833{1834 var done = a_test.done.bind(a_test);1835 var operationUnforgeable = member.isUnforgeable;1836 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);1837 // "The property has attributes { [[Writable]]: B,1838 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the1839 // operation is unforgeable on the interface, and true otherwise".1840 assert_false("get" in desc, "property should not have a getter");1841 assert_false("set" in desc, "property should not have a setter");1842 assert_equals(desc.writable, !operationUnforgeable,1843 "property should be writable if and only if not unforgeable");1844 assert_true(desc.enumerable, "property should be enumerable");1845 assert_equals(desc.configurable, !operationUnforgeable,1846 "property should be configurable if and only if not unforgeable");1847 // "The value of the property is a Function object whose1848 // behavior is as follows . . ."1849 assert_equals(typeof memberHolderObject[member.name], "function",1850 "property must be a function");1851 // "The value of the Function object’s “length” property is1852 // a Number determined as follows:1853 // ". . .1854 // "Return the length of the shortest argument list of the1855 // entries in S."1856 assert_equals(memberHolderObject[member.name].length,1857 minOverloadLength(this.members.filter(function(m) {1858 return m.type == "operation" && m.name == member.name;1859 })),1860 "property has wrong .length");1861 // Make some suitable arguments1862 var args = member.arguments.map(function(arg) {1863 return create_suitable_object(arg.idlType);1864 });1865 // "Let O be a value determined as follows:1866 // ". . .1867 // "Otherwise, throw a TypeError."1868 // This should be hit if the operation is not static, there is1869 // no [ImplicitThis] attribute, and the this value is null.1870 //1871 // TODO: We currently ignore the [ImplicitThis] case. Except we manually1872 // check for globals, since otherwise we'll invoke window.close(). And we1873 // have to skip this test for anything that on the proto chain of "self",1874 // since that does in fact have implicit-this behavior.1875 if (!member["static"]) {1876 var cb;1877 if (!this.is_global() &&1878 memberHolderObject[member.name] != self[member.name])1879 {1880 cb = awaitNCallbacks(2, done);1881 throwOrReject(a_test, member, memberHolderObject[member.name], null, args,1882 "calling operation with this = null didn't throw TypeError", cb);1883 } else {1884 cb = awaitNCallbacks(1, done);1885 }1886 // ". . . If O is not null and is also not a platform object1887 // that implements interface I, throw a TypeError."1888 //1889 // TODO: Test a platform object that implements some other1890 // interface. (Have to be sure to get inheritance right.)1891 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args,1892 "calling operation with this = {} didn't throw TypeError", cb);1893 } else {1894 done();1895 }1896}1897//@}1898IdlInterface.prototype.add_iterable_members = function(member)1899//@{1900{1901 this.members.push(new IdlInterfaceMember(1902 { type: "operation", name: "entries", idlType: "iterator", arguments: []}));1903 this.members.push(new IdlInterfaceMember(1904 { type: "operation", name: "keys", idlType: "iterator", arguments: []}));1905 this.members.push(new IdlInterfaceMember(1906 { type: "operation", name: "values", idlType: "iterator", arguments: []}));1907 this.members.push(new IdlInterfaceMember(1908 { type: "operation", name: "forEach", idlType: "void",1909 arguments:1910 [{ name: "callback", idlType: {idlType: "function"}},1911 { name: "thisValue", idlType: {idlType: "any"}, optional: true}]}));1912};1913IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, member) {1914 var instanceName = memberHolderObject.constructor.name;1915 if (member.has_extended_attribute("Default")) {1916 var map = this.default_to_json_operation();1917 test(function() {1918 var json = memberHolderObject.toJSON();1919 map.forEach(function(type, k) {1920 assert_true(k in json, "property " + JSON.stringify(k) + " should be present in the output of " + this.name + ".prototype.toJSON()");1921 var descriptor = Object.getOwnPropertyDescriptor(json, k);1922 assert_true(descriptor.writable, "property " + k + " should be writable");1923 assert_true(descriptor.configurable, "property " + k + " should be configurable");1924 assert_true(descriptor.enumerable, "property " + k + " should be enumerable");1925 this.array.assert_type_is(json[k], type);1926 delete json[k];1927 }, this);1928 }.bind(this), "Test default toJSON operation of " + instanceName);1929 } else {1930 test(function() {1931 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);1932 this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType);1933 }.bind(this), "Test toJSON operation of " + instanceName);1934 }1935};1936//@}1937IdlInterface.prototype.test_member_iterable = function(member)1938//@{1939{1940 var interfaceName = this.name;1941 var isPairIterator = member.idlType instanceof Array;1942 test(function()1943 {1944 var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator);1945 assert_true(descriptor.writable, "property should be writable");1946 assert_true(descriptor.configurable, "property should be configurable");1947 assert_false(descriptor.enumerable, "property should not be enumerable");1948 assert_equals(self[interfaceName].prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name");1949 }, "Testing Symbol.iterator property of iterable interface " + interfaceName);1950 if (isPairIterator) {1951 test(function() {1952 assert_equals(self[interfaceName].prototype[Symbol.iterator], self[interfaceName].prototype["entries"], "entries method is not the same as @@iterator");1953 }, "Testing pair iterable interface " + interfaceName);1954 } else {1955 test(function() {1956 ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) {1957 assert_equals(self[interfaceName].prototype[property], Array.prototype[property], property + " function is not the same as Array one");1958 });1959 }, "Testing value iterable interface " + interfaceName);1960 }1961};1962//@}1963IdlInterface.prototype.test_member_stringifier = function(member)1964//@{1965{1966 test(function()1967 {1968 if (this.is_callback() && !this.has_constants()) {1969 return;1970 }1971 assert_own_property(self, this.name,1972 "self does not have own property " + format_value(this.name));1973 if (this.is_callback()) {1974 assert_false("prototype" in self[this.name],1975 this.name + ' should not have a "prototype" property');1976 return;1977 }1978 assert_own_property(self[this.name], "prototype",1979 'interface "' + this.name + '" does not have own property "prototype"');1980 // ". . . the property exists on the interface prototype object."1981 var interfacePrototypeObject = self[this.name].prototype;1982 assert_own_property(self[this.name].prototype, "toString",1983 "interface prototype object missing non-static operation");1984 var stringifierUnforgeable = member.isUnforgeable;1985 var desc = Object.getOwnPropertyDescriptor(interfacePrototypeObject, "toString");1986 // "The property has attributes { [[Writable]]: B,1987 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the1988 // stringifier is unforgeable on the interface, and true otherwise."1989 assert_false("get" in desc, "property should not have a getter");1990 assert_false("set" in desc, "property should not have a setter");1991 assert_equals(desc.writable, !stringifierUnforgeable,1992 "property should be writable if and only if not unforgeable");1993 assert_true(desc.enumerable, "property should be enumerable");1994 assert_equals(desc.configurable, !stringifierUnforgeable,1995 "property should be configurable if and only if not unforgeable");1996 // "The value of the property is a Function object, which behaves as1997 // follows . . ."1998 assert_equals(typeof interfacePrototypeObject.toString, "function",1999 "property must be a function");2000 // "The value of the Function object’s “length” property is the Number2001 // value 0."2002 assert_equals(interfacePrototypeObject.toString.length, 0,2003 "property has wrong .length");2004 // "Let O be the result of calling ToObject on the this value."2005 assert_throws(new TypeError(), function() {2006 self[this.name].prototype.toString.apply(null, []);2007 }, "calling stringifier with this = null didn't throw TypeError");2008 // "If O is not an object that implements the interface on which the2009 // stringifier was declared, then throw a TypeError."2010 //2011 // TODO: Test a platform object that implements some other2012 // interface. (Have to be sure to get inheritance right.)2013 assert_throws(new TypeError(), function() {2014 self[this.name].prototype.toString.apply({}, []);2015 }, "calling stringifier with this = {} didn't throw TypeError");2016 }.bind(this), this.name + " interface: stringifier");2017};2018//@}2019IdlInterface.prototype.test_members = function()2020//@{2021{2022 for (var i = 0; i < this.members.length; i++)2023 {2024 var member = this.members[i];2025 switch (member.type) {2026 case "iterable":2027 this.add_iterable_members(member);2028 break;2029 // TODO: add setlike and maplike handling.2030 default:2031 break;2032 }2033 }2034 for (var i = 0; i < this.members.length; i++)2035 {2036 var member = this.members[i];2037 if (member.untested) {2038 continue;2039 }2040 if (!exposed_in(exposure_set(member, this.exposureSet))) {2041 test(function() {2042 // It's not exposed, so we shouldn't find it anywhere.2043 assert_false(member.name in self[this.name],2044 "The interface object must not have a property " +2045 format_value(member.name));2046 assert_false(member.name in self[this.name].prototype,2047 "The prototype object must not have a property " +2048 format_value(member.name));2049 }.bind(this), this.name + " interface: member " + member.name);2050 continue;2051 }2052 switch (member.type) {2053 case "const":2054 this.test_member_const(member);2055 break;2056 case "attribute":2057 // For unforgeable attributes, we do the checks in2058 // test_interface_of instead.2059 if (!member.isUnforgeable)2060 {2061 this.test_member_attribute(member);2062 }2063 if (member.stringifier) {2064 this.test_member_stringifier(member);2065 }2066 break;2067 case "operation":2068 // TODO: Need to correctly handle multiple operations with the same2069 // identifier.2070 // For unforgeable operations, we do the checks in2071 // test_interface_of instead.2072 if (member.name) {2073 if (!member.isUnforgeable)2074 {2075 this.test_member_operation(member);2076 }2077 } else if (member.stringifier) {2078 this.test_member_stringifier(member);2079 }2080 break;2081 case "iterable":2082 this.test_member_iterable(member);2083 break;2084 default:2085 // TODO: check more member types.2086 break;2087 }2088 }2089};2090//@}2091IdlInterface.prototype.test_object = function(desc)2092//@{2093{2094 var obj, exception = null;2095 try2096 {2097 obj = eval(desc);2098 }2099 catch(e)2100 {2101 exception = e;2102 }2103 var expected_typeof =2104 this.members.some(function(member) { return member.legacycaller; })2105 ? "function"2106 : "object";2107 this.test_primary_interface_of(desc, obj, exception, expected_typeof);2108 var current_interface = this;2109 while (current_interface)2110 {2111 if (!(current_interface.name in this.array.members))2112 {2113 throw new IdlHarnessError("Interface " + current_interface.name + " not found (inherited by " + this.name + ")");2114 }2115 if (current_interface.prevent_multiple_testing && current_interface.already_tested)2116 {2117 return;2118 }2119 current_interface.test_interface_of(desc, obj, exception, expected_typeof);2120 current_interface = this.array.members[current_interface.base];2121 }2122};2123//@}2124IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception, expected_typeof)2125//@{2126{2127 // Only the object itself, not its members, are tested here, so if the2128 // interface is untested, there is nothing to do.2129 if (this.untested)2130 {2131 return;2132 }2133 // "The internal [[SetPrototypeOf]] method of every platform object that2134 // implements an interface with the [Global] extended2135 // attribute must execute the same algorithm as is defined for the2136 // [[SetPrototypeOf]] internal method of an immutable prototype exotic2137 // object."2138 // https://heycam.github.io/webidl/#platform-object-setprototypeof2139 if (this.is_global())2140 {2141 this.test_immutable_prototype("global platform object", obj);2142 }2143 // We can't easily test that its prototype is correct if there's no2144 // interface object, or the object is from a different global environment2145 // (not instanceof Object). TODO: test in this case that its prototype at2146 // least looks correct, even if we can't test that it's actually correct.2147 if (!this.has_extended_attribute("NoInterfaceObject")2148 && (typeof obj != expected_typeof || obj instanceof Object))2149 {2150 test(function()2151 {2152 assert_equals(exception, null, "Unexpected exception when evaluating object");2153 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2154 assert_own_property(self, this.name,2155 "self does not have own property " + format_value(this.name));2156 assert_own_property(self[this.name], "prototype",2157 'interface "' + this.name + '" does not have own property "prototype"');2158 // "The value of the internal [[Prototype]] property of the2159 // platform object is the interface prototype object of the primary2160 // interface from the platform object’s associated global2161 // environment."2162 assert_equals(Object.getPrototypeOf(obj),2163 self[this.name].prototype,2164 desc + "'s prototype is not " + this.name + ".prototype");2165 }.bind(this), this.name + " must be primary interface of " + desc);2166 }2167 // "The class string of a platform object that implements one or more2168 // interfaces must be the identifier of the primary interface of the2169 // platform object."2170 test(function()2171 {2172 assert_equals(exception, null, "Unexpected exception when evaluating object");2173 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2174 assert_class_string(obj, this.name, "class string of " + desc);2175 if (!this.has_stringifier())2176 {2177 assert_equals(String(obj), "[object " + this.name + "]", "String(" + desc + ")");2178 }2179 }.bind(this), "Stringification of " + desc);2180};2181//@}2182IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expected_typeof)2183//@{2184{2185 // TODO: Indexed and named properties, more checks on interface members2186 this.already_tested = true;2187 for (var i = 0; i < this.members.length; i++)2188 {2189 var member = this.members[i];2190 if (member.untested) {2191 continue;2192 }2193 if (!exposed_in(exposure_set(member, this.exposureSet))) {2194 test(function() {2195 assert_equals(exception, null, "Unexpected exception when evaluating object");2196 assert_false(member.name in obj);2197 }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"');2198 continue;2199 }2200 if (member.type == "attribute" && member.isUnforgeable)2201 {2202 var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"');2203 a_test.step(function() {2204 assert_equals(exception, null, "Unexpected exception when evaluating object");2205 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2206 // Call do_interface_attribute_asserts last, since it will call a_test.done()2207 this.do_interface_attribute_asserts(obj, member, a_test);2208 }.bind(this));2209 }2210 else if (member.type == "operation" &&2211 member.name &&2212 member.isUnforgeable)2213 {2214 var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"');2215 a_test.step(function()2216 {2217 assert_equals(exception, null, "Unexpected exception when evaluating object");2218 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2219 assert_own_property(obj, member.name,2220 "Doesn't have the unforgeable operation property");2221 this.do_member_operation_asserts(obj, member, a_test);2222 }.bind(this));2223 }2224 else if ((member.type == "const"2225 || member.type == "attribute"2226 || member.type == "operation")2227 && member.name)2228 {2229 var described_name = member.name;2230 if (member.type == "operation")2231 {2232 described_name += "(" + member.arguments.map(arg => arg.idlType.idlType).join(", ") + ")";2233 }2234 test(function()2235 {2236 assert_equals(exception, null, "Unexpected exception when evaluating object");2237 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2238 if (!member["static"]) {2239 if (!this.is_global()) {2240 assert_inherits(obj, member.name);2241 } else {2242 assert_own_property(obj, member.name);2243 }2244 if (member.type == "const")2245 {2246 assert_equals(obj[member.name], constValue(member.value));2247 }2248 if (member.type == "attribute")2249 {2250 // Attributes are accessor properties, so they might2251 // legitimately throw an exception rather than returning2252 // anything.2253 var property, thrown = false;2254 try2255 {2256 property = obj[member.name];2257 }2258 catch (e)2259 {2260 thrown = true;2261 }2262 if (!thrown)2263 {2264 this.array.assert_type_is(property, member.idlType);2265 }2266 }2267 if (member.type == "operation")2268 {2269 assert_equals(typeof obj[member.name], "function");2270 }2271 }2272 }.bind(this), this.name + " interface: " + desc + ' must inherit property "' + described_name + '" with the proper type');2273 }2274 // TODO: This is wrong if there are multiple operations with the same2275 // identifier.2276 // TODO: Test passing arguments of the wrong type.2277 if (member.type == "operation" && member.name && member.arguments.length)2278 {2279 var a_test = async_test( this.name + " interface: calling " + member.name +2280 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }).join(", ") +2281 ") on " + desc + " with too few arguments must throw TypeError");2282 a_test.step(function()2283 {2284 assert_equals(exception, null, "Unexpected exception when evaluating object");2285 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2286 var fn;2287 if (!member["static"]) {2288 if (!this.is_global() && !member.isUnforgeable) {2289 assert_inherits(obj, member.name);2290 } else {2291 assert_own_property(obj, member.name);2292 }2293 fn = obj[member.name];2294 }2295 else2296 {2297 assert_own_property(obj.constructor, member.name, "interface object must have static operation as own property");2298 fn = obj.constructor[member.name];2299 }2300 var minLength = minOverloadLength(this.members.filter(function(m) {2301 return m.type == "operation" && m.name == member.name;2302 }));2303 var args = [];2304 var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test));2305 for (var i = 0; i < minLength; i++) {2306 throwOrReject(a_test, member, fn, obj, args, "Called with " + i + " arguments", cb);2307 args.push(create_suitable_object(member.arguments[i].idlType));2308 }2309 if (minLength === 0) {2310 cb();2311 }2312 }.bind(this));2313 }2314 if (member.is_to_json_regular_operation()) {2315 this.test_to_json_operation(obj, member);2316 }2317 }2318};2319//@}2320IdlInterface.prototype.has_stringifier = function()2321//@{2322{2323 if (this.name === "DOMException") {2324 // toString is inherited from Error, so don't assume we have the2325 // default stringifer2326 return true;2327 }2328 if (this.members.some(function(member) { return member.stringifier; })) {2329 return true;2330 }2331 if (this.base &&2332 this.array.members[this.base].has_stringifier()) {2333 return true;2334 }2335 return false;2336};2337//@}2338IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_test)2339//@{2340{2341 // This function tests WebIDL as of 2015-01-27.2342 // TODO: Consider [Exposed].2343 // This is called by test_member_attribute() with the prototype as obj if2344 // it is not a global, and the global otherwise, and by test_interface_of()2345 // with the object as obj.2346 var pendingPromises = [];2347 // "For each exposed attribute of the interface, whether it was declared on2348 // the interface itself or one of its consequential interfaces, there MUST2349 // exist a corresponding property. The characteristics of this property are2350 // as follows:"2351 // "The name of the property is the identifier of the attribute."2352 assert_own_property(obj, member.name);2353 // "The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]:2354 // true, [[Configurable]]: configurable }, where:2355 // "configurable is false if the attribute was declared with the2356 // [Unforgeable] extended attribute and true otherwise;2357 // "G is the attribute getter, defined below; and2358 // "S is the attribute setter, also defined below."2359 var desc = Object.getOwnPropertyDescriptor(obj, member.name);2360 assert_false("value" in desc, 'property descriptor should not have a "value" field');2361 assert_false("writable" in desc, 'property descriptor should not have a "writable" field');2362 assert_true(desc.enumerable, "property should be enumerable");2363 if (member.isUnforgeable)2364 {2365 assert_false(desc.configurable, "[Unforgeable] property must not be configurable");2366 }2367 else2368 {2369 assert_true(desc.configurable, "property must be configurable");2370 }2371 // "The attribute getter is a Function object whose behavior when invoked2372 // is as follows:"2373 assert_equals(typeof desc.get, "function", "getter must be Function");2374 // "If the attribute is a regular attribute, then:"2375 if (!member["static"]) {2376 // "If O is not a platform object that implements I, then:2377 // "If the attribute was specified with the [LenientThis] extended2378 // attribute, then return undefined.2379 // "Otherwise, throw a TypeError."2380 if (!member.has_extended_attribute("LenientThis")) {2381 if (member.idlType.generic !== "Promise") {2382 assert_throws(new TypeError(), function() {2383 desc.get.call({});2384 }.bind(this), "calling getter on wrong object type must throw TypeError");2385 } else {2386 pendingPromises.push(2387 promise_rejects(a_test, new TypeError(), desc.get.call({}),2388 "calling getter on wrong object type must reject the return promise with TypeError"));2389 }2390 } else {2391 assert_equals(desc.get.call({}), undefined,2392 "calling getter on wrong object type must return undefined");2393 }2394 }2395 // "The value of the Function object’s “length” property is the Number2396 // value 0."2397 assert_equals(desc.get.length, 0, "getter length must be 0");2398 // TODO: Test calling setter on the interface prototype (should throw2399 // TypeError in most cases).2400 if (member.readonly2401 && !member.has_extended_attribute("LenientSetter")2402 && !member.has_extended_attribute("PutForwards")2403 && !member.has_extended_attribute("Replaceable"))2404 {2405 // "The attribute setter is undefined if the attribute is declared2406 // readonly and has neither a [PutForwards] nor a [Replaceable]2407 // extended attribute declared on it."2408 assert_equals(desc.set, undefined, "setter must be undefined for readonly attributes");2409 }2410 else2411 {2412 // "Otherwise, it is a Function object whose behavior when2413 // invoked is as follows:"2414 assert_equals(typeof desc.set, "function", "setter must be function for PutForwards, Replaceable, or non-readonly attributes");2415 // "If the attribute is a regular attribute, then:"2416 if (!member["static"]) {2417 // "If /validThis/ is false and the attribute was not specified2418 // with the [LenientThis] extended attribute, then throw a2419 // TypeError."2420 // "If the attribute is declared with a [Replaceable] extended2421 // attribute, then: ..."2422 // "If validThis is false, then return."2423 if (!member.has_extended_attribute("LenientThis")) {2424 assert_throws(new TypeError(), function() {2425 desc.set.call({});2426 }.bind(this), "calling setter on wrong object type must throw TypeError");2427 } else {2428 assert_equals(desc.set.call({}), undefined,2429 "calling setter on wrong object type must return undefined");2430 }2431 }2432 // "The value of the Function object’s “length” property is the Number2433 // value 1."2434 assert_equals(desc.set.length, 1, "setter length must be 1");2435 }2436 Promise.all(pendingPromises).then(a_test.done.bind(a_test));2437}2438//@}2439/// IdlInterfaceMember ///2440function IdlInterfaceMember(obj)2441//@{2442{2443 /**2444 * obj is an object produced by the WebIDLParser.js "ifMember" production.2445 * We just forward all properties to this object without modification,2446 * except for special extAttrs handling.2447 */2448 for (var k in obj)2449 {2450 this[k] = obj[k];2451 }2452 if (!("extAttrs" in this))2453 {2454 this.extAttrs = [];2455 }2456 this.isUnforgeable = this.has_extended_attribute("Unforgeable");2457 this.isUnscopable = this.has_extended_attribute("Unscopable");2458}2459//@}2460IdlInterfaceMember.prototype = Object.create(IdlObject.prototype);2461IdlInterfaceMember.prototype.is_to_json_regular_operation = function() {2462 return this.type == "operation" && !this.static && this.name == "toJSON";2463};2464/// Internal helper functions ///2465function create_suitable_object(type)2466//@{2467{2468 /**2469 * type is an object produced by the WebIDLParser.js "type" production. We2470 * return a JavaScript value that matches the type, if we can figure out2471 * how.2472 */2473 if (type.nullable)2474 {2475 return null;2476 }2477 switch (type.idlType)2478 {2479 case "any":2480 case "boolean":2481 return true;2482 case "byte": case "octet": case "short": case "unsigned short":2483 case "long": case "unsigned long": case "long long":2484 case "unsigned long long": case "float": case "double":2485 case "unrestricted float": case "unrestricted double":2486 return 7;2487 case "DOMString":2488 case "ByteString":2489 case "USVString":2490 return "foo";2491 case "object":2492 return {a: "b"};2493 case "Node":2494 return document.createTextNode("abc");2495 }2496 return null;2497}2498//@}2499/// IdlEnum ///2500// Used for IdlArray.prototype.assert_type_is2501function IdlEnum(obj)2502//@{2503{2504 /**2505 * obj is an object produced by the WebIDLParser.js "dictionary"2506 * production.2507 */2508 /** Self-explanatory. */2509 this.name = obj.name;2510 /** An array of values produced by the "enum" production. */2511 this.values = obj.values;2512}2513//@}2514IdlEnum.prototype = Object.create(IdlObject.prototype);2515/// IdlTypedef ///2516// Used for IdlArray.prototype.assert_type_is2517function IdlTypedef(obj)2518//@{2519{2520 /**2521 * obj is an object produced by the WebIDLParser.js "typedef"2522 * production.2523 */2524 /** Self-explanatory. */2525 this.name = obj.name;2526 /** The idlType that we are supposed to be typedeffing to. */2527 this.idlType = obj.idlType;2528}2529//@}2530IdlTypedef.prototype = Object.create(IdlObject.prototype);2531}());...

Full Screen

Full Screen

sidebars.js

Source:sidebars.js Github

copy

Full Screen

1module.exports = {2 someSidebar: {3 'Getting Started': [4 'getting_started/quick_start',5 'getting_started/using_the_generator',6 'getting_started/mutation',7 'getting_started/pagination',8 'getting_started/error',9 'getting_started/middleware',10 ],11 Concept: [12 'concept/spec',13 'concept/schema',14 'concept/contracts',15 'concept/data_structure',16 'concept/offline',17 ],18 'API Reference': [19 'api/data_fetcher',20 'api/environment',21 'api/use_fetch',22 'api/use_mutation',23 'api/use_pagination',24 'api/use_refetch',25 ],26 Recipes: [27 'recipes/custom_data_hook',28 'recipes/data_component',29 'recipes/dep_chain',30 ],31 },...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org');3var options = {4};5 if (err) return console.error(err);6 wpt.getTestResults(data.data.testId, function(err, data) {7 if (err) return console.error(err);8 console.log(data.data.average.firstView);9 });10});11var wpt = require('webpagetest');12var wpt = new WebPageTest('www.webpagetest.org');13var options = {14};15 if (err) return console.error(err);16 wpt.getTestResults(data.data.testId, function(err, data) {17 if (err) return console.error(err);18 console.log(data.data.average.firstView);19 });20});21var wpt = require('webpagetest');22var wpt = new WebPageTest('www.webpagetest.org');23var options = {24};25 if (err) return console.error(err);26 wpt.getTestResults(data.data.testId, function(err, data) {27 if (err) return console.error(err);28 console.log(data.data.average.firstView);29 });30});31var wpt = require('webpagetest');32var wpt = new WebPageTest('www.webpagetest.org');33var options = {34};

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var options = {3};4var wpt = new WebPageTest('www.webpagetest.org', options.key);5 if (err) return console.log(err);6 console.log('Waiting for results...');7 wpt.getTestResults(data.data.testId, function(err, data) {8 if (err) return console.log(err);9 console.log('Got results!');10 console.log(data);11 });12});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var options = {3};4var wpt = new WebPageTest(options);5 console.log(data);6});7var wpt = require('webpagetest');8var options = {9};10var wpt = new WebPageTest(options);11 console.log(data);12});13var wpt = require('webpagetest');14var options = {15};16var wpt = new WebPageTest(options);17 console.log(data);18});19var wpt = require('webpagetest');20var options = {21};22var wpt = new WebPageTest(options);23 console.log(data);24});25var wpt = require('webpagetest');26var options = {27};28var wpt = new WebPageTest(options);29 console.log(data);30});31var wpt = require('webpagetest');32var options = {33};34var wpt = new WebPageTest(options);35 console.log(data);36});37var wpt = require('webpagetest');38var options = {39};40var wpt = new WebPageTest(options);

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org');3var options = {4};5wpt.dep_chain(url, options, function(err, data) {6 if (err) return console.error(err);7 console.log(data);8});9var wpt = require('webpagetest');10var wpt = new WebPageTest('www.webpagetest.org');11var options = {12};13wpt.dep_chain(url, options, function(err, data) {14 if (err) return console.error(err);15 console.log(data);16});17var wpt = require('webpagetest');18var wpt = new WebPageTest('www.webpagetest.org');19var options = {20};21wpt.dep_chain(url, options, function(err, data) {22 if (err) return console.error(err);23 console.log(data);24});25var wpt = require('webpagetest');26var wpt = new WebPageTest('www.webpagetest.org');27var options = {28};29wpt.dep_chain(url, options, function(err, data) {30 if (err) return console.error(err);31 console.log(data);32});33var wpt = require('webpagetest');34var wpt = new WebPageTest('www.webpagetest.org');35var options = {

Full Screen

Using AI Code Generation

copy

Full Screen

1const wpt = require('wpt');2 if(err){3 console.log(err);4 }else{5 console.log(data);6 }7});8const wpt = require('wpt');9 if(err){10 console.log(err);11 }else{12 console.log(data);13 }14});15const wpt = require('wpt');16 if(err){17 console.log(err);18 }else{19 console.log(data);20 }21});22const wpt = require('wpt');23 if(err){24 console.log(err);25 }else{26 console.log(data);27 }28});29const wpt = require('wpt');30 if(err){31 console.log(err);32 }else{33 console.log(data);34 }35});36const wpt = require('wpt');37 if(err){38 console.log(err);39 }else{40 console.log(data);41 }42});43const wpt = require('wpt');44 if(err){45 console.log(err);46 }else{47 console.log(data);48 }49});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var page = wptools.page('Albert Einstein');3page.get_dep_chain(function(err, res){4 if(err){5 console.log(err);6 }else{7 console.log(res);8 }9});10var wptools = require('wptools');11var page = wptools.page('Albert Einstein');12page.get_dep_chain(function(err, res){13 if(err){14 console.log(err);15 }else{16 console.log(res);17 }18});19var wptools = require('wptools');20var page = wptools.page('Albert Einstein');21page.get_dep_chain(function(err, res){22 if(err){23 console.log(err);24 }else{25 console.log(res);26 }27});28var wptools = require('wptools');29var page = wptools.page('Albert Einstein');30page.get_dep_chain(function(err, res){31 if(err){32 console.log(err);33 }else{34 console.log(res);35 }36});37var wptools = require('wptools');38var page = wptools.page('Albert Einstein');39page.get_dep_chain(function(err, res){40 if(err){41 console.log(err);42 }else{43 console.log(res);44 }45});46var wptools = require('wptools');47var page = wptools.page('Albert Einstein');48page.get_dep_chain(function(err, res){49 if(err){50 console.log(err);51 }else{52 console.log(res);53 }54});55var wptools = require('wptools');56var page = wptools.page('Albert Einstein');57page.get_dep_chain(function(err, res){58 if(err){59 console.log(err);60 }else{61 console.log(res);62 }63});64var wptools = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var dep_chain = wptools.dep_chain;3var chain = dep_chain('India');4chain.then(function (res) {5 console.log(res);6});7#### .page([pageName], [options], [callback])8* `pageName` - The name of the page. (optional)9* `options` - The options for the page. (optional)10* `callback` - The callback function. (optional)11var wptools = require('wptools');12var page = wptools.page('India');13page.then(function (res) {14 console.log(res);15});16#### .dep_chain([pageName], [options], [callback])17* `pageName` - The name of the page. (optional)18* `options` - The options for the page. (optional)19* `callback` - The callback function. (optional)20var wptools = require('wptools');21var dep_chain = wptools.dep_chain;22var chain = dep_chain('India');23chain.then(function (res) {24 console.log(res);25});26#### .get([options], [callback])27* `options` - The options for the page. (optional)28* `callback` - The callback function. (optional)29var wptools = require('wptools');30var page = wptools.page('India');31page.then(function (res) {32 console.log(res);33});34#### .getCategories([options], [callback])35* `options` - The options for the page. (optional)

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run wpt automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful