Best JavaScript code snippet using wpt
aflprep_idlharness.js
Source:aflprep_idlharness.js
...483 }484 return false;485 }486};487function exposure_set(object, default_set) {488 var exposed = object.extAttrs && object.extAttrs.filter(a => a.name === "Exposed");489 if (exposed && exposed.length > 1) {490 throw new IdlHarnessError(491 `Multiple 'Exposed' extended attributes on ${object.name}`);492 }493 let result = default_set || ["Window"];494 if (result && !(result instanceof Set)) {495 result = new Set(result);496 }497 if (exposed && exposed.length) {498 const { rhs } = exposed[0];499 const set = rhs.type === "identifier-list" ?500 rhs.value.map(id => id.value) :501 [ rhs.value ];502 result = new Set(set);503 }504 if (result && result.has("Worker")) {505 result.delete("Worker");506 result.add("DedicatedWorker");507 result.add("ServiceWorker");508 result.add("SharedWorker");509 }510 return result;511}512function exposed_in(globals) {513 if ('Window' in self) {514 return globals.has("Window");515 }516 if ('DedicatedWorkerGlobalScope' in self &&517 self instanceof DedicatedWorkerGlobalScope) {518 return globals.has("DedicatedWorker");519 }520 if ('SharedWorkerGlobalScope' in self &&521 self instanceof SharedWorkerGlobalScope) {522 return globals.has("SharedWorker");523 }524 if ('ServiceWorkerGlobalScope' in self &&525 self instanceof ServiceWorkerGlobalScope) {526 return globals.has("ServiceWorker");527 }528 throw new IdlHarnessError("Unexpected global object");529}530 * Asserts that the given error message is thrown for the given function.531 * @param {string|IdlHarnessError} error Expected Error message.532 * @param {Function} idlArrayFunc Function operating on an IdlArray that should throw.533IdlArray.prototype.assert_throws = function(error, idlArrayFunc)534{535 try {536 idlArrayFunc.call(this, this);537 } catch (e) {538 if (e instanceof AssertionError) {539 throw e;540 }541 if (error instanceof IdlHarnessError) {542 error = error.message;543 }544 if (e.message !== error) {545 throw new IdlHarnessError(`${idlArrayFunc} threw "${e}", not the expected IdlHarnessError "${error}"`);546 }547 return;548 }549 throw new IdlHarnessError(`${idlArrayFunc} did not throw the expected IdlHarnessError`);550}551IdlArray.prototype.test = function()552{553 this.merge_partials();554 this.merge_mixins();555 for (const member of Object.values(this.members).filter(m => m.base)) {556 const lhs = member.name;557 const rhs = member.base;558 if (!(rhs in this.members)) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is undefined.`);559 const lhs_is_interface = this.members[lhs] instanceof IdlInterface;560 const rhs_is_interface = this.members[rhs] instanceof IdlInterface;561 if (rhs_is_interface != lhs_is_interface) {562 if (!lhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${lhs} is not an interface.`);563 if (!rhs_is_interface) throw new IdlHarnessError(`${lhs} inherits ${rhs}, but ${rhs} is not an interface.`);564 }565 member.get_reverse_inheritance_stack();566 }567 Object.getOwnPropertyNames(this.members).forEach(function(memberName) {568 var member = this.members[memberName];569 if (!(member instanceof IdlInterface)) {570 return;571 }572 var globals = exposure_set(member);573 member.exposed = exposed_in(globals);574 member.exposureSet = globals;575 }.bind(this));576 for (var name in this.members)577 {578 this.members[name].test();579 if (name in this.objects)580 {581 const objects = this.objects[name];582 if (!objects || !Array.isArray(objects)) {583 throw new IdlHarnessError(`Invalid or empty objects for member ${name}`);584 }585 objects.forEach(function(str)586 {587 if (!this.members[name] || !(this.members[name] instanceof IdlInterface)) {588 throw new IdlHarnessError(`Invalid object member name ${name}`);589 }590 this.members[name].test_object(str);591 }.bind(this));592 }593 }594};595IdlArray.prototype.merge_partials = function()596{597 const testedPartials = new Map();598 this.partials.forEach(function(parsed_idl)599 {600 const originalExists = parsed_idl.name in this.members601 && (this.members[parsed_idl.name] instanceof IdlInterface602 || this.members[parsed_idl.name] instanceof IdlDictionary603 || this.members[parsed_idl.name] instanceof IdlNamespace);604 let partialTestName = parsed_idl.name;605 let partialTestCount = 1;606 if (testedPartials.has(parsed_idl.name)) {607 partialTestCount += testedPartials.get(parsed_idl.name);608 partialTestName = `${partialTestName}[${partialTestCount}]`;609 }610 testedPartials.set(parsed_idl.name, partialTestCount);611 if (!parsed_idl.untested) {612 test(function () {613 assert_true(originalExists, `Original ${parsed_idl.type} should be defined`);614 var expected;615 switch (parsed_idl.type) {616 case 'dictionary': expected = IdlDictionary; break;617 case 'namespace': expected = IdlNamespace; break;618 case 'interface':619 case 'interface mixin':620 default:621 expected = IdlInterface; break;622 }623 assert_true(624 expected.prototype.isPrototypeOf(this.members[parsed_idl.name]),625 `Original ${parsed_idl.name} definition should have type ${parsed_idl.type}`);626 }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: original ${parsed_idl.type} defined`);627 }628 if (!originalExists) {629 return;630 }631 if (parsed_idl.extAttrs)632 {633 const exposureAttr = parsed_idl.extAttrs.find(a => a.name === "Exposed");634 if (exposureAttr) {635 if (!parsed_idl.untested) {636 test(function () {637 const partialExposure = exposure_set(parsed_idl);638 const memberExposure = exposure_set(this.members[parsed_idl.name]);639 partialExposure.forEach(name => {640 if (!memberExposure || !memberExposure.has(name)) {641 throw new IdlHarnessError(642 `Partial ${parsed_idl.name} ${parsed_idl.type} is exposed to '${name}', the original ${parsed_idl.type} is not.`);643 }644 });645 }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: valid exposure set`);646 }647 parsed_idl.members.forEach(function (member) {648 member.extAttrs.push(exposureAttr);649 }.bind(this));650 }651 parsed_idl.extAttrs.forEach(function(extAttr)652 {653 if (extAttr.name === "Exposed") {654 return;655 }656 this.members[parsed_idl.name].extAttrs.push(extAttr);657 }.bind(this));658 }659 if (parsed_idl.members.length) {660 test(function () {661 var clash = parsed_idl.members.find(function(member) {662 return this.members[parsed_idl.name].members.find(function(m) {663 return this.are_duplicate_members(m, member);664 }.bind(this));665 }.bind(this));666 parsed_idl.members.forEach(function(member)667 {668 this.members[parsed_idl.name].members.push(new IdlInterfaceMember(member));669 }.bind(this));670 assert_true(!clash, "member " + (clash && clash.name) + " is unique");671 }.bind(this), `Partial ${parsed_idl.type} ${partialTestName}: member names are unique`);672 }673 }.bind(this));674 this.partials = [];675}676IdlArray.prototype.merge_mixins = function()677{678 for (const parsed_idl of this.includes)679 {680 const lhs = parsed_idl.target;681 const rhs = parsed_idl.includes;682 var errStr = lhs + " includes " + rhs + ", but ";683 if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";684 if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";685 if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";686 if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";687 if (this.members[rhs].members.length) {688 test(function () {689 var clash = this.members[rhs].members.find(function(member) {690 return this.members[lhs].members.find(function(m) {691 return this.are_duplicate_members(m, member);692 }.bind(this));693 }.bind(this));694 this.members[rhs].members.forEach(function(member) {695 assert_true(696 this.members[lhs].members.every(m => !this.are_duplicate_members(m, member)),697 "member " + member.name + " is unique");698 this.members[lhs].members.push(new IdlInterfaceMember(member));699 }.bind(this));700 assert_true(!clash, "member " + (clash && clash.name) + " is unique");701 }.bind(this), lhs + " includes " + rhs + ": member names are unique");702 }703 }704 this.includes = [];705}706IdlArray.prototype.are_duplicate_members = function(m1, m2) {707 if (m1.name !== m2.name) {708 return false;709 }710 if (m1.type === 'operation' && m2.type === 'operation'711 && m1.arguments.length !== m2.arguments.length) {712 return false;713 }714 return true;715}716IdlArray.prototype.assert_type_is = function(value, type)717{718 if (type.idlType in this.members719 && this.members[type.idlType] instanceof IdlTypedef) {720 this.assert_type_is(value, this.members[type.idlType].idlType);721 return;722 }723 if (type.nullable && value === null)724 {725 return;726 }727 if (type.union) {728 for (var i = 0; i < type.idlType.length; i++) {729 try {730 this.assert_type_is(value, type.idlType[i]);731 return;732 } catch(e) {733 if (e instanceof AssertionError) {734 continue;735 }736 throw e;737 }738 }739 assert_true(false, "Attribute has value " + format_value(value)740 + " which doesn't match any of the types in the union");741 }742 * Helper function that tests that value is an instance of type according743 * to the rules of WebIDL. value is any JavaScript value, and type is an744 * object produced by WebIDLParser.js' "type" production. That production745 * is fairly elaborate due to the complexity of WebIDL's types, so it's746 * best to look at the grammar to figure out what properties it might have.747 if (type.idlType == "any")748 {749 return;750 }751 if (type.array)752 {753 return;754 }755 if (type.generic === "sequence")756 {757 assert_true(Array.isArray(value), "should be an Array");758 if (!value.length)759 {760 return;761 }762 this.assert_type_is(value[0], type.idlType[0]);763 return;764 }765 if (type.generic === "Promise") {766 assert_true("then" in value, "Attribute with a Promise type should have a then property");767 return;768 }769 if (type.generic === "FrozenArray") {770 assert_true(Array.isArray(value), "Value should be array");771 assert_true(Object.isFrozen(value), "Value should be frozen");772 if (!value.length)773 {774 return;775 }776 this.assert_type_is(value[0], type.idlType[0]);777 return;778 }779 type = Array.isArray(type.idlType) ? type.idlType[0] : type.idlType;780 switch(type)781 {782 case "undefined":783 assert_equals(value, undefined);784 return;785 case "boolean":786 assert_equals(typeof value, "boolean");787 return;788 case "byte":789 assert_equals(typeof value, "number");790 assert_equals(value, Math.floor(value), "should be an integer");791 assert_true(-128 <= value && value <= 127, "byte " + value + " should be in range [-128, 127]");792 return;793 case "octet":794 assert_equals(typeof value, "number");795 assert_equals(value, Math.floor(value), "should be an integer");796 assert_true(0 <= value && value <= 255, "octet " + value + " should be in range [0, 255]");797 return;798 case "short":799 assert_equals(typeof value, "number");800 assert_equals(value, Math.floor(value), "should be an integer");801 assert_true(-32768 <= value && value <= 32767, "short " + value + " should be in range [-32768, 32767]");802 return;803 case "unsigned short":804 assert_equals(typeof value, "number");805 assert_equals(value, Math.floor(value), "should be an integer");806 assert_true(0 <= value && value <= 65535, "unsigned short " + value + " should be in range [0, 65535]");807 return;808 case "long":809 assert_equals(typeof value, "number");810 assert_equals(value, Math.floor(value), "should be an integer");811 assert_true(-2147483648 <= value && value <= 2147483647, "long " + value + " should be in range [-2147483648, 2147483647]");812 return;813 case "unsigned long":814 assert_equals(typeof value, "number");815 assert_equals(value, Math.floor(value), "should be an integer");816 assert_true(0 <= value && value <= 4294967295, "unsigned long " + value + " should be in range [0, 4294967295]");817 return;818 case "long long":819 assert_equals(typeof value, "number");820 return;821 case "unsigned long long":822 case "DOMTimeStamp":823 assert_equals(typeof value, "number");824 assert_true(0 <= value, "unsigned long long should be positive");825 return;826 case "float":827 assert_equals(typeof value, "number");828 assert_equals(value, Math.fround(value), "float rounded to 32-bit float should be itself");829 assert_not_equals(value, Infinity);830 assert_not_equals(value, -Infinity);831 assert_not_equals(value, NaN);832 return;833 case "DOMHighResTimeStamp":834 case "double":835 assert_equals(typeof value, "number");836 assert_not_equals(value, Infinity);837 assert_not_equals(value, -Infinity);838 assert_not_equals(value, NaN);839 return;840 case "unrestricted float":841 assert_equals(typeof value, "number");842 assert_equals(value, Math.fround(value), "unrestricted float rounded to 32-bit float should be itself");843 return;844 case "unrestricted double":845 assert_equals(typeof value, "number");846 return;847 case "DOMString":848 assert_equals(typeof value, "string");849 return;850 case "ByteString":851 assert_equals(typeof value, "string");852 return;853 case "USVString":854 assert_equals(typeof value, "string");855 return;856 case "ArrayBufferView":857 assert_true(ArrayBuffer.isView(value));858 return;859 case "object":860 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");861 return;862 }863 if (!(type in this.members))864 {865 assert_true(value instanceof self[type], "wrong type: not a " + type);866 return;867 }868 if (this.members[type] instanceof IdlInterface)869 {870 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");871 if (value instanceof Object872 && !this.members[type].has_extended_attribute("LegacyNoInterfaceObject")873 && type in self)874 {875 assert_true(value instanceof self[type], "instanceof " + type);876 }877 }878 else if (this.members[type] instanceof IdlEnum)879 {880 assert_equals(typeof value, "string");881 }882 else if (this.members[type] instanceof IdlDictionary)883 {884 }885 else if (this.members[type] instanceof IdlCallback)886 {887 assert_equals(typeof value, "function");888 }889 else890 {891 throw new IdlHarnessError("Type " + type + " isn't an interface, callback or dictionary");892 }893};894function IdlObject() {}895IdlObject.prototype.test = function()896{897 * By default, this does nothing, so no actual tests are run for IdlObjects898 * that don't define any (e.g., IdlDictionary at the time of this writing).899};900IdlObject.prototype.has_extended_attribute = function(name)901{902 * This is only meaningful for things that support extended attributes,903 * such as interfaces, exceptions, and members.904 return this.extAttrs.some(function(o)905 {906 return o.name == name;907 });908};909function IdlDictionary(obj)910{911 * obj is an object produced by the WebIDLParser.js "dictionary"912 * production.913 this.name = obj.name;914 this.array = obj.array;915 this.members = obj.members;916 * The name (as a string) of the dictionary type we inherit from, or null917 * if there is none.918 this.base = obj.inheritance;919}920IdlDictionary.prototype = Object.create(IdlObject.prototype);921IdlDictionary.prototype.get_reverse_inheritance_stack = function() {922 return IdlInterface.prototype.get_reverse_inheritance_stack.call(this);923};924function IdlInterface(obj, is_callback, is_mixin)925{926 * obj is an object produced by the WebIDLParser.js "interface" production.927 this.name = obj.name;928 this.array = obj.array;929 * An indicator of whether we should run tests on the interface object and930 * interface prototype object. Tests on members are controlled by .untested931 * on each member, not this.932 this.untested = obj.untested;933 this.extAttrs = obj.extAttrs;934 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m); });935 if (this.has_extended_attribute("LegacyUnforgeable")) {936 this.members937 .filter(function(m) { return m.special !== "static" && (m.type == "attribute" || m.type == "operation"); })938 .forEach(function(m) { return m.isUnforgeable = true; });939 }940 * The name (as a string) of the type we inherit from, or null if there is941 * none.942 this.base = obj.inheritance;943 this._is_callback = is_callback;944 this._is_mixin = is_mixin;945}946IdlInterface.prototype = Object.create(IdlObject.prototype);947IdlInterface.prototype.is_callback = function()948{949 return this._is_callback;950};951IdlInterface.prototype.is_mixin = function()952{953 return this._is_mixin;954};955IdlInterface.prototype.has_constants = function()956{957 return this.members.some(function(member) {958 return member.type === "const";959 });960};961IdlInterface.prototype.get_unscopables = function()962{963 return this.members.filter(function(member) {964 return member.isUnscopable;965 });966};967IdlInterface.prototype.is_global = function()968{969 return this.extAttrs.some(function(attribute) {970 return attribute.name === "Global";971 });972};973 * Value of the LegacyNamespace extended attribute, if any.974 *975IdlInterface.prototype.get_legacy_namespace = function()976{977 var legacyNamespace = this.extAttrs.find(function(attribute) {978 return attribute.name === "LegacyNamespace";979 });980 return legacyNamespace ? legacyNamespace.rhs.value : undefined;981};982IdlInterface.prototype.get_interface_object_owner = function()983{984 var legacyNamespace = this.get_legacy_namespace();985 return legacyNamespace ? self[legacyNamespace] : self;986};987IdlInterface.prototype.should_have_interface_object = function()988{989 return this.is_callback() ? this.has_constants() : !this.has_extended_attribute("LegacyNoInterfaceObject");990};991IdlInterface.prototype.assert_interface_object_exists = function()992{993 var owner = this.get_legacy_namespace() || "self";994 assert_own_property(self[owner], this.name, owner + " does not have own property " + format_value(this.name));995};996IdlInterface.prototype.get_interface_object = function() {997 if (!this.should_have_interface_object()) {998 var reason = this.is_callback() ? "lack of declared constants" : "declared [LegacyNoInterfaceObject] attribute";999 throw new IdlHarnessError(this.name + " has no interface object due to " + reason);1000 }1001 return this.get_interface_object_owner()[this.name];1002};1003IdlInterface.prototype.get_qualified_name = function() {1004 var legacyNamespace = this.get_legacy_namespace();1005 if (legacyNamespace) {1006 return legacyNamespace + "." + this.name;1007 }1008 return this.name;1009};1010IdlInterface.prototype.has_to_json_regular_operation = function() {1011 return this.members.some(function(m) {1012 return m.is_to_json_regular_operation();1013 });1014};1015IdlInterface.prototype.has_default_to_json_regular_operation = function() {1016 return this.members.some(function(m) {1017 return m.is_to_json_regular_operation() && m.has_extended_attribute("Default");1018 });1019};1020 * with the order reversed.1021 *1022 * The order is reversed so that the base class comes first in the list, because1023 * this is what all call sites need.1024 *1025 * So given:1026 *1027 * A : B {};1028 * B : C {};1029 * C {};1030 *1031 * then A.get_reverse_inheritance_stack() returns [C, B, A],1032 * and B.get_reverse_inheritance_stack() returns [C, B].1033 *1034 * Note: as dictionary inheritance is expressed identically by the AST,1035 * this works just as well for getting a stack of inherited dictionaries.1036IdlInterface.prototype.get_reverse_inheritance_stack = function() {1037 const stack = [this];1038 let idl_interface = this;1039 while (idl_interface.base) {1040 const base = this.array.members[idl_interface.base];1041 if (!base) {1042 throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")");1043 } else if (stack.indexOf(base) > -1) {1044 stack.unshift(base);1045 const dep_chain = stack.map(i => i.name).join(',');1046 throw new IdlHarnessError(`${this.name} has a circular dependency: ${dep_chain}`);1047 }1048 idl_interface = base;1049 stack.unshift(idl_interface);1050 }1051 return stack;1052};1053 * Implementation of1054 * for testing purposes.1055 *1056 * Collects the IDL types of the attributes that meet the criteria1057 * for inclusion in the default toJSON operation for easy1058 * comparison with actual value1059IdlInterface.prototype.default_to_json_operation = function() {1060 const map = new Map()1061 let isDefault = false;1062 for (const I of this.get_reverse_inheritance_stack()) {1063 if (I.has_default_to_json_regular_operation()) {1064 isDefault = true;1065 for (const m of I.members) {1066 if (m.special !== "static" && m.type == "attribute" && I.array.is_json_type(m.idlType)) {1067 map.set(m.name, m.idlType);1068 }1069 }1070 } else if (I.has_to_json_regular_operation()) {1071 isDefault = false;1072 }1073 }1074 return isDefault ? map : null;1075};1076IdlInterface.prototype.test = function()1077{1078 if (this.has_extended_attribute("LegacyNoInterfaceObject") || this.is_mixin())1079 {1080 return;1081 }1082 if (!this.exposed)1083 {1084 if (!this.untested)1085 {1086 subsetTestByKey(this.name, test, function() {1087 assert_false(this.name in self);1088 }.bind(this), this.name + " interface: existence and properties of interface object");1089 }1090 return;1091 }1092 if (!this.untested)1093 {1094 this.test_self();1095 }1096 this.test_members();1097};1098IdlInterface.prototype.constructors = function()1099{1100 return this.members1101 .filter(function(m) { return m.type == "constructor"; });1102}1103IdlInterface.prototype.test_self = function()1104{1105 subsetTestByKey(this.name, test, function()1106 {1107 if (!this.should_have_interface_object()) {1108 return;1109 }1110 this.assert_interface_object_exists();1111 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object_owner(), this.name);1112 assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter");1113 assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter");1114 assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable");1115 assert_false(desc.enumerable, "self's property " + format_value(this.name) + " should not be enumerable");1116 assert_true(desc.configurable, "self's property " + format_value(this.name) + " should be configurable");1117 if (this.is_callback()) {1118 assert_equals(Object.getPrototypeOf(this.get_interface_object()), Function.prototype,1119 "prototype of self's property " + format_value(this.name) + " is not Object.prototype");1120 return;1121 }1122 assert_class_string(this.get_interface_object(), "Function", "class string of " + this.name);1123 var prototype = Object.getPrototypeOf(this.get_interface_object());1124 if (this.base) {1125 var inherited_interface = this.array.members[this.base];1126 if (!inherited_interface.has_extended_attribute("LegacyNoInterfaceObject")) {1127 inherited_interface.assert_interface_object_exists();1128 assert_equals(prototype, inherited_interface.get_interface_object(),1129 'prototype of ' + this.name + ' is not ' +1130 this.base);1131 }1132 } else {1133 assert_equals(prototype, Function.prototype,1134 "prototype of self's property " + format_value(this.name) + " is not Function.prototype");1135 }1136 assert_true(isConstructor(this.get_interface_object()), "interface object must pass IsConstructor check");1137 if (!this.constructors().length) {1138 var interface_object = this.get_interface_object();1139 assert_throws_js(globalOf(interface_object).TypeError, function() {1140 interface_object();1141 }, "interface object didn't throw TypeError when called as a function");1142 assert_throws_js(globalOf(interface_object).TypeError, function() {1143 new interface_object();1144 }, "interface object didn't throw TypeError when called as a constructor");1145 }1146 }.bind(this), this.name + " interface: existence and properties of interface object");1147 if (this.should_have_interface_object() && !this.is_callback()) {1148 subsetTestByKey(this.name, test, function() {1149 this.assert_interface_object_exists();1150 assert_own_property(this.get_interface_object(), "length");1151 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "length");1152 assert_false("get" in desc, this.name + ".length should not have a getter");1153 assert_false("set" in desc, this.name + ".length should not have a setter");1154 assert_false(desc.writable, this.name + ".length should not be writable");1155 assert_false(desc.enumerable, this.name + ".length should not be enumerable");1156 assert_true(desc.configurable, this.name + ".length should be configurable");1157 var constructors = this.constructors();1158 var expected_length = minOverloadLength(constructors);1159 assert_equals(this.get_interface_object().length, expected_length, "wrong value for " + this.name + ".length");1160 }.bind(this), this.name + " interface object length");1161 }1162 if (this.should_have_interface_object()) {1163 subsetTestByKey(this.name, test, function() {1164 this.assert_interface_object_exists();1165 assert_own_property(this.get_interface_object(), "name");1166 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "name");1167 assert_false("get" in desc, this.name + ".name should not have a getter");1168 assert_false("set" in desc, this.name + ".name should not have a setter");1169 assert_false(desc.writable, this.name + ".name should not be writable");1170 assert_false(desc.enumerable, this.name + ".name should not be enumerable");1171 assert_true(desc.configurable, this.name + ".name should be configurable");1172 assert_equals(this.get_interface_object().name, this.name, "wrong value for " + this.name + ".name");1173 }.bind(this), this.name + " interface object name");1174 }1175 if (this.has_extended_attribute("LegacyWindowAlias")) {1176 subsetTestByKey(this.name, test, function()1177 {1178 var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; });1179 if (aliasAttrs.length > 1) {1180 throw new IdlHarnessError("Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name);1181 }1182 if (this.is_callback()) {1183 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name);1184 }1185 if (!this.exposureSet.has("Window")) {1186 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window");1187 }1188 var rhs = aliasAttrs[0].rhs;1189 if (!rhs) {1190 throw new IdlHarnessError("Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier");1191 }1192 var aliases;1193 if (rhs.type === "identifier-list") {1194 aliases = rhs.value.map(id => id.value);1195 aliases = [ rhs.value ];1196 }1197 var alias;1198 if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) {1199 for (alias of aliases) {1200 assert_true(alias in self, alias + " should exist");1201 assert_equals(self[alias], this.get_interface_object(), "self." + alias + " should be the same value as self." + this.get_qualified_name());1202 var desc = Object.getOwnPropertyDescriptor(self, alias);1203 assert_equals(desc.value, this.get_interface_object(), "wrong value in " + alias + " property descriptor");1204 assert_true(desc.writable, alias + " should be writable");1205 assert_false(desc.enumerable, alias + " should not be enumerable");1206 assert_true(desc.configurable, alias + " should be configurable");1207 assert_false('get' in desc, alias + " should not have a getter");1208 assert_false('set' in desc, alias + " should not have a setter");1209 }1210 } else {1211 for (alias of aliases) {1212 assert_false(alias in self, alias + " should not exist");1213 }1214 }1215 }.bind(this), this.name + " interface: legacy window alias");1216 }1217 if (this.has_extended_attribute("LegacyFactoryFunction")) {1218 var constructors = this.extAttrs1219 .filter(function(attr) { return attr.name == "LegacyFactoryFunction"; });1220 if (constructors.length !== 1) {1221 throw new IdlHarnessError("Internal error: missing support for multiple LegacyFactoryFunction extended attributes");1222 }1223 var constructor = constructors[0];1224 var min_length = minOverloadLength([constructor]);1225 subsetTestByKey(this.name, test, function()1226 {1227 var name = constructor.rhs.value;1228 assert_own_property(self, name);1229 var desc = Object.getOwnPropertyDescriptor(self, name);1230 assert_equals(desc.value, self[name], "wrong value in " + name + " property descriptor");1231 assert_true(desc.writable, name + " should be writable");1232 assert_false(desc.enumerable, name + " should not be enumerable");1233 assert_true(desc.configurable, name + " should be configurable");1234 assert_false("get" in desc, name + " should not have a getter");1235 assert_false("set" in desc, name + " should not have a setter");1236 }.bind(this), this.name + " interface: named constructor");1237 subsetTestByKey(this.name, test, function()1238 {1239 var name = constructor.rhs.value;1240 var value = self[name];1241 assert_equals(typeof value, "function", "type of value in " + name + " property descriptor");1242 assert_not_equals(value, this.get_interface_object(), "wrong value in " + name + " property descriptor");1243 assert_equals(Object.getPrototypeOf(value), Function.prototype, "wrong value for " + name + "'s prototype");1244 }.bind(this), this.name + " interface: named constructor object");1245 subsetTestByKey(this.name, test, function()1246 {1247 var name = constructor.rhs.value;1248 var expected = this.get_interface_object().prototype;1249 var desc = Object.getOwnPropertyDescriptor(self[name], "prototype");1250 assert_equals(desc.value, expected, "wrong value for " + name + ".prototype");1251 assert_false(desc.writable, "prototype should not be writable");1252 assert_false(desc.enumerable, "prototype should not be enumerable");1253 assert_false(desc.configurable, "prototype should not be configurable");1254 assert_false("get" in desc, "prototype should not have a getter");1255 assert_false("set" in desc, "prototype should not have a setter");1256 }.bind(this), this.name + " interface: named constructor prototype property");1257 subsetTestByKey(this.name, test, function()1258 {1259 var name = constructor.rhs.value;1260 var desc = Object.getOwnPropertyDescriptor(self[name], "name");1261 assert_equals(desc.value, name, "wrong value for " + name + ".name");1262 assert_false(desc.writable, "name should not be writable");1263 assert_false(desc.enumerable, "name should not be enumerable");1264 assert_true(desc.configurable, "name should be configurable");1265 assert_false("get" in desc, "name should not have a getter");1266 assert_false("set" in desc, "name should not have a setter");1267 }.bind(this), this.name + " interface: named constructor name");1268 subsetTestByKey(this.name, test, function()1269 {1270 var name = constructor.rhs.value;1271 var desc = Object.getOwnPropertyDescriptor(self[name], "length");1272 assert_equals(desc.value, min_length, "wrong value for " + name + ".length");1273 assert_false(desc.writable, "length should not be writable");1274 assert_false(desc.enumerable, "length should not be enumerable");1275 assert_true(desc.configurable, "length should be configurable");1276 assert_false("get" in desc, "length should not have a getter");1277 assert_false("set" in desc, "length should not have a setter");1278 }.bind(this), this.name + " interface: named constructor length");1279 subsetTestByKey(this.name, test, function()1280 {1281 var name = constructor.rhs.value;1282 var args = constructor.arguments.map(function(arg) {1283 return create_suitable_object(arg.idlType);1284 });1285 assert_throws_js(globalOf(self[name]).TypeError, function() {1286 self[name](...args);1287 }.bind(this));1288 }.bind(this), this.name + " interface: named constructor without 'new'");1289 }1290 subsetTestByKey(this.name, test, function()1291 {1292 if (!this.should_have_interface_object()) {1293 return;1294 }1295 this.assert_interface_object_exists();1296 if (this.is_callback()) {1297 assert_false("prototype" in this.get_interface_object(),1298 this.name + ' should not have a "prototype" property');1299 return;1300 }1301 assert_own_property(this.get_interface_object(), "prototype",1302 'interface "' + this.name + '" does not have own property "prototype"');1303 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), "prototype");1304 assert_false("get" in desc, this.name + ".prototype should not have a getter");1305 assert_false("set" in desc, this.name + ".prototype should not have a setter");1306 assert_false(desc.writable, this.name + ".prototype should not be writable");1307 assert_false(desc.enumerable, this.name + ".prototype should not be enumerable");1308 assert_false(desc.configurable, this.name + ".prototype should not be configurable");1309 if (this.name === "Window") {1310 assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype),1311 'WindowProperties',1312 'Class name for prototype of Window' +1313 '.prototype is not "WindowProperties"');1314 } else {1315 var inherit_interface, inherit_interface_interface_object;1316 if (this.base) {1317 inherit_interface = this.base;1318 var parent = this.array.members[inherit_interface];1319 if (!parent.has_extended_attribute("LegacyNoInterfaceObject")) {1320 parent.assert_interface_object_exists();1321 inherit_interface_interface_object = parent.get_interface_object();1322 }1323 } else if (this.name === "DOMException") {1324 inherit_interface = 'Error';1325 inherit_interface_interface_object = self.Error;1326 } else {1327 inherit_interface = 'Object';1328 inherit_interface_interface_object = self.Object;1329 }1330 if (inherit_interface_interface_object) {1331 assert_not_equals(inherit_interface_interface_object, undefined,1332 'should inherit from ' + inherit_interface + ', but there is no such property');1333 assert_own_property(inherit_interface_interface_object, 'prototype',1334 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property');1335 assert_equals(Object.getPrototypeOf(this.get_interface_object().prototype),1336 inherit_interface_interface_object.prototype,1337 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype');1338 } else {1339 assert_class_string(Object.getPrototypeOf(this.get_interface_object().prototype),1340 inherit_interface + 'Prototype',1341 'Class name for prototype of ' + this.name +1342 '.prototype is not "' + inherit_interface + 'Prototype"');1343 }1344 }1345 if (!this.has_stringifier()) {1346 }1347 }.bind(this), this.name + " interface: existence and properties of interface prototype object");1348 if (this.is_global()) {1349 this.test_immutable_prototype("interface prototype object", this.get_interface_object().prototype);1350 }1351 subsetTestByKey(this.name, test, function()1352 {1353 if (!this.should_have_interface_object()) {1354 return;1355 }1356 this.assert_interface_object_exists();1357 if (this.is_callback()) {1358 assert_false("prototype" in this.get_interface_object(),1359 this.name + ' should not have a "prototype" property');1360 return;1361 }1362 assert_own_property(this.get_interface_object(), "prototype",1363 'interface "' + this.name + '" does not have own property "prototype"');1364 assert_own_property(this.get_interface_object().prototype, "constructor",1365 this.name + '.prototype does not have own property "constructor"');1366 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, "constructor");1367 assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter");1368 assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter");1369 assert_true(desc.writable, this.name + ".prototype.constructor should be writable");1370 assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable");1371 assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable");1372 assert_equals(this.get_interface_object().prototype.constructor, this.get_interface_object(),1373 this.name + '.prototype.constructor is not the same object as ' + this.name);1374 }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');1375 subsetTestByKey(this.name, test, function()1376 {1377 if (!this.should_have_interface_object()) {1378 return;1379 }1380 this.assert_interface_object_exists();1381 if (this.is_callback()) {1382 assert_false("prototype" in this.get_interface_object(),1383 this.name + ' should not have a "prototype" property');1384 return;1385 }1386 assert_own_property(this.get_interface_object(), "prototype",1387 'interface "' + this.name + '" does not have own property "prototype"');1388 var unscopables = this.get_unscopables().map(m => m.name);1389 var proto = this.get_interface_object().prototype;1390 if (unscopables.length != 0) {1391 assert_own_property(1392 proto, Symbol.unscopables,1393 this.name + '.prototype should have an @@unscopables property');1394 var desc = Object.getOwnPropertyDescriptor(proto, Symbol.unscopables);1395 assert_false("get" in desc,1396 this.name + ".prototype[Symbol.unscopables] should not have a getter");1397 assert_false("set" in desc, this.name + ".prototype[Symbol.unscopables] should not have a setter");1398 assert_false(desc.writable, this.name + ".prototype[Symbol.unscopables] should not be writable");1399 assert_false(desc.enumerable, this.name + ".prototype[Symbol.unscopables] should not be enumerable");1400 assert_true(desc.configurable, this.name + ".prototype[Symbol.unscopables] should be configurable");1401 assert_equals(desc.value, proto[Symbol.unscopables],1402 this.name + '.prototype[Symbol.unscopables] should be in the descriptor');1403 assert_equals(typeof desc.value, "object",1404 this.name + '.prototype[Symbol.unscopables] should be an object');1405 assert_equals(Object.getPrototypeOf(desc.value), null,1406 this.name + '.prototype[Symbol.unscopables] should have a null prototype');1407 assert_equals(Object.getOwnPropertySymbols(desc.value).length,1408 0,1409 this.name + '.prototype[Symbol.unscopables] should have the right number of symbol-named properties');1410 var observed = Object.getOwnPropertyNames(desc.value);1411 for (var prop of observed) {1412 assert_not_equals(unscopables.indexOf(prop),1413 -1,1414 this.name + '.prototype[Symbol.unscopables] has unexpected property "' + prop + '"');1415 }1416 } else {1417 assert_equals(Object.getOwnPropertyDescriptor(this.get_interface_object().prototype, Symbol.unscopables),1418 undefined,1419 this.name + '.prototype should not have @@unscopables');1420 }1421 }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s @@unscopables property');1422};1423IdlInterface.prototype.test_immutable_prototype = function(type, obj)1424{1425 if (typeof Object.setPrototypeOf !== "function") {1426 return;1427 }1428 subsetTestByKey(this.name, test, function(t) {1429 var originalValue = Object.getPrototypeOf(obj);1430 var newValue = Object.create(null);1431 t.add_cleanup(function() {1432 try {1433 Object.setPrototypeOf(obj, originalValue);1434 } catch (err) {}1435 });1436 assert_throws_js(TypeError, function() {1437 Object.setPrototypeOf(obj, newValue);1438 });1439 assert_equals(1440 Object.getPrototypeOf(obj),1441 originalValue,1442 "original value not modified"1443 );1444 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1445 "of " + type + " - setting to a new value via Object.setPrototypeOf " +1446 "should throw a TypeError");1447 subsetTestByKey(this.name, test, function(t) {1448 var originalValue = Object.getPrototypeOf(obj);1449 var newValue = Object.create(null);1450 t.add_cleanup(function() {1451 let setter = Object.getOwnPropertyDescriptor(1452 Object.prototype, '__proto__'1453 ).set;1454 try {1455 setter.call(obj, originalValue);1456 } catch (err) {}1457 });1458 let setter;1459 {1460 let cur = obj;1461 while (cur) {1462 const desc = Object.getOwnPropertyDescriptor(cur, "__proto__");1463 if (desc) {1464 setter = desc.set;1465 break;1466 }1467 cur = Object.getPrototypeOf(cur);1468 }1469 }1470 assert_throws_js(globalOf(setter).TypeError, function() {1471 obj.__proto__ = newValue;1472 });1473 assert_equals(1474 Object.getPrototypeOf(obj),1475 originalValue,1476 "original value not modified"1477 );1478 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1479 "of " + type + " - setting to a new value via __proto__ " +1480 "should throw a TypeError");1481 subsetTestByKey(this.name, test, function(t) {1482 var originalValue = Object.getPrototypeOf(obj);1483 var newValue = Object.create(null);1484 t.add_cleanup(function() {1485 try {1486 Reflect.setPrototypeOf(obj, originalValue);1487 } catch (err) {}1488 });1489 assert_false(Reflect.setPrototypeOf(obj, newValue));1490 assert_equals(1491 Object.getPrototypeOf(obj),1492 originalValue,1493 "original value not modified"1494 );1495 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1496 "of " + type + " - setting to a new value via Reflect.setPrototypeOf " +1497 "should return false");1498 subsetTestByKey(this.name, test, function() {1499 var originalValue = Object.getPrototypeOf(obj);1500 Object.setPrototypeOf(obj, originalValue);1501 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1502 "of " + type + " - setting to its original value via Object.setPrototypeOf " +1503 "should not throw");1504 subsetTestByKey(this.name, test, function() {1505 var originalValue = Object.getPrototypeOf(obj);1506 obj.__proto__ = originalValue;1507 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1508 "of " + type + " - setting to its original value via __proto__ " +1509 "should not throw");1510 subsetTestByKey(this.name, test, function() {1511 var originalValue = Object.getPrototypeOf(obj);1512 assert_true(Reflect.setPrototypeOf(obj, originalValue));1513 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1514 "of " + type + " - setting to its original value via Reflect.setPrototypeOf " +1515 "should return true");1516};1517IdlInterface.prototype.test_member_const = function(member)1518{1519 if (!this.has_constants()) {1520 throw new IdlHarnessError("Internal error: test_member_const called without any constants");1521 }1522 subsetTestByKey(this.name, test, function()1523 {1524 this.assert_interface_object_exists();1525 assert_own_property(this.get_interface_object(), member.name);1526 assert_equals(this.get_interface_object()[member.name], constValue(member.value),1527 "property has wrong value");1528 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name);1529 assert_false("get" in desc, "property should not have a getter");1530 assert_false("set" in desc, "property should not have a setter");1531 assert_false(desc.writable, "property should not be writable");1532 assert_true(desc.enumerable, "property should be enumerable");1533 assert_false(desc.configurable, "property should not be configurable");1534 }.bind(this), this.name + " interface: constant " + member.name + " on interface object");1535 subsetTestByKey(this.name, test, function()1536 {1537 this.assert_interface_object_exists();1538 if (this.is_callback()) {1539 assert_false("prototype" in this.get_interface_object(),1540 this.name + ' should not have a "prototype" property');1541 return;1542 }1543 assert_own_property(this.get_interface_object(), "prototype",1544 'interface "' + this.name + '" does not have own property "prototype"');1545 assert_own_property(this.get_interface_object().prototype, member.name);1546 assert_equals(this.get_interface_object().prototype[member.name], constValue(member.value),1547 "property has wrong value");1548 var desc = Object.getOwnPropertyDescriptor(this.get_interface_object(), member.name);1549 assert_false("get" in desc, "property should not have a getter");1550 assert_false("set" in desc, "property should not have a setter");1551 assert_false(desc.writable, "property should not be writable");1552 assert_true(desc.enumerable, "property should be enumerable");1553 assert_false(desc.configurable, "property should not be configurable");1554 }.bind(this), this.name + " interface: constant " + member.name + " on interface prototype object");1555};1556IdlInterface.prototype.test_member_attribute = function(member)1557 {1558 if (!shouldRunSubTest(this.name)) {1559 return;1560 }1561 var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: attribute " + member.name);1562 a_test.step(function()1563 {1564 if (!this.should_have_interface_object()) {1565 a_test.done();1566 return;1567 }1568 this.assert_interface_object_exists();1569 assert_own_property(this.get_interface_object(), "prototype",1570 'interface "' + this.name + '" does not have own property "prototype"');1571 if (member.special === "static") {1572 assert_own_property(this.get_interface_object(), member.name,1573 "The interface object must have a property " +1574 format_value(member.name));1575 a_test.done();1576 return;1577 }1578 this.do_member_unscopable_asserts(member);1579 if (this.is_global()) {1580 assert_own_property(self, member.name,1581 "The global object must have a property " +1582 format_value(member.name));1583 assert_false(member.name in this.get_interface_object().prototype,1584 "The prototype object should not have a property " +1585 format_value(member.name));1586 var getter = Object.getOwnPropertyDescriptor(self, member.name).get;1587 assert_equals(typeof(getter), "function",1588 format_value(member.name) + " must have a getter");1589 var gotValue;1590 var propVal;1591 try {1592 propVal = self[member.name];1593 gotValue = true;1594 } catch (e) {1595 gotValue = false;1596 }1597 if (gotValue) {1598 assert_equals(propVal, getter.call(undefined),1599 "Gets on a global should not require an explicit this");1600 }1601 this.do_interface_attribute_asserts(self, member, a_test);1602 } else {1603 assert_true(member.name in this.get_interface_object().prototype,1604 "The prototype object must have a property " +1605 format_value(member.name));1606 if (!member.has_extended_attribute("LegacyLenientThis")) {1607 if (member.idlType.generic !== "Promise") {1608 assert_throws_js(TypeError, function() {1609 this.get_interface_object().prototype[member.name];1610 }.bind(this), "getting property on prototype object must throw TypeError");1611 this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test);1612 } else {1613 promise_rejects_js(a_test, TypeError,1614 this.get_interface_object().prototype[member.name])1615 .then(a_test.step_func(function() {1616 this.do_interface_attribute_asserts(this.get_interface_object().prototype,1617 member, a_test);1618 }.bind(this)));1619 }1620 } else {1621 assert_equals(this.get_interface_object().prototype[member.name], undefined,1622 "getting property on prototype object must return undefined");1623 this.do_interface_attribute_asserts(this.get_interface_object().prototype, member, a_test);1624 }1625 }1626 }.bind(this));1627};1628IdlInterface.prototype.test_member_operation = function(member)1629{1630 if (!shouldRunSubTest(this.name)) {1631 return;1632 }1633 var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: operation " + member);1634 a_test.step(function()1635 {1636 if (!this.should_have_interface_object()) {1637 a_test.done();1638 return;1639 }1640 this.assert_interface_object_exists();1641 if (this.is_callback()) {1642 assert_false("prototype" in this.get_interface_object(),1643 this.name + ' should not have a "prototype" property');1644 a_test.done();1645 return;1646 }1647 assert_own_property(this.get_interface_object(), "prototype",1648 'interface "' + this.name + '" does not have own property "prototype"');1649 var memberHolderObject;1650 if (member.special === "static") {1651 assert_own_property(this.get_interface_object(), member.name,1652 "interface object missing static operation");1653 memberHolderObject = this.get_interface_object();1654 } else if (this.is_global()) {1655 assert_own_property(self, member.name,1656 "global object missing non-static operation");1657 memberHolderObject = self;1658 } else {1659 assert_own_property(this.get_interface_object().prototype, member.name,1660 "interface prototype object missing non-static operation");1661 memberHolderObject = this.get_interface_object().prototype;1662 }1663 this.do_member_unscopable_asserts(member);1664 this.do_member_operation_asserts(memberHolderObject, member, a_test);1665 }.bind(this));1666};1667IdlInterface.prototype.do_member_unscopable_asserts = function(member)1668{1669 if (!member.isUnscopable) {1670 return;1671 }1672 var unscopables = this.get_interface_object().prototype[Symbol.unscopables];1673 var prop = member.name;1674 var propDesc = Object.getOwnPropertyDescriptor(unscopables, prop);1675 assert_equals(typeof propDesc, "object",1676 this.name + '.prototype[Symbol.unscopables].' + prop + ' must exist')1677 assert_false("get" in propDesc,1678 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no getter');1679 assert_false("set" in propDesc,1680 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have no setter');1681 assert_true(propDesc.writable,1682 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be writable');1683 assert_true(propDesc.enumerable,1684 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be enumerable');1685 assert_true(propDesc.configurable,1686 this.name + '.prototype[Symbol.unscopables].' + prop + ' must be configurable');1687 assert_equals(propDesc.value, true,1688 this.name + '.prototype[Symbol.unscopables].' + prop + ' must have the value `true`');1689};1690IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test)1691{1692 var done = a_test.done.bind(a_test);1693 var operationUnforgeable = member.isUnforgeable;1694 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);1695 assert_false("get" in desc, "property should not have a getter");1696 assert_false("set" in desc, "property should not have a setter");1697 assert_equals(desc.writable, !operationUnforgeable,1698 "property should be writable if and only if not unforgeable");1699 assert_true(desc.enumerable, "property should be enumerable");1700 assert_equals(desc.configurable, !operationUnforgeable,1701 "property should be configurable if and only if not unforgeable");1702 assert_equals(typeof memberHolderObject[member.name], "function",1703 "property must be a function");1704 const ctors = this.members.filter(function(m) {1705 return m.type == "operation" && m.name == member.name;1706 });1707 assert_equals(1708 memberHolderObject[member.name].length,1709 minOverloadLength(ctors),1710 "property has wrong .length");1711 assert_equals(1712 memberHolderObject[member.name].name,1713 member.name,1714 "property has wrong .name");1715 var args = member.arguments.map(function(arg) {1716 return create_suitable_object(arg.idlType);1717 });1718 if (member.special !== "static") {1719 var cb;1720 if (!this.is_global() &&1721 memberHolderObject[member.name] != self[member.name])1722 {1723 cb = awaitNCallbacks(2, done);1724 throwOrReject(a_test, member, memberHolderObject[member.name], null, args,1725 "calling operation with this = null didn't throw TypeError", cb);1726 } else {1727 cb = awaitNCallbacks(1, done);1728 }1729 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args,1730 "calling operation with this = {} didn't throw TypeError", cb);1731 } else {1732 done();1733 }1734}1735IdlInterface.prototype.test_to_json_operation = function(desc, memberHolderObject, member) {1736 var instanceName = memberHolderObject && memberHolderObject.constructor.name1737 || member.name + " object";1738 if (member.has_extended_attribute("Default")) {1739 subsetTestByKey(this.name, test, function() {1740 var map = this.default_to_json_operation();1741 var json = memberHolderObject.toJSON();1742 map.forEach(function(type, k) {1743 assert_true(k in json, "property " + JSON.stringify(k) + " should be present in the output of " + this.name + ".prototype.toJSON()");1744 var descriptor = Object.getOwnPropertyDescriptor(json, k);1745 assert_true(descriptor.writable, "property " + k + " should be writable");1746 assert_true(descriptor.configurable, "property " + k + " should be configurable");1747 assert_true(descriptor.enumerable, "property " + k + " should be enumerable");1748 this.array.assert_type_is(json[k], type);1749 delete json[k];1750 }, this);1751 }.bind(this), this.name + " interface: default toJSON operation on " + desc);1752 } else {1753 subsetTestByKey(this.name, test, function() {1754 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);1755 this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType);1756 }.bind(this), this.name + " interface: toJSON operation on " + desc);1757 }1758};1759IdlInterface.prototype.test_member_iterable = function(member)1760{1761 subsetTestByKey(this.name, test, function()1762 {1763 var isPairIterator = member.idlType.length === 2;1764 var proto = this.get_interface_object().prototype;1765 var iteratorDesc = Object.getOwnPropertyDescriptor(proto, Symbol.iterator);1766 assert_true(iteratorDesc.writable, "@@iterator property should be writable");1767 assert_true(iteratorDesc.configurable, "@@iterator property should be configurable");1768 assert_false(iteratorDesc.enumerable, "@@iterator property should not be enumerable");1769 assert_equals(typeof iteratorDesc.value, "function", "@@iterator property should be a function");1770 assert_equals(iteratorDesc.value.length, 0, "@@iterator function object length should be 0");1771 assert_equals(iteratorDesc.value.name, isPairIterator ? "entries" : "values", "@@iterator function object should have the right name");1772 if (isPairIterator) {1773 assert_equals(proto["entries"], proto[Symbol.iterator], "entries method should be the same as @@iterator method");1774 [1775 ["entries", 0],1776 ["keys", 0],1777 ["values", 0],1778 ["forEach", 1]1779 ].forEach(([property, length]) => {1780 var desc = Object.getOwnPropertyDescriptor(proto, property);1781 assert_equals(typeof desc.value, "function", property + " property should be a function");1782 assert_equals(desc.value.length, length, property + " function object length should be " + length);1783 assert_equals(desc.value.name, property, property + " function object should have the right name");1784 });1785 } else {1786 assert_equals(proto[Symbol.iterator], Array.prototype[Symbol.iterator], "@@iterator method should be the same as Array prototype's");1787 ["entries", "keys", "values", "forEach", Symbol.iterator].forEach(property => {1788 var propertyName = property === Symbol.iterator ? "@@iterator" : property;1789 assert_equals(proto[property], Array.prototype[property], propertyName + " method should be the same as Array prototype's");1790 });1791 }1792 }.bind(this), this.name + " interface: iterable<" + member.idlType.map(function(t) { return t.idlType; }).join(", ") + ">");1793};1794IdlInterface.prototype.test_member_async_iterable = function(member)1795{1796 subsetTestByKey(this.name, test, function()1797 {1798 var isPairIterator = member.idlType.length === 2;1799 var proto = this.get_interface_object().prototype;1800 var iteratorDesc = Object.getOwnPropertyDescriptor(proto, Symbol.asyncIterator);1801 assert_true(iteratorDesc.writable, "@@asyncIterator property should be writable");1802 assert_true(iteratorDesc.configurable, "@@asyncIterator property should be configurable");1803 assert_false(iteratorDesc.enumerable, "@@asyncIterator property should not be enumerable");1804 assert_equals(typeof iteratorDesc.value, "function", "@@asyncIterator property should be a function");1805 assert_equals(iteratorDesc.value.length, 0, "@@asyncIterator function object length should be 0");1806 assert_equals(iteratorDesc.value.name, isPairIterator ? "entries" : "values", "@@asyncIterator function object should have the right name");1807 if (isPairIterator) {1808 assert_equals(proto["entries"], proto[Symbol.asyncIterator], "entries method should be the same as @@asyncIterator method");1809 ["entries", "keys", "values"].forEach(property => {1810 var desc = Object.getOwnPropertyDescriptor(proto, property);1811 assert_equals(typeof desc.value, "function", property + " property should be a function");1812 assert_equals(desc.value.length, 0, property + " function object length should be 0");1813 assert_equals(desc.value.name, property, property + " function object should have the right name");1814 });1815 } else {1816 assert_equals(proto["values"], proto[Symbol.asyncIterator], "values method should be the same as @@asyncIterator method");1817 assert_false("entries" in proto, "should not have an entries method");1818 assert_false("keys" in proto, "should not have a keys method");1819 }1820 }.bind(this), this.name + " interface: async iterable<" + member.idlType.map(function(t) { return t.idlType; }).join(", ") + ">");1821};1822IdlInterface.prototype.test_member_stringifier = function(member)1823{1824 subsetTestByKey(this.name, test, function()1825 {1826 if (!this.should_have_interface_object()) {1827 return;1828 }1829 this.assert_interface_object_exists();1830 if (this.is_callback()) {1831 assert_false("prototype" in this.get_interface_object(),1832 this.name + ' should not have a "prototype" property');1833 return;1834 }1835 assert_own_property(this.get_interface_object(), "prototype",1836 'interface "' + this.name + '" does not have own property "prototype"');1837 var interfacePrototypeObject = this.get_interface_object().prototype;1838 assert_own_property(interfacePrototypeObject, "toString",1839 "interface prototype object missing non-static operation");1840 var stringifierUnforgeable = member.isUnforgeable;1841 var desc = Object.getOwnPropertyDescriptor(interfacePrototypeObject, "toString");1842 assert_false("get" in desc, "property should not have a getter");1843 assert_false("set" in desc, "property should not have a setter");1844 assert_equals(desc.writable, !stringifierUnforgeable,1845 "property should be writable if and only if not unforgeable");1846 assert_true(desc.enumerable, "property should be enumerable");1847 assert_equals(desc.configurable, !stringifierUnforgeable,1848 "property should be configurable if and only if not unforgeable");1849 assert_equals(typeof interfacePrototypeObject.toString, "function",1850 "property must be a function");1851 assert_equals(interfacePrototypeObject.toString.length, 0,1852 "property has wrong .length");1853 assert_throws_js(globalOf(interfacePrototypeObject.toString).TypeError, function() {1854 interfacePrototypeObject.toString.apply(null, []);1855 }, "calling stringifier with this = null didn't throw TypeError");1856 assert_throws_js(globalOf(interfacePrototypeObject.toString).TypeError, function() {1857 interfacePrototypeObject.toString.apply({}, []);1858 }, "calling stringifier with this = {} didn't throw TypeError");1859 }.bind(this), this.name + " interface: stringifier");1860};1861IdlInterface.prototype.test_members = function()1862{1863 for (var i = 0; i < this.members.length; i++)1864 {1865 var member = this.members[i];1866 if (member.untested) {1867 continue;1868 }1869 if (!exposed_in(exposure_set(member, this.exposureSet))) {1870 subsetTestByKey(this.name, test, function() {1871 assert_false(member.name in this.get_interface_object(),1872 "The interface object must not have a property " +1873 format_value(member.name));1874 assert_false(member.name in this.get_interface_object().prototype,1875 "The prototype object must not have a property " +1876 format_value(member.name));1877 }.bind(this), this.name + " interface: member " + member.name);1878 continue;1879 }1880 switch (member.type) {1881 case "const":1882 this.test_member_const(member);1883 break;1884 case "attribute":1885 if (!member.isUnforgeable)1886 {1887 this.test_member_attribute(member);1888 }1889 if (member.special === "stringifier") {1890 this.test_member_stringifier(member);1891 }1892 break;1893 case "operation":1894 if (member.name) {1895 if (!member.isUnforgeable)1896 {1897 this.test_member_operation(member);1898 }1899 } else if (member.special === "stringifier") {1900 this.test_member_stringifier(member);1901 }1902 break;1903 case "iterable":1904 if (member.async) {1905 this.test_member_async_iterable(member);1906 } else {1907 this.test_member_iterable(member);1908 }1909 break;1910 default:1911 break;1912 }1913 }1914};1915IdlInterface.prototype.test_object = function(desc)1916{1917 var obj, exception = null;1918 try1919 {1920 obj = eval(desc);1921 }1922 catch(e)1923 {1924 exception = e;1925 }1926 var expected_typeof;1927 if (this.name == "HTMLAllCollection")1928 {1929 expected_typeof = "undefined";1930 }1931 else1932 {1933 expected_typeof = "object";1934 }1935 this.test_primary_interface_of(desc, obj, exception, expected_typeof);1936 var current_interface = this;1937 while (current_interface)1938 {1939 if (!(current_interface.name in this.array.members))1940 {1941 throw new IdlHarnessError("Interface " + current_interface.name + " not found (inherited by " + this.name + ")");1942 }1943 if (current_interface.prevent_multiple_testing && current_interface.already_tested)1944 {1945 return;1946 }1947 current_interface.test_interface_of(desc, obj, exception, expected_typeof);1948 current_interface = this.array.members[current_interface.base];1949 }1950};1951IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception, expected_typeof)1952{1953 if (this.untested)1954 {1955 return;1956 }1957 if (this.is_global())1958 {1959 this.test_immutable_prototype("global platform object", obj);1960 }1961 if (this.should_have_interface_object()1962 && (typeof obj != expected_typeof || obj instanceof Object))1963 {1964 subsetTestByKey(this.name, test, function()1965 {1966 assert_equals(exception, null, "Unexpected exception when evaluating object");1967 assert_equals(typeof obj, expected_typeof, "wrong typeof object");1968 this.assert_interface_object_exists();1969 assert_own_property(this.get_interface_object(), "prototype",1970 'interface "' + this.name + '" does not have own property "prototype"');1971 assert_equals(Object.getPrototypeOf(obj),1972 this.get_interface_object().prototype,1973 desc + "'s prototype is not " + this.name + ".prototype");1974 }.bind(this), this.name + " must be primary interface of " + desc);1975 }1976 subsetTestByKey(this.name, test, function()1977 {1978 assert_equals(exception, null, "Unexpected exception when evaluating object");1979 assert_equals(typeof obj, expected_typeof, "wrong typeof object");1980 assert_class_string(obj, this.get_qualified_name(), "class string of " + desc);1981 if (!this.has_stringifier())1982 {1983 assert_equals(String(obj), "[object " + this.get_qualified_name() + "]", "String(" + desc + ")");1984 }1985 }.bind(this), "Stringification of " + desc);1986};1987IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expected_typeof)1988{1989 this.already_tested = true;1990 if (!shouldRunSubTest(this.name)) {1991 return;1992 }1993 for (var i = 0; i < this.members.length; i++)1994 {1995 var member = this.members[i];1996 if (member.untested) {1997 continue;1998 }1999 if (!exposed_in(exposure_set(member, this.exposureSet))) {2000 subsetTestByKey(this.name, test, function() {2001 assert_equals(exception, null, "Unexpected exception when evaluating object");2002 assert_false(member.name in obj);2003 }.bind(this), this.name + " interface: " + desc + ' must not have property "' + member.name + '"');2004 continue;2005 }2006 if (member.type == "attribute" && member.isUnforgeable)2007 {2008 var a_test = subsetTestByKey(this.name, async_test, this.name + " interface: " + desc + ' must have own property "' + member.name + '"');2009 a_test.step(function() {2010 assert_equals(exception, null, "Unexpected exception when evaluating object");2011 assert_equals(typeof obj, expected_typeof, "wrong typeof object");2012 this.do_interface_attribute_asserts(obj, member, a_test);2013 }.bind(this));...
idlharness.js
Source:idlharness.js
...400 }401 return false;402 }403};404function exposure_set(object, default_set) {405 var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed" });406 if (exposed.length > 1 || exposed.length < 0) {407 throw "Unexpected Exposed extended attributes on " + memberName + ": " + exposed;408 }409 if (exposed.length === 0) {410 return default_set;411 }412 var set = exposed[0].rhs.value;413 // Could be a list or a string.414 if (typeof set == "string") {415 set = [ set ];416 }417 return set;418}419function exposed_in(globals) {420 if ('document' in self) {421 return globals.indexOf("Window") >= 0;422 }423 if ('DedicatedWorkerGlobalScope' in self &&424 self instanceof DedicatedWorkerGlobalScope) {425 return globals.indexOf("Worker") >= 0 ||426 globals.indexOf("DedicatedWorker") >= 0;427 }428 if ('SharedWorkerGlobalScope' in self &&429 self instanceof SharedWorkerGlobalScope) {430 return globals.indexOf("Worker") >= 0 ||431 globals.indexOf("SharedWorker") >= 0;432 }433 if ('ServiceWorkerGlobalScope' in self &&434 self instanceof ServiceWorkerGlobalScope) {435 return globals.indexOf("Worker") >= 0 ||436 globals.indexOf("ServiceWorker") >= 0;437 }438 throw "Unexpected global object";439}440//@}441IdlArray.prototype.test = function()442//@{443{444 /** Entry point. See documentation at beginning of file. */445 // First merge in all the partial interfaces and implements statements we446 // encountered.447 this.partials.forEach(function(parsed_idl)448 {449 if (!(parsed_idl.name in this.members)450 || !(this.members[parsed_idl.name] instanceof IdlInterface))451 {452 throw "Partial interface " + parsed_idl.name + " with no original interface";453 }454 if (parsed_idl.extAttrs)455 {456 parsed_idl.extAttrs.forEach(function(extAttr)457 {458 this.members[parsed_idl.name].extAttrs.push(extAttr);459 }.bind(this));460 }461 parsed_idl.members.forEach(function(member)462 {463 this.members[parsed_idl.name].members.push(new IdlInterfaceMember(member));464 }.bind(this));465 }.bind(this));466 this.partials = [];467 for (var lhs in this["implements"])468 {469 this.recursively_get_implements(lhs).forEach(function(rhs)470 {471 var errStr = lhs + " implements " + rhs + ", but ";472 if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";473 if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";474 if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";475 if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";476 this.members[rhs].members.forEach(function(member)477 {478 this.members[lhs].members.push(new IdlInterfaceMember(member));479 }.bind(this));480 }.bind(this));481 }482 this["implements"] = {};483 Object.getOwnPropertyNames(this.members).forEach(function(memberName) {484 var member = this.members[memberName];485 if (!(member instanceof IdlInterface)) {486 return;487 }488 var globals = exposure_set(member, ["Window"]);489 member.exposed = exposed_in(globals);490 member.exposureSet = globals;491 }.bind(this));492 // Now run test() on every member, and test_object() for every object.493 for (var name in this.members)494 {495 this.members[name].test();496 if (name in this.objects)497 {498 this.objects[name].forEach(function(str)499 {500 this.members[name].test_object(str);501 }.bind(this));502 }503 }504};505//@}506IdlArray.prototype.assert_type_is = function(value, type)507//@{508{509 if (type.idlType in this.members510 && this.members[type.idlType] instanceof IdlTypedef) {511 this.assert_type_is(value, this.members[type.idlType].idlType);512 return;513 }514 if (type.union) {515 for (var i = 0; i < type.idlType.length; i++) {516 try {517 this.assert_type_is(value, type.idlType[i]);518 // No AssertionError, so we match one type in the union519 return;520 } catch(e) {521 if (e instanceof AssertionError) {522 // We didn't match this type, let's try some others523 continue;524 }525 throw e;526 }527 }528 // TODO: Is there a nice way to list the union's types in the message?529 assert_true(false, "Attribute has value " + format_value(value)530 + " which doesn't match any of the types in the union");531 }532 /**533 * Helper function that tests that value is an instance of type according534 * to the rules of WebIDL. value is any JavaScript value, and type is an535 * object produced by WebIDLParser.js' "type" production. That production536 * is fairly elaborate due to the complexity of WebIDL's types, so it's537 * best to look at the grammar to figure out what properties it might have.538 */539 if (type.idlType == "any")540 {541 // No assertions to make542 return;543 }544 if (type.nullable && value === null)545 {546 // This is fine547 return;548 }549 if (type.array)550 {551 // TODO: not supported yet552 return;553 }554 if (type.sequence)555 {556 assert_true(Array.isArray(value), "should be an Array");557 if (!value.length)558 {559 // Nothing we can do.560 return;561 }562 this.assert_type_is(value[0], type.idlType);563 return;564 }565 if (type.generic === "Promise") {566 assert_true("then" in value, "Attribute with a Promise type should have a then property");567 // TODO: Ideally, we would check on project fulfillment568 // that we get the right type569 // but that would require making the type check async570 return;571 }572 if (type.generic === "FrozenArray") {573 assert_true(Array.isArray(value), "Value should be array");574 assert_true(Object.isFrozen(value), "Value should be frozen");575 if (!value.length)576 {577 // Nothing we can do.578 return;579 }580 this.assert_type_is(value[0], type.idlType);581 return;582 }583 type = type.idlType;584 switch(type)585 {586 case "void":587 assert_equals(value, undefined);588 return;589 case "boolean":590 assert_equals(typeof value, "boolean");591 return;592 case "byte":593 assert_equals(typeof value, "number");594 assert_equals(value, Math.floor(value), "should be an integer");595 assert_true(-128 <= value && value <= 127, "byte " + value + " should be in range [-128, 127]");596 return;597 case "octet":598 assert_equals(typeof value, "number");599 assert_equals(value, Math.floor(value), "should be an integer");600 assert_true(0 <= value && value <= 255, "octet " + value + " should be in range [0, 255]");601 return;602 case "short":603 assert_equals(typeof value, "number");604 assert_equals(value, Math.floor(value), "should be an integer");605 assert_true(-32768 <= value && value <= 32767, "short " + value + " should be in range [-32768, 32767]");606 return;607 case "unsigned short":608 assert_equals(typeof value, "number");609 assert_equals(value, Math.floor(value), "should be an integer");610 assert_true(0 <= value && value <= 65535, "unsigned short " + value + " should be in range [0, 65535]");611 return;612 case "long":613 assert_equals(typeof value, "number");614 assert_equals(value, Math.floor(value), "should be an integer");615 assert_true(-2147483648 <= value && value <= 2147483647, "long " + value + " should be in range [-2147483648, 2147483647]");616 return;617 case "unsigned long":618 assert_equals(typeof value, "number");619 assert_equals(value, Math.floor(value), "should be an integer");620 assert_true(0 <= value && value <= 4294967295, "unsigned long " + value + " should be in range [0, 4294967295]");621 return;622 case "long long":623 assert_equals(typeof value, "number");624 return;625 case "unsigned long long":626 case "DOMTimeStamp":627 assert_equals(typeof value, "number");628 assert_true(0 <= value, "unsigned long long should be positive");629 return;630 case "float":631 assert_equals(typeof value, "number");632 assert_equals(value, fround(value), "float rounded to 32-bit float should be itself");633 assert_not_equals(value, Infinity);634 assert_not_equals(value, -Infinity);635 assert_not_equals(value, NaN);636 return;637 case "DOMHighResTimeStamp":638 case "double":639 assert_equals(typeof value, "number");640 assert_not_equals(value, Infinity);641 assert_not_equals(value, -Infinity);642 assert_not_equals(value, NaN);643 return;644 case "unrestricted float":645 assert_equals(typeof value, "number");646 assert_equals(value, fround(value), "unrestricted float rounded to 32-bit float should be itself");647 return;648 case "unrestricted double":649 assert_equals(typeof value, "number");650 return;651 case "DOMString":652 assert_equals(typeof value, "string");653 return;654 case "ByteString":655 assert_equals(typeof value, "string");656 assert_regexp_match(value, /^[\x00-\x7F]*$/);657 return;658 case "USVString":659 assert_equals(typeof value, "string");660 assert_regexp_match(value, /^([\x00-\ud7ff\ue000-\uffff]|[\ud800-\udbff][\udc00-\udfff])*$/);661 return;662 case "object":663 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");664 return;665 }666 if (!(type in this.members))667 {668 throw "Unrecognized type " + type;669 }670 if (this.members[type] instanceof IdlInterface)671 {672 // We don't want to run the full673 // IdlInterface.prototype.test_instance_of, because that could result674 // in an infinite loop. TODO: This means we don't have tests for675 // NoInterfaceObject interfaces, and we also can't test objects that676 // come from another self.677 assert_in_array(typeof value, ["object", "function"], "wrong type: not object or function");678 if (value instanceof Object679 && !this.members[type].has_extended_attribute("NoInterfaceObject")680 && type in self)681 {682 assert_true(value instanceof self[type], "instanceof " + type);683 }684 }685 else if (this.members[type] instanceof IdlEnum)686 {687 assert_equals(typeof value, "string");688 }689 else if (this.members[type] instanceof IdlDictionary)690 {691 // TODO: Test when we actually have something to test this on692 }693 else694 {695 throw "Type " + type + " isn't an interface or dictionary";696 }697};698//@}699/// IdlObject ///700function IdlObject() {}701IdlObject.prototype.test = function()702//@{703{704 /**705 * By default, this does nothing, so no actual tests are run for IdlObjects706 * that don't define any (e.g., IdlDictionary at the time of this writing).707 */708};709//@}710IdlObject.prototype.has_extended_attribute = function(name)711//@{712{713 /**714 * This is only meaningful for things that support extended attributes,715 * such as interfaces, exceptions, and members.716 */717 return this.extAttrs.some(function(o)718 {719 return o.name == name;720 });721};722//@}723/// IdlDictionary ///724// Used for IdlArray.prototype.assert_type_is725function IdlDictionary(obj)726//@{727{728 /**729 * obj is an object produced by the WebIDLParser.js "dictionary"730 * production.731 */732 /** Self-explanatory. */733 this.name = obj.name;734 /** A back-reference to our IdlArray. */735 this.array = obj.array;736 /** An array of objects produced by the "dictionaryMember" production. */737 this.members = obj.members;738 /**739 * The name (as a string) of the dictionary type we inherit from, or null740 * if there is none.741 */742 this.base = obj.inheritance;743}744//@}745IdlDictionary.prototype = Object.create(IdlObject.prototype);746IdlDictionary.prototype.get_inheritance_stack = function() {747 return IdlInterface.prototype.get_inheritance_stack.call(this);748};749/// IdlInterface ///750function IdlInterface(obj, is_callback)751//@{752{753 /**754 * obj is an object produced by the WebIDLParser.js "interface" production.755 */756 /** Self-explanatory. */757 this.name = obj.name;758 /** A back-reference to our IdlArray. */759 this.array = obj.array;760 /**761 * An indicator of whether we should run tests on the interface object and762 * interface prototype object. Tests on members are controlled by .untested763 * on each member, not this.764 */765 this.untested = obj.untested;766 /** An array of objects produced by the "ExtAttr" production. */767 this.extAttrs = obj.extAttrs;768 /** An array of IdlInterfaceMembers. */769 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m); });770 if (this.has_extended_attribute("Unforgeable")) {771 this.members772 .filter(function(m) { return !m["static"] && (m.type == "attribute" || m.type == "operation"); })773 .forEach(function(m) { return m.isUnforgeable = true; });774 }775 /**776 * The name (as a string) of the type we inherit from, or null if there is777 * none.778 */779 this.base = obj.inheritance;780 this._is_callback = is_callback;781}782//@}783IdlInterface.prototype = Object.create(IdlObject.prototype);784IdlInterface.prototype.is_callback = function()785//@{786{787 return this._is_callback;788};789//@}790IdlInterface.prototype.has_constants = function()791//@{792{793 return this.members.some(function(member) {794 return member.type === "const";795 });796};797//@}798IdlInterface.prototype.is_global = function()799//@{800{801 return this.extAttrs.some(function(attribute) {802 return attribute.name === "Global" ||803 attribute.name === "PrimaryGlobal";804 });805};806//@}807IdlInterface.prototype.has_to_json_regular_operation = function() {808 return this.members.some(function(m) {809 return m.is_to_json_regular_operation();810 });811};812IdlInterface.prototype.has_default_to_json_regular_operation = function() {813 return this.members.some(function(m) {814 return m.is_to_json_regular_operation() && m.has_extended_attribute("Default");815 });816};817IdlInterface.prototype.get_inheritance_stack = function() {818 /**819 * See https://heycam.github.io/webidl/#create-an-inheritance-stack820 *821 * Returns an array of IdlInterface objects which contains itself822 * and all of its inherited interfaces.823 *824 * So given:825 *826 * A : B {};827 * B : C {};828 * C {};829 *830 * then A.get_inheritance_stack() should return [A, B, C],831 * and B.get_inheritance_stack() should return [B, C].832 *833 * Note: as dictionary inheritance is expressed identically by the AST,834 * this works just as well for getting a stack of inherited dictionaries. 835 */836 var stack = [this];837 var idl_interface = this;838 while (idl_interface.base) {839 var base = this.array.members[idl_interface.base];840 if (!base) {841 throw new Error(idl_interface.type + " " + idl_interface.base + " not found (inherited by " + idl_interface.name + ")");842 }843 idl_interface = base;844 stack.push(idl_interface);845 }846 return stack;847};848/**849 * Implementation of850 * https://heycam.github.io/webidl/#default-tojson-operation851 * for testing purposes.852 *853 * Collects the IDL types of the attributes that meet the criteria854 * for inclusion in the default toJSON operation for easy855 * comparison with actual value856 */857IdlInterface.prototype.default_to_json_operation = function(callback) {858 var map = new Map(), isDefault = false;859 this.traverse_inherited_and_consequential_interfaces(function(I) {860 if (I.has_default_to_json_regular_operation()) {861 isDefault = true;862 I.members.forEach(function(m) {863 if (!m.static && m.type == "attribute" && I.array.is_json_type(m.idlType)) {864 map.set(m.name, m.idlType);865 }866 });867 } else if (I.has_to_json_regular_operation()) {868 isDefault = false;869 }870 });871 return isDefault ? map : null;872};873/**874 * Traverses inherited interfaces from the top down875 * and imeplemented interfaces inside out.876 * Invokes |callback| on each interface.877 *878 * This is an abstract implementation of the traversal879 * algorithm specified in:880 * https://heycam.github.io/webidl/#collect-attribute-values881 * Given the following inheritance tree:882 *883 * F884 * |885 * C E - I886 * | |887 * B - D888 * |889 * G - A - H - J890 *891 * Invoking traverse_inherited_and_consequential_interfaces() on A892 * would traverse the tree in the following order:893 * C -> B -> F -> E -> I -> D -> A -> G -> H -> J894 */895IdlInterface.prototype.traverse_inherited_and_consequential_interfaces = function(callback) {896 if (typeof callback != "function") {897 throw new TypeError();898 }899 var stack = this.get_inheritance_stack();900 _traverse_inherited_and_consequential_interfaces(stack, callback);901};902function _traverse_inherited_and_consequential_interfaces(stack, callback) {903 var I = stack.pop();904 callback(I);905 var mixins = I.array["implements"][I.name];906 if (mixins) {907 mixins.forEach(id => {908 var mixin = I.array.members[id];909 if (!mixin) {910 throw new Error("Interface " + id + " not found (implemented by " + I.name + ")");911 }912 var interfaces = mixin.get_inheritance_stack();913 _traverse_inherited_and_consequential_interfaces(interfaces, callback);914 });915 }916 if (stack.length > 0) {917 _traverse_inherited_and_consequential_interfaces(stack, callback);918 }919}920IdlInterface.prototype.test = function()921//@{922{923 if (this.has_extended_attribute("NoInterfaceObject"))924 {925 // No tests to do without an instance. TODO: We should still be able926 // to run tests on the prototype object, if we obtain one through some927 // other means.928 return;929 }930 if (!this.exposed) {931 test(function() {932 assert_false(this.name in self);933 }.bind(this), this.name + " interface: existence and properties of interface object");934 return;935 }936 if (!this.untested)937 {938 // First test things to do with the exception/interface object and939 // exception/interface prototype object.940 this.test_self();941 }942 // Then test things to do with its members (constants, fields, attributes,943 // operations, . . .). These are run even if .untested is true, because944 // members might themselves be marked as .untested. This might happen to945 // interfaces if the interface itself is untested but a partial interface946 // that extends it is tested -- then the interface itself and its initial947 // members will be marked as untested, but the members added by the partial948 // interface are still tested.949 this.test_members();950};951//@}952IdlInterface.prototype.test_self = function()953//@{954{955 test(function()956 {957 // This function tests WebIDL as of 2015-01-13.958 // "For every interface that is exposed in a given ECMAScript global959 // environment and:960 // * is a callback interface that has constants declared on it, or961 // * is a non-callback interface that is not declared with the962 // [NoInterfaceObject] extended attribute,963 // a corresponding property MUST exist on the ECMAScript global object.964 // The name of the property is the identifier of the interface, and its965 // value is an object called the interface object.966 // The property has the attributes { [[Writable]]: true,967 // [[Enumerable]]: false, [[Configurable]]: true }."968 if (this.is_callback() && !this.has_constants()) {969 return;970 }971 // TODO: Should we test here that the property is actually writable972 // etc., or trust getOwnPropertyDescriptor?973 assert_own_property(self, this.name,974 "self does not have own property " + format_value(this.name));975 var desc = Object.getOwnPropertyDescriptor(self, this.name);976 assert_false("get" in desc, "self's property " + format_value(this.name) + " should not have a getter");977 assert_false("set" in desc, "self's property " + format_value(this.name) + " should not have a setter");978 assert_true(desc.writable, "self's property " + format_value(this.name) + " should be writable");979 assert_false(desc.enumerable, "self's property " + format_value(this.name) + " should not be enumerable");980 assert_true(desc.configurable, "self's property " + format_value(this.name) + " should be configurable");981 if (this.is_callback()) {982 // "The internal [[Prototype]] property of an interface object for983 // a callback interface must be the Function.prototype object."984 assert_equals(Object.getPrototypeOf(self[this.name]), Function.prototype,985 "prototype of self's property " + format_value(this.name) + " is not Object.prototype");986 return;987 }988 // "The interface object for a given non-callback interface is a989 // function object."990 // "If an object is defined to be a function object, then it has991 // characteristics as follows:"992 // Its [[Prototype]] internal property is otherwise specified (see993 // below).994 // "* Its [[Get]] internal property is set as described in ECMA-262995 // section 9.1.8."996 // Not much to test for this.997 // "* Its [[Construct]] internal property is set as described in998 // ECMA-262 section 19.2.2.3."999 // Tested below if no constructor is defined. TODO: test constructors1000 // if defined.1001 // "* Its @@hasInstance property is set as described in ECMA-2621002 // section 19.2.3.8, unless otherwise specified."1003 // TODO1004 // ES6 (rev 30) 19.1.3.6:1005 // "Else, if O has a [[Call]] internal method, then let builtinTag be1006 // "Function"."1007 assert_class_string(self[this.name], "Function", "class string of " + this.name);1008 // "The [[Prototype]] internal property of an interface object for a1009 // non-callback interface is determined as follows:"1010 var prototype = Object.getPrototypeOf(self[this.name]);1011 if (this.base) {1012 // "* If the interface inherits from some other interface, the1013 // value of [[Prototype]] is the interface object for that other1014 // interface."1015 var has_interface_object =1016 !this.array1017 .members[this.base]1018 .has_extended_attribute("NoInterfaceObject");1019 if (has_interface_object) {1020 assert_own_property(self, this.base,1021 'should inherit from ' + this.base +1022 ', but self has no such property');1023 assert_equals(prototype, self[this.base],1024 'prototype of ' + this.name + ' is not ' +1025 this.base);1026 }1027 } else {1028 // "If the interface doesn't inherit from any other interface, the1029 // value of [[Prototype]] is %FunctionPrototype% ([ECMA-262],1030 // section 6.1.7.4)."1031 assert_equals(prototype, Function.prototype,1032 "prototype of self's property " + format_value(this.name) + " is not Function.prototype");1033 }1034 if (!this.has_extended_attribute("Constructor")) {1035 // "The internal [[Call]] method of the interface object behaves as1036 // follows . . .1037 //1038 // "If I was not declared with a [Constructor] extended attribute,1039 // then throw a TypeError."1040 assert_throws(new TypeError(), function() {1041 self[this.name]();1042 }.bind(this), "interface object didn't throw TypeError when called as a function");1043 assert_throws(new TypeError(), function() {1044 new self[this.name]();1045 }.bind(this), "interface object didn't throw TypeError when called as a constructor");1046 }1047 }.bind(this), this.name + " interface: existence and properties of interface object");1048 if (!this.is_callback()) {1049 test(function() {1050 // This function tests WebIDL as of 2014-10-25.1051 // https://heycam.github.io/webidl/#es-interface-call1052 assert_own_property(self, this.name,1053 "self does not have own property " + format_value(this.name));1054 // "Interface objects for non-callback interfaces MUST have a1055 // property named âlengthâ with attributes { [[Writable]]: false,1056 // [[Enumerable]]: false, [[Configurable]]: true } whose value is1057 // a Number."1058 assert_own_property(self[this.name], "length");1059 var desc = Object.getOwnPropertyDescriptor(self[this.name], "length");1060 assert_false("get" in desc, this.name + ".length should not have a getter");1061 assert_false("set" in desc, this.name + ".length should not have a setter");1062 assert_false(desc.writable, this.name + ".length should not be writable");1063 assert_false(desc.enumerable, this.name + ".length should not be enumerable");1064 assert_true(desc.configurable, this.name + ".length should be configurable");1065 var constructors = this.extAttrs1066 .filter(function(attr) { return attr.name == "Constructor"; });1067 var expected_length = minOverloadLength(constructors);1068 assert_equals(self[this.name].length, expected_length, "wrong value for " + this.name + ".length");1069 }.bind(this), this.name + " interface object length");1070 }1071 if (!this.is_callback() || this.has_constants()) {1072 test(function() {1073 // This function tests WebIDL as of 2015-11-17.1074 // https://heycam.github.io/webidl/#interface-object1075 assert_own_property(self, this.name,1076 "self does not have own property " + format_value(this.name));1077 // "All interface objects must have a property named ânameâ with1078 // attributes { [[Writable]]: false, [[Enumerable]]: false,1079 // [[Configurable]]: true } whose value is the identifier of the1080 // corresponding interface."1081 assert_own_property(self[this.name], "name");1082 var desc = Object.getOwnPropertyDescriptor(self[this.name], "name");1083 assert_false("get" in desc, this.name + ".name should not have a getter");1084 assert_false("set" in desc, this.name + ".name should not have a setter");1085 assert_false(desc.writable, this.name + ".name should not be writable");1086 assert_false(desc.enumerable, this.name + ".name should not be enumerable");1087 assert_true(desc.configurable, this.name + ".name should be configurable");1088 assert_equals(self[this.name].name, this.name, "wrong value for " + this.name + ".name");1089 }.bind(this), this.name + " interface object name");1090 }1091 if (this.has_extended_attribute("LegacyWindowAlias")) {1092 test(function()1093 {1094 var aliasAttrs = this.extAttrs.filter(function(o) { return o.name === "LegacyWindowAlias"; });1095 if (aliasAttrs.length > 1) {1096 throw "Invalid IDL: multiple LegacyWindowAlias extended attributes on " + this.name;1097 }1098 if (this.is_callback()) {1099 throw "Invalid IDL: LegacyWindowAlias extended attribute on non-interface " + this.name;1100 }1101 if (this.exposureSet.indexOf("Window") === -1) {1102 throw "Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " which is not exposed in Window";1103 }1104 // TODO: when testing of [NoInterfaceObject] interfaces is supported,1105 // check that it's not specified together with LegacyWindowAlias.1106 // TODO: maybe check that [LegacyWindowAlias] is not specified on a partial interface.1107 var rhs = aliasAttrs[0].rhs;1108 if (!rhs) {1109 throw "Invalid IDL: LegacyWindowAlias extended attribute on " + this.name + " without identifier";1110 }1111 var aliases;1112 if (rhs.type === "identifier-list") {1113 aliases = rhs.value;1114 } else { // rhs.type === identifier1115 aliases = [ rhs.value ];1116 }1117 // OK now actually check the aliases...1118 var alias;1119 if (exposed_in(exposure_set(this, this.exposureSet)) && 'document' in self) {1120 for (alias of aliases) {1121 assert_true(alias in self, alias + " should exist");1122 assert_equals(self[alias], self[this.name], "self." + alias + " should be the same value as self." + this.name);1123 var desc = Object.getOwnPropertyDescriptor(self, alias);1124 assert_equals(desc.value, self[this.name], "wrong value in " + alias + " property descriptor");1125 assert_true(desc.writable, alias + " should be writable");1126 assert_false(desc.enumerable, alias + " should not be enumerable");1127 assert_true(desc.configurable, alias + " should be configurable");1128 assert_false('get' in desc, alias + " should not have a getter");1129 assert_false('set' in desc, alias + " should not have a setter");1130 }1131 } else {1132 for (alias of aliases) {1133 assert_false(alias in self, alias + " should not exist");1134 }1135 }1136 }.bind(this), this.name + " interface: legacy window alias");1137 }1138 // TODO: Test named constructors if I find any interfaces that have them.1139 test(function()1140 {1141 // This function tests WebIDL as of 2015-01-21.1142 // https://heycam.github.io/webidl/#interface-object1143 if (this.is_callback() && !this.has_constants()) {1144 return;1145 }1146 assert_own_property(self, this.name,1147 "self does not have own property " + format_value(this.name));1148 if (this.is_callback()) {1149 assert_false("prototype" in self[this.name],1150 this.name + ' should not have a "prototype" property');1151 return;1152 }1153 // "An interface object for a non-callback interface must have a1154 // property named âprototypeâ with attributes { [[Writable]]: false,1155 // [[Enumerable]]: false, [[Configurable]]: false } whose value is an1156 // object called the interface prototype object. This object has1157 // properties that correspond to the regular attributes and regular1158 // operations defined on the interface, and is described in more detail1159 // in section 4.5.4 below."1160 assert_own_property(self[this.name], "prototype",1161 'interface "' + this.name + '" does not have own property "prototype"');1162 var desc = Object.getOwnPropertyDescriptor(self[this.name], "prototype");1163 assert_false("get" in desc, this.name + ".prototype should not have a getter");1164 assert_false("set" in desc, this.name + ".prototype should not have a setter");1165 assert_false(desc.writable, this.name + ".prototype should not be writable");1166 assert_false(desc.enumerable, this.name + ".prototype should not be enumerable");1167 assert_false(desc.configurable, this.name + ".prototype should not be configurable");1168 // Next, test that the [[Prototype]] of the interface prototype object1169 // is correct. (This is made somewhat difficult by the existence of1170 // [NoInterfaceObject].)1171 // TODO: Aryeh thinks there's at least other place in this file where1172 // we try to figure out if an interface prototype object is1173 // correct. Consolidate that code.1174 // "The interface prototype object for a given interface A must have an1175 // internal [[Prototype]] property whose value is returned from the1176 // following steps:1177 // "If A is declared with the [Global] or [PrimaryGlobal] extended1178 // attribute, and A supports named properties, then return the named1179 // properties object for A, as defined in §3.6.4 Named properties1180 // object.1181 // "Otherwise, if A is declared to inherit from another interface, then1182 // return the interface prototype object for the inherited interface.1183 // "Otherwise, if A is declared with the [LegacyArrayClass] extended1184 // attribute, then return %ArrayPrototype%.1185 // "Otherwise, return %ObjectPrototype%.1186 if (this.name === "Window") {1187 assert_class_string(Object.getPrototypeOf(self[this.name].prototype),1188 'WindowProperties',1189 'Class name for prototype of Window' +1190 '.prototype is not "WindowProperties"');1191 } else {1192 var inherit_interface, inherit_interface_has_interface_object;1193 if (this.base) {1194 inherit_interface = this.base;1195 inherit_interface_has_interface_object =1196 !this.array1197 .members[inherit_interface]1198 .has_extended_attribute("NoInterfaceObject");1199 } else if (this.has_extended_attribute('LegacyArrayClass')) {1200 inherit_interface = 'Array';1201 inherit_interface_has_interface_object = true;1202 } else {1203 inherit_interface = 'Object';1204 inherit_interface_has_interface_object = true;1205 }1206 if (inherit_interface_has_interface_object) {1207 assert_own_property(self, inherit_interface,1208 'should inherit from ' + inherit_interface + ', but self has no such property');1209 assert_own_property(self[inherit_interface], 'prototype',1210 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property');1211 assert_equals(Object.getPrototypeOf(self[this.name].prototype),1212 self[inherit_interface].prototype,1213 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype');1214 } else {1215 // We can't test that we get the correct object, because this is the1216 // only way to get our hands on it. We only test that its class1217 // string, at least, is correct.1218 assert_class_string(Object.getPrototypeOf(self[this.name].prototype),1219 inherit_interface + 'Prototype',1220 'Class name for prototype of ' + this.name +1221 '.prototype is not "' + inherit_interface + 'Prototype"');1222 }1223 }1224 // "The class string of an interface prototype object is the1225 // concatenation of the interfaceâs identifier and the string1226 // âPrototypeâ."1227 // Skip these tests for now due to a specification issue about1228 // prototype name.1229 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=282441230 // assert_class_string(self[this.name].prototype, this.name + "Prototype",1231 // "class string of " + this.name + ".prototype");1232 // String() should end up calling {}.toString if nothing defines a1233 // stringifier.1234 if (!this.has_stringifier()) {1235 // assert_equals(String(self[this.name].prototype), "[object " + this.name + "Prototype]",1236 // "String(" + this.name + ".prototype)");1237 }1238 }.bind(this), this.name + " interface: existence and properties of interface prototype object");1239 if (this.is_global() && typeof Object.setPrototypeOf === "function") {1240 // These functions test WebIDL as of 2017-06-06.1241 // https://heycam.github.io/webidl/#platform-object-setprototypeof1242 test(function() {1243 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1244 var newValue = Object.create(null);1245 assert_throws(new TypeError(), function() {1246 Object.setPrototypeOf(self[this.name].prototype, newValue);1247 });1248 assert_equals(1249 Object.getPrototypeOf(self[this.name].prototype),1250 originalValue,1251 "original value not modified"1252 );1253 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1254 "of global platform object - setting to a new value via Object.setPrototypeOf " +1255 "should throw a TypeError");1256 test(function() {1257 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1258 var newValue = Object.create(null);1259 assert_throws(new TypeError(), function() {1260 self[this.name].prototype.__proto__ = newValue;1261 });1262 assert_equals(1263 Object.getPrototypeOf(self[this.name].prototype),1264 originalValue,1265 "original value not modified"1266 );1267 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1268 "of global platform object - setting to a new value via __proto__ " +1269 "should throw a TypeError");1270 test(function() {1271 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1272 var newValue = Object.create(null);1273 assert_false(Reflect.setPrototypeOf(self[this.name].prototype.__proto__, newValue));1274 assert_equals(1275 Object.getPrototypeOf(self[this.name].prototype),1276 originalValue,1277 "original value not modified"1278 );1279 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1280 "of global platform object - setting to a new value via Reflect.setPrototypeOf " +1281 "should return false");1282 test(function() {1283 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1284 Object.setPrototypeOf(self[this.name].prototype, originalValue);1285 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1286 "of global platform object - setting to its original value via Object.setPrototypeOf " +1287 "should not throw");1288 test(function() {1289 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1290 self[this.name].prototype.__proto__ = originalValue;1291 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1292 "of global platform object - setting to its original value via __proto__ " +1293 "should not throw");1294 test(function() {1295 var originalValue = Object.getPrototypeOf(self[this.name].prototype);1296 assert_true(Reflect.setPrototypeOf(self[this.name].prototype, originalValue));1297 }.bind(this), this.name + " interface: internal [[SetPrototypeOf]] method " +1298 "of global platform object - setting to its original value via Reflect.setPrototypeOf " +1299 "should return true");1300 }1301 test(function()1302 {1303 if (this.is_callback() && !this.has_constants()) {1304 return;1305 }1306 assert_own_property(self, this.name,1307 "self does not have own property " + format_value(this.name));1308 if (this.is_callback()) {1309 assert_false("prototype" in self[this.name],1310 this.name + ' should not have a "prototype" property');1311 return;1312 }1313 assert_own_property(self[this.name], "prototype",1314 'interface "' + this.name + '" does not have own property "prototype"');1315 // "If the [NoInterfaceObject] extended attribute was not specified on1316 // the interface, then the interface prototype object must also have a1317 // property named âconstructorâ with attributes { [[Writable]]: true,1318 // [[Enumerable]]: false, [[Configurable]]: true } whose value is a1319 // reference to the interface object for the interface."1320 assert_own_property(self[this.name].prototype, "constructor",1321 this.name + '.prototype does not have own property "constructor"');1322 var desc = Object.getOwnPropertyDescriptor(self[this.name].prototype, "constructor");1323 assert_false("get" in desc, this.name + ".prototype.constructor should not have a getter");1324 assert_false("set" in desc, this.name + ".prototype.constructor should not have a setter");1325 assert_true(desc.writable, this.name + ".prototype.constructor should be writable");1326 assert_false(desc.enumerable, this.name + ".prototype.constructor should not be enumerable");1327 assert_true(desc.configurable, this.name + ".prototype.constructor should be configurable");1328 assert_equals(self[this.name].prototype.constructor, self[this.name],1329 this.name + '.prototype.constructor is not the same object as ' + this.name);1330 }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');1331};1332//@}1333IdlInterface.prototype.test_member_const = function(member)1334//@{1335{1336 if (!this.has_constants()) {1337 throw "Internal error: test_member_const called without any constants";1338 }1339 test(function()1340 {1341 assert_own_property(self, this.name,1342 "self does not have own property " + format_value(this.name));1343 // "For each constant defined on an interface A, there must be1344 // a corresponding property on the interface object, if it1345 // exists."1346 assert_own_property(self[this.name], member.name);1347 // "The value of the property is that which is obtained by1348 // converting the constantâs IDL value to an ECMAScript1349 // value."1350 assert_equals(self[this.name][member.name], constValue(member.value),1351 "property has wrong value");1352 // "The property has attributes { [[Writable]]: false,1353 // [[Enumerable]]: true, [[Configurable]]: false }."1354 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);1355 assert_false("get" in desc, "property should not have a getter");1356 assert_false("set" in desc, "property should not have a setter");1357 assert_false(desc.writable, "property should not be writable");1358 assert_true(desc.enumerable, "property should be enumerable");1359 assert_false(desc.configurable, "property should not be configurable");1360 }.bind(this), this.name + " interface: constant " + member.name + " on interface object");1361 // "In addition, a property with the same characteristics must1362 // exist on the interface prototype object."1363 test(function()1364 {1365 assert_own_property(self, this.name,1366 "self does not have own property " + format_value(this.name));1367 if (this.is_callback()) {1368 assert_false("prototype" in self[this.name],1369 this.name + ' should not have a "prototype" property');1370 return;1371 }1372 assert_own_property(self[this.name], "prototype",1373 'interface "' + this.name + '" does not have own property "prototype"');1374 assert_own_property(self[this.name].prototype, member.name);1375 assert_equals(self[this.name].prototype[member.name], constValue(member.value),1376 "property has wrong value");1377 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);1378 assert_false("get" in desc, "property should not have a getter");1379 assert_false("set" in desc, "property should not have a setter");1380 assert_false(desc.writable, "property should not be writable");1381 assert_true(desc.enumerable, "property should be enumerable");1382 assert_false(desc.configurable, "property should not be configurable");1383 }.bind(this), this.name + " interface: constant " + member.name + " on interface prototype object");1384};1385//@}1386IdlInterface.prototype.test_member_attribute = function(member)1387//@{1388 {1389 var a_test = async_test(this.name + " interface: attribute " + member.name);1390 a_test.step(function()1391 {1392 if (this.is_callback() && !this.has_constants()) {1393 a_test.done()1394 return;1395 }1396 assert_own_property(self, this.name,1397 "self does not have own property " + format_value(this.name));1398 assert_own_property(self[this.name], "prototype",1399 'interface "' + this.name + '" does not have own property "prototype"');1400 if (member["static"]) {1401 assert_own_property(self[this.name], member.name,1402 "The interface object must have a property " +1403 format_value(member.name));1404 a_test.done();1405 } else if (this.is_global()) {1406 assert_own_property(self, member.name,1407 "The global object must have a property " +1408 format_value(member.name));1409 assert_false(member.name in self[this.name].prototype,1410 "The prototype object should not have a property " +1411 format_value(member.name));1412 var getter = Object.getOwnPropertyDescriptor(self, member.name).get;1413 assert_equals(typeof(getter), "function",1414 format_value(member.name) + " must have a getter");1415 // Try/catch around the get here, since it can legitimately throw.1416 // If it does, we obviously can't check for equality with direct1417 // invocation of the getter.1418 var gotValue;1419 var propVal;1420 try {1421 propVal = self[member.name];1422 gotValue = true;1423 } catch (e) {1424 gotValue = false;1425 }1426 if (gotValue) {1427 assert_equals(propVal, getter.call(undefined),1428 "Gets on a global should not require an explicit this");1429 }1430 // do_interface_attribute_asserts must be the last thing we do,1431 // since it will call done() on a_test.1432 this.do_interface_attribute_asserts(self, member, a_test);1433 } else {1434 assert_true(member.name in self[this.name].prototype,1435 "The prototype object must have a property " +1436 format_value(member.name));1437 if (!member.has_extended_attribute("LenientThis")) {1438 if (member.idlType.generic !== "Promise") {1439 assert_throws(new TypeError(), function() {1440 self[this.name].prototype[member.name];1441 }.bind(this), "getting property on prototype object must throw TypeError");1442 // do_interface_attribute_asserts must be the last thing we1443 // do, since it will call done() on a_test.1444 this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test);1445 } else {1446 promise_rejects(a_test, new TypeError(),1447 self[this.name].prototype[member.name])1448 .then(function() {1449 // do_interface_attribute_asserts must be the last1450 // thing we do, since it will call done() on a_test.1451 this.do_interface_attribute_asserts(self[this.name].prototype,1452 member, a_test);1453 }.bind(this));1454 }1455 } else {1456 assert_equals(self[this.name].prototype[member.name], undefined,1457 "getting property on prototype object must return undefined");1458 // do_interface_attribute_asserts must be the last thing we do,1459 // since it will call done() on a_test.1460 this.do_interface_attribute_asserts(self[this.name].prototype, member, a_test);1461 }1462 }1463 }.bind(this));1464};1465//@}1466IdlInterface.prototype.test_member_operation = function(member)1467//@{1468{1469 var a_test = async_test(this.name + " interface: operation " + member.name +1470 "(" + member.arguments.map(1471 function(m) {return m.idlType.idlType; } )1472 +")");1473 a_test.step(function()1474 {1475 // This function tests WebIDL as of 2015-12-29.1476 // https://heycam.github.io/webidl/#es-operations1477 if (this.is_callback() && !this.has_constants()) {1478 a_test.done();1479 return;1480 }1481 assert_own_property(self, this.name,1482 "self does not have own property " + format_value(this.name));1483 if (this.is_callback()) {1484 assert_false("prototype" in self[this.name],1485 this.name + ' should not have a "prototype" property');1486 a_test.done();1487 return;1488 }1489 assert_own_property(self[this.name], "prototype",1490 'interface "' + this.name + '" does not have own property "prototype"');1491 // "For each unique identifier of an exposed operation defined on the1492 // interface, there must exist a corresponding property, unless the1493 // effective overload set for that identifier and operation and with an1494 // argument count of 0 has no entries."1495 // TODO: Consider [Exposed].1496 // "The location of the property is determined as follows:"1497 var memberHolderObject;1498 // "* If the operation is static, then the property exists on the1499 // interface object."1500 if (member["static"]) {1501 assert_own_property(self[this.name], member.name,1502 "interface object missing static operation");1503 memberHolderObject = self[this.name];1504 // "* Otherwise, [...] if the interface was declared with the [Global]1505 // or [PrimaryGlobal] extended attribute, then the property exists1506 // on every object that implements the interface."1507 } else if (this.is_global()) {1508 assert_own_property(self, member.name,1509 "global object missing non-static operation");1510 memberHolderObject = self;1511 // "* Otherwise, the property exists solely on the interfaceâs1512 // interface prototype object."1513 } else {1514 assert_own_property(self[this.name].prototype, member.name,1515 "interface prototype object missing non-static operation");1516 memberHolderObject = self[this.name].prototype;1517 }1518 this.do_member_operation_asserts(memberHolderObject, member, a_test);1519 }.bind(this));1520};1521//@}1522IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test)1523//@{1524{1525 var done = a_test.done.bind(a_test);1526 var operationUnforgeable = member.isUnforgeable;1527 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);1528 // "The property has attributes { [[Writable]]: B,1529 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the1530 // operation is unforgeable on the interface, and true otherwise".1531 assert_false("get" in desc, "property should not have a getter");1532 assert_false("set" in desc, "property should not have a setter");1533 assert_equals(desc.writable, !operationUnforgeable,1534 "property should be writable if and only if not unforgeable");1535 assert_true(desc.enumerable, "property should be enumerable");1536 assert_equals(desc.configurable, !operationUnforgeable,1537 "property should be configurable if and only if not unforgeable");1538 // "The value of the property is a Function object whose1539 // behavior is as follows . . ."1540 assert_equals(typeof memberHolderObject[member.name], "function",1541 "property must be a function");1542 // "The value of the Function objectâs âlengthâ property is1543 // a Number determined as follows:1544 // ". . .1545 // "Return the length of the shortest argument list of the1546 // entries in S."1547 assert_equals(memberHolderObject[member.name].length,1548 minOverloadLength(this.members.filter(function(m) {1549 return m.type == "operation" && m.name == member.name;1550 })),1551 "property has wrong .length");1552 if (member.is_to_json_regular_operation()) {1553 this.test_to_json_operation(memberHolderObject, member);1554 }1555 // Make some suitable arguments1556 var args = member.arguments.map(function(arg) {1557 return create_suitable_object(arg.idlType);1558 });1559 // "Let O be a value determined as follows:1560 // ". . .1561 // "Otherwise, throw a TypeError."1562 // This should be hit if the operation is not static, there is1563 // no [ImplicitThis] attribute, and the this value is null.1564 //1565 // TODO: We currently ignore the [ImplicitThis] case. Except we manually1566 // check for globals, since otherwise we'll invoke window.close(). And we1567 // have to skip this test for anything that on the proto chain of "self",1568 // since that does in fact have implicit-this behavior.1569 if (!member["static"]) {1570 var cb;1571 if (!this.is_global() &&1572 memberHolderObject[member.name] != self[member.name])1573 {1574 cb = awaitNCallbacks(2, done);1575 throwOrReject(a_test, member, memberHolderObject[member.name], null, args,1576 "calling operation with this = null didn't throw TypeError", cb);1577 } else {1578 cb = awaitNCallbacks(1, done);1579 }1580 // ". . . If O is not null and is also not a platform object1581 // that implements interface I, throw a TypeError."1582 //1583 // TODO: Test a platform object that implements some other1584 // interface. (Have to be sure to get inheritance right.)1585 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args,1586 "calling operation with this = {} didn't throw TypeError", cb);1587 } else {1588 done();1589 }1590}1591//@}1592IdlInterface.prototype.add_iterable_members = function(member)1593//@{1594{1595 this.members.push(new IdlInterfaceMember(1596 { type: "operation", name: "entries", idlType: "iterator", arguments: []}));1597 this.members.push(new IdlInterfaceMember(1598 { type: "operation", name: "keys", idlType: "iterator", arguments: []}));1599 this.members.push(new IdlInterfaceMember(1600 { type: "operation", name: "values", idlType: "iterator", arguments: []}));1601 this.members.push(new IdlInterfaceMember(1602 { type: "operation", name: "forEach", idlType: "void",1603 arguments:1604 [{ name: "callback", idlType: {idlType: "function"}},1605 { name: "thisValue", idlType: {idlType: "any"}, optional: true}]}));1606};1607IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, member) {1608 if (member.has_extended_attribute("Default")) {1609 var map = this.default_to_json_operation();1610 test(function() {1611 var json = memberHolderObject.toJSON();1612 map.forEach(function(type, k) {1613 assert_true(k in json, "property " + k + " should be present in the output of " + this.name + ".prototype.toJSON()");1614 var descriptor = Object.getOwnPropertyDescriptor(json, k);1615 assert_true(descriptor.writable, "property " + k + " should be writable");1616 assert_true(descriptor.configurable, "property " + k + " should be configurable");1617 assert_true(descriptor.enumerable, "property " + k + " should be enumerable");1618 this.array.assert_type_is(json[k], type);1619 delete json[k];1620 }, this);1621 for (var k in json) {1622 assert_unreached("property " + k + " should not be present in the output of " + this.name + ".prototype.toJSON()");1623 }1624 }.bind(this), "Test default toJSON operation of " + this.name);1625 } else {1626 test(function() {1627 assert_true(this.array.is_json_type(member.idlType), JSON.stringify(member.idlType) + " is not an appropriate return value for the toJSON operation of " + this.name);1628 this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType);1629 }.bind(this), "Test toJSON operation of " + this.name);1630 }1631};1632//@}1633IdlInterface.prototype.test_member_iterable = function(member)1634//@{1635{1636 var interfaceName = this.name;1637 var isPairIterator = member.idlType instanceof Array;1638 test(function()1639 {1640 var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].prototype, Symbol.iterator);1641 assert_true(descriptor.writable, "property should be writable");1642 assert_true(descriptor.configurable, "property should be configurable");1643 assert_false(descriptor.enumerable, "property should not be enumerable");1644 assert_equals(self[interfaceName].prototype[Symbol.iterator].name, isPairIterator ? "entries" : "values", "@@iterator function does not have the right name");1645 }, "Testing Symbol.iterator property of iterable interface " + interfaceName);1646 if (isPairIterator) {1647 test(function() {1648 assert_equals(self[interfaceName].prototype[Symbol.iterator], self[interfaceName].prototype["entries"], "entries method is not the same as @@iterator");1649 }, "Testing pair iterable interface " + interfaceName);1650 } else {1651 test(function() {1652 ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(function(property) {1653 assert_equals(self[interfaceName].prototype[property], Array.prototype[property], property + " function is not the same as Array one");1654 });1655 }, "Testing value iterable interface " + interfaceName);1656 }1657};1658//@}1659IdlInterface.prototype.test_member_stringifier = function(member)1660//@{1661{1662 test(function()1663 {1664 if (this.is_callback() && !this.has_constants()) {1665 return;1666 }1667 assert_own_property(self, this.name,1668 "self does not have own property " + format_value(this.name));1669 if (this.is_callback()) {1670 assert_false("prototype" in self[this.name],1671 this.name + ' should not have a "prototype" property');1672 return;1673 }1674 assert_own_property(self[this.name], "prototype",1675 'interface "' + this.name + '" does not have own property "prototype"');1676 // ". . . the property exists on the interface prototype object."1677 var interfacePrototypeObject = self[this.name].prototype;1678 assert_own_property(self[this.name].prototype, "toString",1679 "interface prototype object missing non-static operation");1680 var stringifierUnforgeable = member.isUnforgeable;1681 var desc = Object.getOwnPropertyDescriptor(interfacePrototypeObject, "toString");1682 // "The property has attributes { [[Writable]]: B,1683 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the1684 // stringifier is unforgeable on the interface, and true otherwise."1685 assert_false("get" in desc, "property should not have a getter");1686 assert_false("set" in desc, "property should not have a setter");1687 assert_equals(desc.writable, !stringifierUnforgeable,1688 "property should be writable if and only if not unforgeable");1689 assert_true(desc.enumerable, "property should be enumerable");1690 assert_equals(desc.configurable, !stringifierUnforgeable,1691 "property should be configurable if and only if not unforgeable");1692 // "The value of the property is a Function object, which behaves as1693 // follows . . ."1694 assert_equals(typeof interfacePrototypeObject.toString, "function",1695 "property must be a function");1696 // "The value of the Function objectâs âlengthâ property is the Number1697 // value 0."1698 assert_equals(interfacePrototypeObject.toString.length, 0,1699 "property has wrong .length");1700 // "Let O be the result of calling ToObject on the this value."1701 assert_throws(new TypeError(), function() {1702 self[this.name].prototype.toString.apply(null, []);1703 }, "calling stringifier with this = null didn't throw TypeError");1704 // "If O is not an object that implements the interface on which the1705 // stringifier was declared, then throw a TypeError."1706 //1707 // TODO: Test a platform object that implements some other1708 // interface. (Have to be sure to get inheritance right.)1709 assert_throws(new TypeError(), function() {1710 self[this.name].prototype.toString.apply({}, []);1711 }, "calling stringifier with this = {} didn't throw TypeError");1712 }.bind(this), this.name + " interface: stringifier");1713};1714//@}1715IdlInterface.prototype.test_members = function()1716//@{1717{1718 for (var i = 0; i < this.members.length; i++)1719 {1720 var member = this.members[i];1721 switch (member.type) {1722 case "iterable":1723 this.add_iterable_members(member);1724 break;1725 // TODO: add setlike and maplike handling.1726 default:1727 break;1728 }1729 }1730 for (var i = 0; i < this.members.length; i++)1731 {1732 var member = this.members[i];1733 if (member.untested) {1734 continue;1735 }1736 if (!exposed_in(exposure_set(member, this.exposureSet))) {1737 test(function() {1738 // It's not exposed, so we shouldn't find it anywhere.1739 assert_false(member.name in self[this.name],1740 "The interface object must not have a property " +1741 format_value(member.name));1742 assert_false(member.name in self[this.name].prototype,1743 "The prototype object must not have a property " +1744 format_value(member.name));1745 }.bind(this), this.name + " interface: member " + member.name);1746 continue;1747 }1748 switch (member.type) {1749 case "const":1750 this.test_member_const(member);1751 break;1752 case "attribute":1753 // For unforgeable attributes, we do the checks in1754 // test_interface_of instead.1755 if (!member.isUnforgeable)1756 {1757 this.test_member_attribute(member);1758 }1759 if (member.stringifier) {1760 this.test_member_stringifier(member);1761 }1762 break;1763 case "operation":1764 // TODO: Need to correctly handle multiple operations with the same1765 // identifier.1766 // For unforgeable operations, we do the checks in1767 // test_interface_of instead.1768 if (member.name) {1769 if (!member.isUnforgeable)1770 {1771 this.test_member_operation(member);1772 }1773 } else if (member.stringifier) {1774 this.test_member_stringifier(member);1775 }1776 break;1777 case "iterable":1778 this.test_member_iterable(member);1779 break;1780 default:1781 // TODO: check more member types.1782 break;1783 }1784 }1785};1786//@}1787IdlInterface.prototype.test_object = function(desc)1788//@{1789{1790 var obj, exception = null;1791 try1792 {1793 obj = eval(desc);1794 }1795 catch(e)1796 {1797 exception = e;1798 }1799 var expected_typeof =1800 this.members.some(function(member) { return member.legacycaller; })1801 ? "function"1802 : "object";1803 this.test_primary_interface_of(desc, obj, exception, expected_typeof);1804 var current_interface = this;1805 while (current_interface)1806 {1807 if (!(current_interface.name in this.array.members))1808 {1809 throw "Interface " + current_interface.name + " not found (inherited by " + this.name + ")";1810 }1811 if (current_interface.prevent_multiple_testing && current_interface.already_tested)1812 {1813 return;1814 }1815 current_interface.test_interface_of(desc, obj, exception, expected_typeof);1816 current_interface = this.array.members[current_interface.base];1817 }1818};1819//@}1820IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception, expected_typeof)1821//@{1822{1823 // Only the object itself, not its members, are tested here, so if the1824 // interface is untested, there is nothing to do.1825 if (this.untested)1826 {1827 return;1828 }1829 // We can't easily test that its prototype is correct if there's no1830 // interface object, or the object is from a different global environment1831 // (not instanceof Object). TODO: test in this case that its prototype at1832 // least looks correct, even if we can't test that it's actually correct.1833 if (!this.has_extended_attribute("NoInterfaceObject")1834 && (typeof obj != expected_typeof || obj instanceof Object))1835 {1836 test(function()1837 {1838 assert_equals(exception, null, "Unexpected exception when evaluating object");1839 assert_equals(typeof obj, expected_typeof, "wrong typeof object");1840 assert_own_property(self, this.name,1841 "self does not have own property " + format_value(this.name));1842 assert_own_property(self[this.name], "prototype",1843 'interface "' + this.name + '" does not have own property "prototype"');1844 // "The value of the internal [[Prototype]] property of the1845 // platform object is the interface prototype object of the primary1846 // interface from the platform objectâs associated global1847 // environment."1848 assert_equals(Object.getPrototypeOf(obj),1849 self[this.name].prototype,1850 desc + "'s prototype is not " + this.name + ".prototype");1851 }.bind(this), this.name + " must be primary interface of " + desc);1852 }1853 // "The class string of a platform object that implements one or more1854 // interfaces must be the identifier of the primary interface of the1855 // platform object."1856 test(function()1857 {1858 assert_equals(exception, null, "Unexpected exception when evaluating object");1859 assert_equals(typeof obj, expected_typeof, "wrong typeof object");1860 assert_class_string(obj, this.name, "class string of " + desc);1861 if (!this.has_stringifier())1862 {1863 assert_equals(String(obj), "[object " + this.name + "]", "String(" + desc + ")");1864 }1865 }.bind(this), "Stringification of " + desc);1866};1867//@}1868IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expected_typeof)1869//@{1870{1871 // TODO: Indexed and named properties, more checks on interface members1872 this.already_tested = true;1873 for (var i = 0; i < this.members.length; i++)1874 {1875 var member = this.members[i];1876 if (member.untested) {1877 continue;1878 }1879 if (!exposed_in(exposure_set(member, this.exposureSet))) {1880 test(function() {1881 assert_false(member.name in obj);1882 }.bind(this), this.name + "interface: " + desc + 'must not have property "' + member.name + '"');1883 continue;1884 }1885 if (member.type == "attribute" && member.isUnforgeable)1886 {1887 var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"');1888 a_test.step(function() {1889 assert_equals(exception, null, "Unexpected exception when evaluating object");1890 assert_equals(typeof obj, expected_typeof, "wrong typeof object");1891 // Call do_interface_attribute_asserts last, since it will call a_test.done()1892 this.do_interface_attribute_asserts(obj, member, a_test);1893 }.bind(this));...
Using AI Code Generation
1var wpt = require('webpagetest')('www.webpagetest.org');2var location = 'Dulles:Chrome';3var options = {4 videoParams: {5 }6};7wpt.runTest(url, options, function(err, data) {8 if (err) return console.error(err);9 console.log('Test submitted to WebPagetest for %s', url);10 console.log('View your test at: %s', data.data.userUrl);11 console.log('Poll results every %s seconds.', options.pollResults);12 console.log('Video capture: %s', data.data.videoFrames);13 console.log('Video URL: %s', data.data.videoUrl);14 console.log('Test ID: %s', data.data.testId);15});
Using AI Code Generation
1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org');3var options = { location: 'Dulles:Chrome', runs: 3, connectivity: 'Cable' };4 if (err) return console.error(err);5 console.log('Test status:', data.statusText);6 wpt.exposure_set(data.data.testId, 'public', function(err, data) {7 if (err) return console.error(err);8 console.log('Test status:', data.statusText);9 });10});11var wpt = require('webpagetest');12var wpt = new WebPageTest('www.webpagetest.org');13var options = { location: 'Dulles:Chrome', runs: 3, connectivity: 'Cable' };14 if (err) return console.error(err);15 console.log('Test status:', data.statusText);16 wpt.exposure_get(data.data.testId, function(err, data) {17 if (err) return console.error(err);18 console.log('Test status:', data.statusText);19 });20});21var wpt = require('webpagetest');22var wpt = new WebPageTest('www.webpagetest.org');23var options = { location: 'Dulles:Chrome', runs: 3, connectivity: 'Cable' };24 if (err) return console.error(err);25 console.log('Test status:', data.statusText);26 wpt.test_status(data.data.testId, function(err, data) {27 if (err) return console.error(err);28 console.log('Test status:', data.statusText);29 });30});31var wpt = require('webpagetest');32var wpt = new WebPageTest('www.webpagetest.org');33var options = { location: 'Dulles:Chrome', runs: 3, connectivity: 'Cable' };
Using AI Code Generation
1var wpt = require('webpagetest');2var client = wpt('www.webpagetest.org');3 if (err) {4 console.log("Error: " + err);5 } else {6 console.log("Test ID: " + data.data.testId);7 console.log("Test URL: " + data.data.summary);8 console.log("View Test: " + data.data.userUrl);9 }10});11var wpt = require('webpagetest');12var client = wpt('www.webpagetest.org');13 if (err) {14 console.log("Error: " + err);15 } else {16 console.log("Test ID: " + data.data.testId);17 console.log("Test URL: " + data.data.summary);18 console.log("View Test: " + data.data.userUrl);19 }20});21var wpt = require('webpagetest');22var client = wpt('www.webpagetest.org');23 if (err) {24 console.log("Error: " + err);25 } else {26 console.log("Test ID: " + data.data.testId);27 console.log("Test URL: " + data.data.summary);28 console.log("View Test: " + data.data.userUrl);29 }30});31var wpt = require('webpagetest');32var client = wpt('www.webpagetest.org');33 if (err) {34 console.log("Error: " + err);35 } else {36 console.log("Test ID: " + data.data.testId);37 console.log("Test URL: " + data.data.summary);38 console.log("View Test: " + data.data.userUrl);39 }40});41var wpt = require('webpagetest');42var client = wpt('www
Using AI Code Generation
1var wptdriver = require('wptdriver');2wptdriver.exposure_set('test_exposure', 1);3var wptdriver = require('wptdriver');4wptdriver.exposure_get('test_exposure');5var wptdriver = require('wptdriver');6wptdriver.exposure_clear('test_exposure');7var wptdriver = require('wptdriver');8wptdriver.exposure_clear_all();9var wptdriver = require('wptdriver');10wptdriver.exposure_get_all();11* `wptdriver.log_level(level)`12* `wptdriver.log(message, level)`13* `wptdriver.network_emulation_set(network_type, latency, downstream_kbps, upstream_kbps, packet_loss)`14* `Native` - use the native network connection (no emulation)15* `wptdriver.network_clear()`16* `wptdriver.cookie_set(cookie_name, cookie_value, cookie_domain, cookie_path, cookie_expires, cookie_secure, cookie_http_only)`17* `wptdriver.cookie_get(cookie_name
Using AI Code Generation
1var wpt = require('webpagetest');2var client = wpt('www.webpagetest.org');3client.exposure_set('TestID', '1', function(err, data) {4 if (err) {5 console.log(err);6 }7 console.log(data);8});9Name Type Description testId String Test ID exposure Integer Exposure value (0-3)10{11 "data": {12 }13}
Using AI Code Generation
1var wptools = require('wptools');2var wiki = new wptools('Albert Einstein');3wiki.exposure_set('enwiki');4wiki.exposure_set('enwiki', 'Albert Einstein');5wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein');6wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');7wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');8wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');9wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');10wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');11wiki.exposure_set('enwiki', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein', 'Albert Einstein');12wiki.exposure_set('enwiki', 'Albert Einstein', 'Al
Using AI Code Generation
1var wpt = require('./wpt.js');2var exposure_time = 10;3var file_name = 'test.jpg';4wpt.exposure_set(exposure_time, function(err, data) {5 if (err) {6 console.log(err);7 } else {8 console.log(data);9 wpt.take_picture(file_name, function(err, data) {10 if (err) {11 console.log(err);12 } else {13 console.log(data);14 }15 });16 }17});
Using AI Code Generation
1var wpt = require('WebPageTest');2var wpt = new WebPageTest('www.webpagetest.org');3var options = {4};5 if (err) return console.error(err);6 console.log(data.response.data.testId);7 wpt.exposure_set(data.response.data.testId, '3', function(err, data) {8 if (err) return console.error(err);9 console.log(data);10 });11});12### <a name="exposure_get"></a>exposure_get(testId, callback)13var wpt = require('WebPageTest');14var wpt = new WebPageTest('www.webpagetest.org');15var options = {16};17 if (err) return console.error(err);18 console.log(data.response.data.testId);19 wpt.exposure_get(data.response.data.testId, function(err, data) {20 if (err) return console.error(err);21 console.log(data);22 });23});24### <a name="getLocations"></a>getLocations(callback)
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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!