OLD | NEW |
1 /* | 1 /* |
2 Distributed under both the W3C Test Suite License [1] and the W3C | 2 Distributed under both the W3C Test Suite License [1] and the W3C |
3 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the | 3 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the |
4 policies and contribution forms [3]. | 4 policies and contribution forms [3]. |
5 | 5 |
6 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license | 6 [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license |
7 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license | 7 [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license |
8 [3] http://www.w3.org/2004/10/27-testcases | 8 [3] http://www.w3.org/2004/10/27-testcases |
9 */ | 9 */ |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 } | 62 } |
63 | 63 |
64 return overloads.map(function(attr) { | 64 return overloads.map(function(attr) { |
65 return attr.arguments ? attr.arguments.filter(function(arg) { | 65 return attr.arguments ? attr.arguments.filter(function(arg) { |
66 return !arg.optional && !arg.variadic; | 66 return !arg.optional && !arg.variadic; |
67 }).length : 0; | 67 }).length : 0; |
68 }) | 68 }) |
69 .reduce(function(m, n) { return Math.min(m, n); }); | 69 .reduce(function(m, n) { return Math.min(m, n); }); |
70 } | 70 } |
71 | 71 |
| 72 function throwOrReject(a_test, operation, fn, obj, args, message, cb) { |
| 73 if (operation.idlType.generic !== "Promise") { |
| 74 assert_throws(new TypeError(), function() { |
| 75 fn.apply(obj, args); |
| 76 }, message); |
| 77 cb(); |
| 78 } else { |
| 79 try { |
| 80 promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(c
b, cb); |
| 81 } catch (e){ |
| 82 a_test.step(function() { |
| 83 assert_unreached("Throws \"" + e + "\" instead of rejecting prom
ise"); |
| 84 cb(); |
| 85 }); |
| 86 } |
| 87 } |
| 88 } |
| 89 |
| 90 function awaitNCallbacks(n, cb, ctx) { |
| 91 var counter = 0; |
| 92 return function() { |
| 93 counter++; |
| 94 if (counter >= n) { |
| 95 cb(); |
| 96 } |
| 97 }; |
| 98 } |
| 99 |
| 100 var fround = (function(){ |
| 101 if (Math.fround) return Math.fround; |
| 102 |
| 103 var arr = new Float32Array(1); |
| 104 return function fround(n) { |
| 105 arr[0] = n; |
| 106 return arr[0]; |
| 107 }; |
| 108 })(); |
| 109 |
72 /// IdlArray /// | 110 /// IdlArray /// |
73 // Entry point | 111 // Entry point |
74 self.IdlArray = function() | 112 self.IdlArray = function() |
75 //@{ | 113 //@{ |
76 { | 114 { |
77 /** | 115 /** |
78 * A map from strings to the corresponding named IdlObject, such as | 116 * A map from strings to the corresponding named IdlObject, such as |
79 * IdlInterface or IdlException. These are the things that test() will run | 117 * IdlInterface or IdlException. These are the things that test() will run |
80 * tests on. | 118 * tests on. |
81 */ | 119 */ |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 assert_equals(typeof value, "number"); | 460 assert_equals(typeof value, "number"); |
423 return; | 461 return; |
424 | 462 |
425 case "unsigned long long": | 463 case "unsigned long long": |
426 case "DOMTimeStamp": | 464 case "DOMTimeStamp": |
427 assert_equals(typeof value, "number"); | 465 assert_equals(typeof value, "number"); |
428 assert_true(0 <= value, "unsigned long long is negative"); | 466 assert_true(0 <= value, "unsigned long long is negative"); |
429 return; | 467 return; |
430 | 468 |
431 case "float": | 469 case "float": |
| 470 assert_equals(typeof value, "number"); |
| 471 assert_equals(value, fround(value), "float rounded to 32-bit float s
hould be itself"); |
| 472 assert_not_equals(value, Infinity); |
| 473 assert_not_equals(value, -Infinity); |
| 474 assert_not_equals(value, NaN); |
| 475 return; |
| 476 |
| 477 case "DOMHighResTimeStamp": |
432 case "double": | 478 case "double": |
433 case "DOMHighResTimeStamp": | 479 assert_equals(typeof value, "number"); |
| 480 assert_not_equals(value, Infinity); |
| 481 assert_not_equals(value, -Infinity); |
| 482 assert_not_equals(value, NaN); |
| 483 return; |
| 484 |
434 case "unrestricted float": | 485 case "unrestricted float": |
| 486 assert_equals(typeof value, "number"); |
| 487 assert_equals(value, fround(value), "unrestricted float rounded to 3
2-bit float should be itself"); |
| 488 return; |
| 489 |
435 case "unrestricted double": | 490 case "unrestricted double": |
436 // TODO: distinguish these cases | |
437 assert_equals(typeof value, "number"); | 491 assert_equals(typeof value, "number"); |
438 return; | 492 return; |
439 | 493 |
440 case "DOMString": | 494 case "DOMString": |
441 case "ByteString": | |
442 case "USVString": | |
443 // TODO: https://github.com/w3c/testharness.js/issues/92 | |
444 assert_equals(typeof value, "string"); | 495 assert_equals(typeof value, "string"); |
445 return; | 496 return; |
446 | 497 |
| 498 case "ByteString": |
| 499 assert_equals(typeof value, "string"); |
| 500 assert_regexp_match(value, /^[\x00-\x7F]*$/); |
| 501 return; |
| 502 |
| 503 case "USVString": |
| 504 assert_equals(typeof value, "string"); |
| 505 assert_regexp_match(value, /^([\x00-\ud7ff\ue000-\uffff]|[\ud800-\ud
bff][\udc00-\udfff])*$/); |
| 506 return; |
| 507 |
447 case "object": | 508 case "object": |
448 assert_true(typeof value == "object" || typeof value == "function",
"wrong type: not object or function"); | 509 assert_true(typeof value == "object" || typeof value == "function",
"wrong type: not object or function"); |
449 return; | 510 return; |
450 } | 511 } |
451 | 512 |
452 if (!(type in this.members)) | 513 if (!(type in this.members)) |
453 { | 514 { |
454 throw "Unrecognized type " + type; | 515 throw "Unrecognized type " + type; |
455 } | 516 } |
456 | 517 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 */ | 598 */ |
538 this.base = obj.inheritance; | 599 this.base = obj.inheritance; |
539 } | 600 } |
540 | 601 |
541 //@} | 602 //@} |
542 IdlDictionary.prototype = Object.create(IdlObject.prototype); | 603 IdlDictionary.prototype = Object.create(IdlObject.prototype); |
543 | 604 |
544 /// IdlInterface /// | 605 /// IdlInterface /// |
545 function IdlInterface(obj, is_callback) { | 606 function IdlInterface(obj, is_callback) { |
546 /** | 607 /** |
547 * obj is an object produced by the WebIDLParser.js "exception" or | 608 * obj is an object produced by the WebIDLParser.js "interface" production. |
548 * "interface" production, as appropriate. | |
549 */ | 609 */ |
550 | 610 |
551 /** Self-explanatory. */ | 611 /** Self-explanatory. */ |
552 this.name = obj.name; | 612 this.name = obj.name; |
553 | 613 |
554 /** A back-reference to our IdlArray. */ | 614 /** A back-reference to our IdlArray. */ |
555 this.array = obj.array; | 615 this.array = obj.array; |
556 | 616 |
557 /** | 617 /** |
558 * An indicator of whether we should run tests on the (exception) interface | 618 * An indicator of whether we should run tests on the interface object and |
559 * object and (exception) interface prototype object. Tests on members are | 619 * interface prototype object. Tests on members are controlled by .untested |
560 * controlled by .untested on each member, not this. | 620 * on each member, not this. |
561 */ | 621 */ |
562 this.untested = obj.untested; | 622 this.untested = obj.untested; |
563 | 623 |
564 /** An array of objects produced by the "ExtAttr" production. */ | 624 /** An array of objects produced by the "ExtAttr" production. */ |
565 this.extAttrs = obj.extAttrs; | 625 this.extAttrs = obj.extAttrs; |
566 | 626 |
567 /** An array of IdlInterfaceMembers. */ | 627 /** An array of IdlInterfaceMembers. */ |
568 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m);
}); | 628 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m);
}); |
569 if (this.has_extended_attribute("Unforgeable")) { | 629 if (this.has_extended_attribute("Unforgeable")) { |
570 this.members | 630 this.members |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 assert_true(desc.configurable, this.name + ".prototype.constructor in no
t configurable"); | 997 assert_true(desc.configurable, this.name + ".prototype.constructor in no
t configurable"); |
938 assert_equals(self[this.name].prototype.constructor, self[this.name], | 998 assert_equals(self[this.name].prototype.constructor, self[this.name], |
939 this.name + '.prototype.constructor is not the same object
as ' + this.name); | 999 this.name + '.prototype.constructor is not the same object
as ' + this.name); |
940 }.bind(this), this.name + ' interface: existence and properties of interface
prototype object\'s "constructor" property'); | 1000 }.bind(this), this.name + ' interface: existence and properties of interface
prototype object\'s "constructor" property'); |
941 }; | 1001 }; |
942 | 1002 |
943 //@} | 1003 //@} |
944 IdlInterface.prototype.test_member_const = function(member) | 1004 IdlInterface.prototype.test_member_const = function(member) |
945 //@{ | 1005 //@{ |
946 { | 1006 { |
| 1007 if (!this.has_constants()) { |
| 1008 throw "Internal error: test_member_const called without any constants"; |
| 1009 } |
| 1010 |
947 test(function() | 1011 test(function() |
948 { | 1012 { |
949 if (this.is_callback() && !this.has_constants()) { | |
950 return; | |
951 } | |
952 | |
953 assert_own_property(self, this.name, | 1013 assert_own_property(self, this.name, |
954 "self does not have own property " + format_value(th
is.name)); | 1014 "self does not have own property " + format_value(th
is.name)); |
955 | 1015 |
956 // "For each constant defined on an interface A, there must be | 1016 // "For each constant defined on an interface A, there must be |
957 // a corresponding property on the interface object, if it | 1017 // a corresponding property on the interface object, if it |
958 // exists." | 1018 // exists." |
959 assert_own_property(self[this.name], member.name); | 1019 assert_own_property(self[this.name], member.name); |
960 // "The value of the property is that which is obtained by | 1020 // "The value of the property is that which is obtained by |
961 // converting the constant’s IDL value to an ECMAScript | 1021 // converting the constant’s IDL value to an ECMAScript |
962 // value." | 1022 // value." |
963 assert_equals(self[this.name][member.name], constValue(member.value), | 1023 assert_equals(self[this.name][member.name], constValue(member.value), |
964 "property has wrong value"); | 1024 "property has wrong value"); |
965 // "The property has attributes { [[Writable]]: false, | 1025 // "The property has attributes { [[Writable]]: false, |
966 // [[Enumerable]]: true, [[Configurable]]: false }." | 1026 // [[Enumerable]]: true, [[Configurable]]: false }." |
967 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name)
; | 1027 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name)
; |
968 assert_false("get" in desc, "property has getter"); | 1028 assert_false("get" in desc, "property has getter"); |
969 assert_false("set" in desc, "property has setter"); | 1029 assert_false("set" in desc, "property has setter"); |
970 assert_false(desc.writable, "property is writable"); | 1030 assert_false(desc.writable, "property is writable"); |
971 assert_true(desc.enumerable, "property is not enumerable"); | 1031 assert_true(desc.enumerable, "property is not enumerable"); |
972 assert_false(desc.configurable, "property is configurable"); | 1032 assert_false(desc.configurable, "property is configurable"); |
973 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face object"); | 1033 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face object"); |
| 1034 |
974 // "In addition, a property with the same characteristics must | 1035 // "In addition, a property with the same characteristics must |
975 // exist on the interface prototype object." | 1036 // exist on the interface prototype object." |
976 test(function() | 1037 test(function() |
977 { | 1038 { |
978 if (this.is_callback() && !this.has_constants()) { | |
979 return; | |
980 } | |
981 | |
982 assert_own_property(self, this.name, | 1039 assert_own_property(self, this.name, |
983 "self does not have own property " + format_value(th
is.name)); | 1040 "self does not have own property " + format_value(th
is.name)); |
984 | 1041 |
985 if (this.is_callback()) { | 1042 if (this.is_callback()) { |
986 assert_false("prototype" in self[this.name], | 1043 assert_false("prototype" in self[this.name], |
987 this.name + ' should not have a "prototype" property'); | 1044 this.name + ' should not have a "prototype" property'); |
988 return; | 1045 return; |
989 } | 1046 } |
990 | 1047 |
991 assert_own_property(self[this.name], "prototype", | 1048 assert_own_property(self[this.name], "prototype", |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 "The interface object must have a property " + | 1081 "The interface object must have a property " + |
1025 format_value(member.name)); | 1082 format_value(member.name)); |
1026 } else if (this.is_global()) { | 1083 } else if (this.is_global()) { |
1027 assert_own_property(self, member.name, | 1084 assert_own_property(self, member.name, |
1028 "The global object must have a property " + | 1085 "The global object must have a property " + |
1029 format_value(member.name)); | 1086 format_value(member.name)); |
1030 assert_false(member.name in self[this.name].prototype, | 1087 assert_false(member.name in self[this.name].prototype, |
1031 "The prototype object must not have a property " + | 1088 "The prototype object must not have a property " + |
1032 format_value(member.name)); | 1089 format_value(member.name)); |
1033 | 1090 |
| 1091 var getter = Object.getOwnPropertyDescriptor(self, member.name).get; |
| 1092 assert_equals(typeof(getter), "function", |
| 1093 format_value(member.name) + " must have a getter"); |
| 1094 |
1034 // Try/catch around the get here, since it can legitimately throw. | 1095 // Try/catch around the get here, since it can legitimately throw. |
1035 // If it does, we obviously can't check for equality with direct | 1096 // If it does, we obviously can't check for equality with direct |
1036 // invocation of the getter. | 1097 // invocation of the getter. |
1037 var gotValue; | 1098 var gotValue; |
1038 var propVal; | 1099 var propVal; |
1039 try { | 1100 try { |
1040 propVal = self[member.name]; | 1101 propVal = self[member.name]; |
1041 gotValue = true; | 1102 gotValue = true; |
1042 } catch (e) { | 1103 } catch (e) { |
1043 gotValue = false; | 1104 gotValue = false; |
1044 } | 1105 } |
1045 if (gotValue) { | 1106 if (gotValue) { |
1046 var getter = Object.getOwnPropertyDescriptor(self, member.name).
get; | |
1047 assert_equals(typeof(getter), "function", | |
1048 format_value(member.name) + " must have a getter")
; | |
1049 assert_equals(propVal, getter.call(undefined), | 1107 assert_equals(propVal, getter.call(undefined), |
1050 "Gets on a global should not require an explicit t
his"); | 1108 "Gets on a global should not require an explicit t
his"); |
1051 } | 1109 } |
| 1110 |
1052 this.do_interface_attribute_asserts(self, member); | 1111 this.do_interface_attribute_asserts(self, member); |
1053 } else { | 1112 } else { |
1054 assert_true(member.name in self[this.name].prototype, | 1113 assert_true(member.name in self[this.name].prototype, |
1055 "The prototype object must have a property " + | 1114 "The prototype object must have a property " + |
1056 format_value(member.name)); | 1115 format_value(member.name)); |
1057 | 1116 |
1058 if (!member.has_extended_attribute("LenientThis")) { | 1117 if (!member.has_extended_attribute("LenientThis")) { |
1059 assert_throws(new TypeError(), function() { | 1118 assert_throws(new TypeError(), function() { |
1060 self[this.name].prototype[member.name]; | 1119 self[this.name].prototype[member.name]; |
1061 }.bind(this), "getting property on prototype object must throw T
ypeError"); | 1120 }.bind(this), "getting property on prototype object must throw T
ypeError"); |
1062 } else { | 1121 } else { |
1063 assert_equals(self[this.name].prototype[member.name], undefined, | 1122 assert_equals(self[this.name].prototype[member.name], undefined, |
1064 "getting property on prototype object must return
undefined"); | 1123 "getting property on prototype object must return
undefined"); |
1065 } | 1124 } |
1066 this.do_interface_attribute_asserts(self[this.name].prototype, membe
r); | 1125 this.do_interface_attribute_asserts(self[this.name].prototype, membe
r); |
1067 } | 1126 } |
1068 }.bind(this), this.name + " interface: attribute " + member.name); | 1127 }.bind(this), this.name + " interface: attribute " + member.name); |
1069 }; | 1128 }; |
1070 | 1129 |
1071 //@} | 1130 //@} |
1072 IdlInterface.prototype.test_member_operation = function(member) | 1131 IdlInterface.prototype.test_member_operation = function(member) |
1073 //@{ | 1132 //@{ |
1074 { | 1133 { |
1075 test(function() | 1134 var a_test = async_test(this.name + " interface: operation " + member.name + |
| 1135 "(" + member.arguments.map( |
| 1136 function(m) {return m.idlType.idlType; } ) |
| 1137 +")"); |
| 1138 a_test.step(function() |
1076 { | 1139 { |
| 1140 // This function tests WebIDL as of 2015-12-29. |
| 1141 // https://heycam.github.io/webidl/#es-operations |
| 1142 |
1077 if (this.is_callback() && !this.has_constants()) { | 1143 if (this.is_callback() && !this.has_constants()) { |
| 1144 a_test.done(); |
1078 return; | 1145 return; |
1079 } | 1146 } |
1080 | 1147 |
1081 assert_own_property(self, this.name, | 1148 assert_own_property(self, this.name, |
1082 "self does not have own property " + format_value(th
is.name)); | 1149 "self does not have own property " + format_value(th
is.name)); |
1083 | 1150 |
1084 if (this.is_callback()) { | 1151 if (this.is_callback()) { |
1085 assert_false("prototype" in self[this.name], | 1152 assert_false("prototype" in self[this.name], |
1086 this.name + ' should not have a "prototype" property'); | 1153 this.name + ' should not have a "prototype" property'); |
| 1154 a_test.done(); |
1087 return; | 1155 return; |
1088 } | 1156 } |
1089 | 1157 |
1090 assert_own_property(self[this.name], "prototype", | 1158 assert_own_property(self[this.name], "prototype", |
1091 'interface "' + this.name + '" does not have own pro
perty "prototype"'); | 1159 'interface "' + this.name + '" does not have own pro
perty "prototype"'); |
1092 | 1160 |
1093 // "For each unique identifier of an operation defined on the | 1161 // "For each unique identifier of an exposed operation defined on the |
1094 // interface, there must be a corresponding property on the | 1162 // interface, there must exist a corresponding property, unless the |
1095 // interface prototype object (if it is a regular operation) or | 1163 // effective overload set for that identifier and operation and with an |
1096 // the interface object (if it is a static operation), unless | 1164 // argument count of 0 has no entries." |
1097 // the effective overload set for that identifier and operation | 1165 |
1098 // and with an argument count of 0 (for the ECMAScript language | 1166 // TODO: Consider [Exposed]. |
1099 // binding) has no entries." | 1167 |
1100 // | 1168 // "The location of the property is determined as follows:" |
1101 var memberHolderObject; | 1169 var memberHolderObject; |
| 1170 // "* If the operation is static, then the property exists on the |
| 1171 // interface object." |
1102 if (member["static"]) { | 1172 if (member["static"]) { |
1103 assert_own_property(self[this.name], member.name, | 1173 assert_own_property(self[this.name], member.name, |
1104 "interface object missing static operation"); | 1174 "interface object missing static operation"); |
1105 memberHolderObject = self[this.name]; | 1175 memberHolderObject = self[this.name]; |
| 1176 // "* Otherwise, [...] if the interface was declared with the [Global] |
| 1177 // or [PrimaryGlobal] extended attribute, then the property exists |
| 1178 // on every object that implements the interface." |
1106 } else if (this.is_global()) { | 1179 } else if (this.is_global()) { |
1107 assert_own_property(self, member.name, | 1180 assert_own_property(self, member.name, |
1108 "global object missing non-static operation"); | 1181 "global object missing non-static operation"); |
1109 memberHolderObject = self; | 1182 memberHolderObject = self; |
| 1183 // "* Otherwise, the property exists solely on the interface’s |
| 1184 // interface prototype object." |
1110 } else { | 1185 } else { |
1111 assert_own_property(self[this.name].prototype, member.name, | 1186 assert_own_property(self[this.name].prototype, member.name, |
1112 "interface prototype object missing non-static operation"); | 1187 "interface prototype object missing non-static operation"); |
1113 memberHolderObject = self[this.name].prototype; | 1188 memberHolderObject = self[this.name].prototype; |
1114 } | 1189 } |
1115 | 1190 this.do_member_operation_asserts(memberHolderObject, member, a_test); |
1116 this.do_member_operation_asserts(memberHolderObject, member); | 1191 }.bind(this)); |
1117 }.bind(this), this.name + " interface: operation " + member.name + | |
1118 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + | |
1119 ")"); | |
1120 }; | 1192 }; |
1121 | 1193 |
1122 //@} | 1194 //@} |
1123 IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
, member) | 1195 IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
, member, a_test) |
1124 //@{ | 1196 //@{ |
1125 { | 1197 { |
| 1198 var done = a_test.done.bind(a_test); |
1126 var operationUnforgeable = member.isUnforgeable; | 1199 var operationUnforgeable = member.isUnforgeable; |
1127 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name); | 1200 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name); |
1128 // "The property has attributes { [[Writable]]: B, | 1201 // "The property has attributes { [[Writable]]: B, |
1129 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the | 1202 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the |
1130 // operation is unforgeable on the interface, and true otherwise". | 1203 // operation is unforgeable on the interface, and true otherwise". |
1131 assert_false("get" in desc, "property has getter"); | 1204 assert_false("get" in desc, "property has getter"); |
1132 assert_false("set" in desc, "property has setter"); | 1205 assert_false("set" in desc, "property has setter"); |
1133 assert_equals(desc.writable, !operationUnforgeable, | 1206 assert_equals(desc.writable, !operationUnforgeable, |
1134 "property should be writable if and only if not unforgeable"); | 1207 "property should be writable if and only if not unforgeable"); |
1135 assert_true(desc.enumerable, "property is not enumerable"); | 1208 assert_true(desc.enumerable, "property is not enumerable"); |
(...skipping 23 matching lines...) Expand all Loading... |
1159 // ". . . | 1232 // ". . . |
1160 // "Otherwise, throw a TypeError." | 1233 // "Otherwise, throw a TypeError." |
1161 // This should be hit if the operation is not static, there is | 1234 // This should be hit if the operation is not static, there is |
1162 // no [ImplicitThis] attribute, and the this value is null. | 1235 // no [ImplicitThis] attribute, and the this value is null. |
1163 // | 1236 // |
1164 // TODO: We currently ignore the [ImplicitThis] case. Except we manually | 1237 // TODO: We currently ignore the [ImplicitThis] case. Except we manually |
1165 // check for globals, since otherwise we'll invoke window.close(). And we | 1238 // check for globals, since otherwise we'll invoke window.close(). And we |
1166 // have to skip this test for anything that on the proto chain of "self", | 1239 // have to skip this test for anything that on the proto chain of "self", |
1167 // since that does in fact have implicit-this behavior. | 1240 // since that does in fact have implicit-this behavior. |
1168 if (!member["static"]) { | 1241 if (!member["static"]) { |
| 1242 var cb; |
1169 if (!this.is_global() && | 1243 if (!this.is_global() && |
1170 memberHolderObject[member.name] != self[member.name]) | 1244 memberHolderObject[member.name] != self[member.name]) |
1171 { | 1245 { |
1172 assert_throws(new TypeError(), function() { | 1246 cb = awaitNCallbacks(2, done); |
1173 memberHolderObject[member.name].apply(null, args); | 1247 throwOrReject(a_test, member, memberHolderObject[member.name], null,
args, |
1174 }, "calling operation with this = null didn't throw TypeError"); | 1248 "calling operation with this = null didn't throw TypeE
rror", cb); |
| 1249 } else { |
| 1250 cb = awaitNCallbacks(1, done); |
1175 } | 1251 } |
1176 | 1252 |
1177 // ". . . If O is not null and is also not a platform object | 1253 // ". . . If O is not null and is also not a platform object |
1178 // that implements interface I, throw a TypeError." | 1254 // that implements interface I, throw a TypeError." |
1179 // | 1255 // |
1180 // TODO: Test a platform object that implements some other | 1256 // TODO: Test a platform object that implements some other |
1181 // interface. (Have to be sure to get inheritance right.) | 1257 // interface. (Have to be sure to get inheritance right.) |
1182 assert_throws(new TypeError(), function() { | 1258 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, |
1183 memberHolderObject[member.name].apply({}, args); | 1259 "calling operation with this = {} didn't throw TypeError",
cb); |
1184 }, "calling operation with this = {} didn't throw TypeError"); | 1260 } else { |
| 1261 done(); |
1185 } | 1262 } |
1186 } | 1263 } |
1187 | 1264 |
1188 //@} | 1265 //@} |
1189 IdlInterface.prototype.test_member_stringifier = function(member) | 1266 IdlInterface.prototype.test_member_stringifier = function(member) |
1190 //@{ | 1267 //@{ |
1191 { | 1268 { |
1192 test(function() | 1269 test(function() |
1193 { | 1270 { |
1194 if (this.is_callback() && !this.has_constants()) { | 1271 if (this.is_callback() && !this.has_constants()) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 { | 1470 { |
1394 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1471 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1395 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1472 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1396 this.do_interface_attribute_asserts(obj, member); | 1473 this.do_interface_attribute_asserts(obj, member); |
1397 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); | 1474 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); |
1398 } | 1475 } |
1399 else if (member.type == "operation" && | 1476 else if (member.type == "operation" && |
1400 member.name && | 1477 member.name && |
1401 member.isUnforgeable) | 1478 member.isUnforgeable) |
1402 { | 1479 { |
1403 test(function() | 1480 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); |
| 1481 a_test.step(function() |
1404 { | 1482 { |
1405 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1483 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1406 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1484 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1407 assert_own_property(obj, member.name, | 1485 assert_own_property(obj, member.name, |
1408 "Doesn't have the unforgeable operation prop
erty"); | 1486 "Doesn't have the unforgeable operation prop
erty"); |
1409 this.do_member_operation_asserts(obj, member); | 1487 this.do_member_operation_asserts(obj, member, a_test); |
1410 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); | 1488 }.bind(this)); |
1411 } | 1489 } |
1412 else if ((member.type == "const" | 1490 else if ((member.type == "const" |
1413 || member.type == "attribute" | 1491 || member.type == "attribute" |
1414 || member.type == "operation") | 1492 || member.type == "operation") |
1415 && member.name) | 1493 && member.name) |
1416 { | 1494 { |
1417 test(function() | 1495 test(function() |
1418 { | 1496 { |
1419 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1497 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1420 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1498 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 assert_equals(typeof obj[member.name], "function"); | 1531 assert_equals(typeof obj[member.name], "function"); |
1454 } | 1532 } |
1455 } | 1533 } |
1456 }.bind(this), this.name + " interface: " + desc + ' must inherit pro
perty "' + member.name + '" with the proper type (' + i + ')'); | 1534 }.bind(this), this.name + " interface: " + desc + ' must inherit pro
perty "' + member.name + '" with the proper type (' + i + ')'); |
1457 } | 1535 } |
1458 // TODO: This is wrong if there are multiple operations with the same | 1536 // TODO: This is wrong if there are multiple operations with the same |
1459 // identifier. | 1537 // identifier. |
1460 // TODO: Test passing arguments of the wrong type. | 1538 // TODO: Test passing arguments of the wrong type. |
1461 if (member.type == "operation" && member.name && member.arguments.length
) | 1539 if (member.type == "operation" && member.name && member.arguments.length
) |
1462 { | 1540 { |
1463 test(function() | 1541 var a_test = async_test( this.name + " interface: calling " + member
.name + |
| 1542 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }
) + |
| 1543 ") on " + desc + " with too few arguments must throw TypeError"); |
| 1544 a_test.step(function() |
1464 { | 1545 { |
1465 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1546 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1466 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1547 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1467 if (!member["static"]) { | 1548 if (!member["static"]) { |
1468 if (!this.is_global() && !member.isUnforgeable) { | 1549 if (!this.is_global() && !member.isUnforgeable) { |
1469 assert_inherits(obj, member.name); | 1550 assert_inherits(obj, member.name); |
1470 } else { | 1551 } else { |
1471 assert_own_property(obj, member.name); | 1552 assert_own_property(obj, member.name); |
1472 } | 1553 } |
1473 } | 1554 } |
1474 else | 1555 else |
1475 { | 1556 { |
1476 assert_false(member.name in obj); | 1557 assert_false(member.name in obj); |
1477 } | 1558 } |
1478 | 1559 |
1479 var minLength = minOverloadLength(this.members.filter(function(m
) { | 1560 var minLength = minOverloadLength(this.members.filter(function(m
) { |
1480 return m.type == "operation" && m.name == member.name; | 1561 return m.type == "operation" && m.name == member.name; |
1481 })); | 1562 })); |
1482 var args = []; | 1563 var args = []; |
| 1564 var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test)); |
1483 for (var i = 0; i < minLength; i++) { | 1565 for (var i = 0; i < minLength; i++) { |
1484 assert_throws(new TypeError(), function() | 1566 throwOrReject(a_test, member, obj[member.name], obj, args,
"Called with " + i + " arguments", cb); |
1485 { | |
1486 obj[member.name].apply(obj, args); | |
1487 }.bind(this), "Called with " + i + " arguments"); | |
1488 | 1567 |
1489 args.push(create_suitable_object(member.arguments[i].idlType
)); | 1568 args.push(create_suitable_object(member.arguments[i].idlType
)); |
1490 } | 1569 } |
1491 }.bind(this), this.name + " interface: calling " + member.name + | 1570 if (minLength === 0) { |
1492 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }
) + | 1571 cb(); |
1493 ") on " + desc + " with too few arguments must throw TypeError"); | 1572 } |
| 1573 }.bind(this)); |
1494 } | 1574 } |
1495 } | 1575 } |
1496 }; | 1576 }; |
1497 | 1577 |
1498 //@} | 1578 //@} |
1499 IdlInterface.prototype.has_stringifier = function() | 1579 IdlInterface.prototype.has_stringifier = function() |
1500 //@{ | 1580 //@{ |
1501 { | 1581 { |
1502 if (this.members.some(function(member) { return member.stringifier; })) { | 1582 if (this.members.some(function(member) { return member.stringifier; })) { |
1503 return true; | 1583 return true; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 /** An array of values produced by the "typedef" production. */ | 1796 /** An array of values produced by the "typedef" production. */ |
1717 this.values = obj.values; | 1797 this.values = obj.values; |
1718 | 1798 |
1719 } | 1799 } |
1720 //@} | 1800 //@} |
1721 | 1801 |
1722 IdlTypedef.prototype = Object.create(IdlObject.prototype); | 1802 IdlTypedef.prototype = Object.create(IdlObject.prototype); |
1723 | 1803 |
1724 }()); | 1804 }()); |
1725 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: | 1805 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: |
OLD | NEW |