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 |
72 /// IdlArray /// | 100 /// IdlArray /// |
73 // Entry point | 101 // Entry point |
74 self.IdlArray = function() | 102 self.IdlArray = function() |
75 //@{ | 103 //@{ |
76 { | 104 { |
77 /** | 105 /** |
78 * A map from strings to the corresponding named IdlObject, such as | 106 * A map from strings to the corresponding named IdlObject, such as |
79 * IdlInterface or IdlException. These are the things that test() will run | 107 * IdlInterface or IdlException. These are the things that test() will run |
80 * tests on. | 108 * tests on. |
81 */ | 109 */ |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 */ | 565 */ |
538 this.base = obj.inheritance; | 566 this.base = obj.inheritance; |
539 } | 567 } |
540 | 568 |
541 //@} | 569 //@} |
542 IdlDictionary.prototype = Object.create(IdlObject.prototype); | 570 IdlDictionary.prototype = Object.create(IdlObject.prototype); |
543 | 571 |
544 /// IdlInterface /// | 572 /// IdlInterface /// |
545 function IdlInterface(obj, is_callback) { | 573 function IdlInterface(obj, is_callback) { |
546 /** | 574 /** |
547 * obj is an object produced by the WebIDLParser.js "exception" or | 575 * obj is an object produced by the WebIDLParser.js "interface" production. |
548 * "interface" production, as appropriate. | |
549 */ | 576 */ |
550 | 577 |
551 /** Self-explanatory. */ | 578 /** Self-explanatory. */ |
552 this.name = obj.name; | 579 this.name = obj.name; |
553 | 580 |
554 /** A back-reference to our IdlArray. */ | 581 /** A back-reference to our IdlArray. */ |
555 this.array = obj.array; | 582 this.array = obj.array; |
556 | 583 |
557 /** | 584 /** |
558 * An indicator of whether we should run tests on the (exception) interface | 585 * An indicator of whether we should run tests on the interface object and |
559 * object and (exception) interface prototype object. Tests on members are | 586 * interface prototype object. Tests on members are controlled by .untested |
560 * controlled by .untested on each member, not this. | 587 * on each member, not this. |
561 */ | 588 */ |
562 this.untested = obj.untested; | 589 this.untested = obj.untested; |
563 | 590 |
564 /** An array of objects produced by the "ExtAttr" production. */ | 591 /** An array of objects produced by the "ExtAttr" production. */ |
565 this.extAttrs = obj.extAttrs; | 592 this.extAttrs = obj.extAttrs; |
566 | 593 |
567 /** An array of IdlInterfaceMembers. */ | 594 /** An array of IdlInterfaceMembers. */ |
568 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m);
}); | 595 this.members = obj.members.map(function(m){return new IdlInterfaceMember(m);
}); |
569 if (this.has_extended_attribute("Unforgeable")) { | 596 if (this.has_extended_attribute("Unforgeable")) { |
570 this.members | 597 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"); | 964 assert_true(desc.configurable, this.name + ".prototype.constructor in no
t configurable"); |
938 assert_equals(self[this.name].prototype.constructor, self[this.name], | 965 assert_equals(self[this.name].prototype.constructor, self[this.name], |
939 this.name + '.prototype.constructor is not the same object
as ' + this.name); | 966 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'); | 967 }.bind(this), this.name + ' interface: existence and properties of interface
prototype object\'s "constructor" property'); |
941 }; | 968 }; |
942 | 969 |
943 //@} | 970 //@} |
944 IdlInterface.prototype.test_member_const = function(member) | 971 IdlInterface.prototype.test_member_const = function(member) |
945 //@{ | 972 //@{ |
946 { | 973 { |
| 974 if (!this.has_constants()) { |
| 975 throw "Internal error: test_member_const called without any constants"; |
| 976 } |
| 977 |
947 test(function() | 978 test(function() |
948 { | 979 { |
949 if (this.is_callback() && !this.has_constants()) { | |
950 return; | |
951 } | |
952 | |
953 assert_own_property(self, this.name, | 980 assert_own_property(self, this.name, |
954 "self does not have own property " + format_value(th
is.name)); | 981 "self does not have own property " + format_value(th
is.name)); |
955 | 982 |
956 // "For each constant defined on an interface A, there must be | 983 // "For each constant defined on an interface A, there must be |
957 // a corresponding property on the interface object, if it | 984 // a corresponding property on the interface object, if it |
958 // exists." | 985 // exists." |
959 assert_own_property(self[this.name], member.name); | 986 assert_own_property(self[this.name], member.name); |
960 // "The value of the property is that which is obtained by | 987 // "The value of the property is that which is obtained by |
961 // converting the constant’s IDL value to an ECMAScript | 988 // converting the constant’s IDL value to an ECMAScript |
962 // value." | 989 // value." |
963 assert_equals(self[this.name][member.name], constValue(member.value), | 990 assert_equals(self[this.name][member.name], constValue(member.value), |
964 "property has wrong value"); | 991 "property has wrong value"); |
965 // "The property has attributes { [[Writable]]: false, | 992 // "The property has attributes { [[Writable]]: false, |
966 // [[Enumerable]]: true, [[Configurable]]: false }." | 993 // [[Enumerable]]: true, [[Configurable]]: false }." |
967 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name)
; | 994 var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name)
; |
968 assert_false("get" in desc, "property has getter"); | 995 assert_false("get" in desc, "property has getter"); |
969 assert_false("set" in desc, "property has setter"); | 996 assert_false("set" in desc, "property has setter"); |
970 assert_false(desc.writable, "property is writable"); | 997 assert_false(desc.writable, "property is writable"); |
971 assert_true(desc.enumerable, "property is not enumerable"); | 998 assert_true(desc.enumerable, "property is not enumerable"); |
972 assert_false(desc.configurable, "property is configurable"); | 999 assert_false(desc.configurable, "property is configurable"); |
973 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face object"); | 1000 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face object"); |
| 1001 |
974 // "In addition, a property with the same characteristics must | 1002 // "In addition, a property with the same characteristics must |
975 // exist on the interface prototype object." | 1003 // exist on the interface prototype object." |
976 test(function() | 1004 test(function() |
977 { | 1005 { |
978 if (this.is_callback() && !this.has_constants()) { | |
979 return; | |
980 } | |
981 | |
982 assert_own_property(self, this.name, | 1006 assert_own_property(self, this.name, |
983 "self does not have own property " + format_value(th
is.name)); | 1007 "self does not have own property " + format_value(th
is.name)); |
984 | 1008 |
985 if (this.is_callback()) { | 1009 if (this.is_callback()) { |
986 assert_false("prototype" in self[this.name], | 1010 assert_false("prototype" in self[this.name], |
987 this.name + ' should not have a "prototype" property'); | 1011 this.name + ' should not have a "prototype" property'); |
988 return; | 1012 return; |
989 } | 1013 } |
990 | 1014 |
991 assert_own_property(self[this.name], "prototype", | 1015 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 " + | 1048 "The interface object must have a property " + |
1025 format_value(member.name)); | 1049 format_value(member.name)); |
1026 } else if (this.is_global()) { | 1050 } else if (this.is_global()) { |
1027 assert_own_property(self, member.name, | 1051 assert_own_property(self, member.name, |
1028 "The global object must have a property " + | 1052 "The global object must have a property " + |
1029 format_value(member.name)); | 1053 format_value(member.name)); |
1030 assert_false(member.name in self[this.name].prototype, | 1054 assert_false(member.name in self[this.name].prototype, |
1031 "The prototype object must not have a property " + | 1055 "The prototype object must not have a property " + |
1032 format_value(member.name)); | 1056 format_value(member.name)); |
1033 | 1057 |
| 1058 var getter = Object.getOwnPropertyDescriptor(self, member.name).get; |
| 1059 assert_equals(typeof(getter), "function", |
| 1060 format_value(member.name) + " must have a getter"); |
| 1061 |
1034 // Try/catch around the get here, since it can legitimately throw. | 1062 // Try/catch around the get here, since it can legitimately throw. |
1035 // If it does, we obviously can't check for equality with direct | 1063 // If it does, we obviously can't check for equality with direct |
1036 // invocation of the getter. | 1064 // invocation of the getter. |
1037 var gotValue; | 1065 var gotValue; |
1038 var propVal; | 1066 var propVal; |
1039 try { | 1067 try { |
1040 propVal = self[member.name]; | 1068 propVal = self[member.name]; |
1041 gotValue = true; | 1069 gotValue = true; |
1042 } catch (e) { | 1070 } catch (e) { |
1043 gotValue = false; | 1071 gotValue = false; |
1044 } | 1072 } |
1045 if (gotValue) { | 1073 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), | 1074 assert_equals(propVal, getter.call(undefined), |
1050 "Gets on a global should not require an explicit t
his"); | 1075 "Gets on a global should not require an explicit t
his"); |
1051 } | 1076 } |
| 1077 |
1052 this.do_interface_attribute_asserts(self, member); | 1078 this.do_interface_attribute_asserts(self, member); |
1053 } else { | 1079 } else { |
1054 assert_true(member.name in self[this.name].prototype, | 1080 assert_true(member.name in self[this.name].prototype, |
1055 "The prototype object must have a property " + | 1081 "The prototype object must have a property " + |
1056 format_value(member.name)); | 1082 format_value(member.name)); |
1057 | 1083 |
1058 if (!member.has_extended_attribute("LenientThis")) { | 1084 if (!member.has_extended_attribute("LenientThis")) { |
1059 assert_throws(new TypeError(), function() { | 1085 assert_throws(new TypeError(), function() { |
1060 self[this.name].prototype[member.name]; | 1086 self[this.name].prototype[member.name]; |
1061 }.bind(this), "getting property on prototype object must throw T
ypeError"); | 1087 }.bind(this), "getting property on prototype object must throw T
ypeError"); |
1062 } else { | 1088 } else { |
1063 assert_equals(self[this.name].prototype[member.name], undefined, | 1089 assert_equals(self[this.name].prototype[member.name], undefined, |
1064 "getting property on prototype object must return
undefined"); | 1090 "getting property on prototype object must return
undefined"); |
1065 } | 1091 } |
1066 this.do_interface_attribute_asserts(self[this.name].prototype, membe
r); | 1092 this.do_interface_attribute_asserts(self[this.name].prototype, membe
r); |
1067 } | 1093 } |
1068 }.bind(this), this.name + " interface: attribute " + member.name); | 1094 }.bind(this), this.name + " interface: attribute " + member.name); |
1069 }; | 1095 }; |
1070 | 1096 |
1071 //@} | 1097 //@} |
1072 IdlInterface.prototype.test_member_operation = function(member) | 1098 IdlInterface.prototype.test_member_operation = function(member) |
1073 //@{ | 1099 //@{ |
1074 { | 1100 { |
1075 test(function() | 1101 var a_test = async_test(this.name + " interface: operation " + member.name + |
| 1102 "(" + member.arguments.map( |
| 1103 function(m) {return m.idlType.idlType; } ) |
| 1104 +")"); |
| 1105 a_test.step(function() |
1076 { | 1106 { |
| 1107 // This function tests WebIDL as of 2015-12-29. |
| 1108 // https://heycam.github.io/webidl/#es-operations |
| 1109 |
1077 if (this.is_callback() && !this.has_constants()) { | 1110 if (this.is_callback() && !this.has_constants()) { |
| 1111 a_test.done(); |
1078 return; | 1112 return; |
1079 } | 1113 } |
1080 | 1114 |
1081 assert_own_property(self, this.name, | 1115 assert_own_property(self, this.name, |
1082 "self does not have own property " + format_value(th
is.name)); | 1116 "self does not have own property " + format_value(th
is.name)); |
1083 | 1117 |
1084 if (this.is_callback()) { | 1118 if (this.is_callback()) { |
1085 assert_false("prototype" in self[this.name], | 1119 assert_false("prototype" in self[this.name], |
1086 this.name + ' should not have a "prototype" property'); | 1120 this.name + ' should not have a "prototype" property'); |
| 1121 a_test.done(); |
1087 return; | 1122 return; |
1088 } | 1123 } |
1089 | 1124 |
1090 assert_own_property(self[this.name], "prototype", | 1125 assert_own_property(self[this.name], "prototype", |
1091 'interface "' + this.name + '" does not have own pro
perty "prototype"'); | 1126 'interface "' + this.name + '" does not have own pro
perty "prototype"'); |
1092 | 1127 |
1093 // "For each unique identifier of an operation defined on the | 1128 // "For each unique identifier of an exposed operation defined on the |
1094 // interface, there must be a corresponding property on the | 1129 // interface, there must exist a corresponding property, unless the |
1095 // interface prototype object (if it is a regular operation) or | 1130 // effective overload set for that identifier and operation and with an |
1096 // the interface object (if it is a static operation), unless | 1131 // argument count of 0 has no entries." |
1097 // the effective overload set for that identifier and operation | 1132 |
1098 // and with an argument count of 0 (for the ECMAScript language | 1133 // TODO: Consider [Exposed]. |
1099 // binding) has no entries." | 1134 |
1100 // | 1135 // "The location of the property is determined as follows:" |
1101 var memberHolderObject; | 1136 var memberHolderObject; |
| 1137 // "* If the operation is static, then the property exists on the |
| 1138 // interface object." |
1102 if (member["static"]) { | 1139 if (member["static"]) { |
1103 assert_own_property(self[this.name], member.name, | 1140 assert_own_property(self[this.name], member.name, |
1104 "interface object missing static operation"); | 1141 "interface object missing static operation"); |
1105 memberHolderObject = self[this.name]; | 1142 memberHolderObject = self[this.name]; |
| 1143 // "* Otherwise, [...] if the interface was declared with the [Global] |
| 1144 // or [PrimaryGlobal] extended attribute, then the property exists |
| 1145 // on every object that implements the interface." |
1106 } else if (this.is_global()) { | 1146 } else if (this.is_global()) { |
1107 assert_own_property(self, member.name, | 1147 assert_own_property(self, member.name, |
1108 "global object missing non-static operation"); | 1148 "global object missing non-static operation"); |
1109 memberHolderObject = self; | 1149 memberHolderObject = self; |
| 1150 // "* Otherwise, the property exists solely on the interface’s |
| 1151 // interface prototype object." |
1110 } else { | 1152 } else { |
1111 assert_own_property(self[this.name].prototype, member.name, | 1153 assert_own_property(self[this.name].prototype, member.name, |
1112 "interface prototype object missing non-static operation"); | 1154 "interface prototype object missing non-static operation"); |
1113 memberHolderObject = self[this.name].prototype; | 1155 memberHolderObject = self[this.name].prototype; |
1114 } | 1156 } |
1115 | 1157 this.do_member_operation_asserts(memberHolderObject, member, a_test); |
1116 this.do_member_operation_asserts(memberHolderObject, member); | 1158 }.bind(this)); |
1117 }.bind(this), this.name + " interface: operation " + member.name + | |
1118 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) + | |
1119 ")"); | |
1120 }; | 1159 }; |
1121 | 1160 |
1122 //@} | 1161 //@} |
1123 IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
, member) | 1162 IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
, member, a_test) |
1124 //@{ | 1163 //@{ |
1125 { | 1164 { |
| 1165 var done = a_test.done.bind(a_test); |
1126 var operationUnforgeable = member.isUnforgeable; | 1166 var operationUnforgeable = member.isUnforgeable; |
1127 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name); | 1167 var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name); |
1128 // "The property has attributes { [[Writable]]: B, | 1168 // "The property has attributes { [[Writable]]: B, |
1129 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the | 1169 // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the |
1130 // operation is unforgeable on the interface, and true otherwise". | 1170 // operation is unforgeable on the interface, and true otherwise". |
1131 assert_false("get" in desc, "property has getter"); | 1171 assert_false("get" in desc, "property has getter"); |
1132 assert_false("set" in desc, "property has setter"); | 1172 assert_false("set" in desc, "property has setter"); |
1133 assert_equals(desc.writable, !operationUnforgeable, | 1173 assert_equals(desc.writable, !operationUnforgeable, |
1134 "property should be writable if and only if not unforgeable"); | 1174 "property should be writable if and only if not unforgeable"); |
1135 assert_true(desc.enumerable, "property is not enumerable"); | 1175 assert_true(desc.enumerable, "property is not enumerable"); |
(...skipping 23 matching lines...) Expand all Loading... |
1159 // ". . . | 1199 // ". . . |
1160 // "Otherwise, throw a TypeError." | 1200 // "Otherwise, throw a TypeError." |
1161 // This should be hit if the operation is not static, there is | 1201 // This should be hit if the operation is not static, there is |
1162 // no [ImplicitThis] attribute, and the this value is null. | 1202 // no [ImplicitThis] attribute, and the this value is null. |
1163 // | 1203 // |
1164 // TODO: We currently ignore the [ImplicitThis] case. Except we manually | 1204 // TODO: We currently ignore the [ImplicitThis] case. Except we manually |
1165 // check for globals, since otherwise we'll invoke window.close(). And we | 1205 // 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", | 1206 // have to skip this test for anything that on the proto chain of "self", |
1167 // since that does in fact have implicit-this behavior. | 1207 // since that does in fact have implicit-this behavior. |
1168 if (!member["static"]) { | 1208 if (!member["static"]) { |
| 1209 var cb; |
1169 if (!this.is_global() && | 1210 if (!this.is_global() && |
1170 memberHolderObject[member.name] != self[member.name]) | 1211 memberHolderObject[member.name] != self[member.name]) |
1171 { | 1212 { |
1172 assert_throws(new TypeError(), function() { | 1213 cb = awaitNCallbacks(2, done); |
1173 memberHolderObject[member.name].apply(null, args); | 1214 throwOrReject(a_test, member, memberHolderObject[member.name], null,
args, |
1174 }, "calling operation with this = null didn't throw TypeError"); | 1215 "calling operation with this = null didn't throw TypeE
rror", cb); |
| 1216 } else { |
| 1217 cb = awaitNCallbacks(1, done); |
1175 } | 1218 } |
1176 | 1219 |
1177 // ". . . If O is not null and is also not a platform object | 1220 // ". . . If O is not null and is also not a platform object |
1178 // that implements interface I, throw a TypeError." | 1221 // that implements interface I, throw a TypeError." |
1179 // | 1222 // |
1180 // TODO: Test a platform object that implements some other | 1223 // TODO: Test a platform object that implements some other |
1181 // interface. (Have to be sure to get inheritance right.) | 1224 // interface. (Have to be sure to get inheritance right.) |
1182 assert_throws(new TypeError(), function() { | 1225 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, |
1183 memberHolderObject[member.name].apply({}, args); | 1226 "calling operation with this = {} didn't throw TypeError",
cb); |
1184 }, "calling operation with this = {} didn't throw TypeError"); | 1227 } else { |
| 1228 done(); |
1185 } | 1229 } |
1186 } | 1230 } |
1187 | 1231 |
1188 //@} | 1232 //@} |
1189 IdlInterface.prototype.test_member_stringifier = function(member) | 1233 IdlInterface.prototype.test_member_stringifier = function(member) |
1190 //@{ | 1234 //@{ |
1191 { | 1235 { |
1192 test(function() | 1236 test(function() |
1193 { | 1237 { |
1194 if (this.is_callback() && !this.has_constants()) { | 1238 if (this.is_callback() && !this.has_constants()) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 { | 1437 { |
1394 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1438 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1395 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1439 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1396 this.do_interface_attribute_asserts(obj, member); | 1440 this.do_interface_attribute_asserts(obj, member); |
1397 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); | 1441 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); |
1398 } | 1442 } |
1399 else if (member.type == "operation" && | 1443 else if (member.type == "operation" && |
1400 member.name && | 1444 member.name && |
1401 member.isUnforgeable) | 1445 member.isUnforgeable) |
1402 { | 1446 { |
1403 test(function() | 1447 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); |
| 1448 a_test.step(function() |
1404 { | 1449 { |
1405 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1450 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1406 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1451 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1407 assert_own_property(obj, member.name, | 1452 assert_own_property(obj, member.name, |
1408 "Doesn't have the unforgeable operation prop
erty"); | 1453 "Doesn't have the unforgeable operation prop
erty"); |
1409 this.do_member_operation_asserts(obj, member); | 1454 this.do_member_operation_asserts(obj, member, a_test); |
1410 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); | 1455 }.bind(this)); |
1411 } | 1456 } |
1412 else if ((member.type == "const" | 1457 else if ((member.type == "const" |
1413 || member.type == "attribute" | 1458 || member.type == "attribute" |
1414 || member.type == "operation") | 1459 || member.type == "operation") |
1415 && member.name) | 1460 && member.name) |
1416 { | 1461 { |
1417 test(function() | 1462 test(function() |
1418 { | 1463 { |
1419 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1464 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1420 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1465 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"); | 1498 assert_equals(typeof obj[member.name], "function"); |
1454 } | 1499 } |
1455 } | 1500 } |
1456 }.bind(this), this.name + " interface: " + desc + ' must inherit pro
perty "' + member.name + '" with the proper type (' + i + ')'); | 1501 }.bind(this), this.name + " interface: " + desc + ' must inherit pro
perty "' + member.name + '" with the proper type (' + i + ')'); |
1457 } | 1502 } |
1458 // TODO: This is wrong if there are multiple operations with the same | 1503 // TODO: This is wrong if there are multiple operations with the same |
1459 // identifier. | 1504 // identifier. |
1460 // TODO: Test passing arguments of the wrong type. | 1505 // TODO: Test passing arguments of the wrong type. |
1461 if (member.type == "operation" && member.name && member.arguments.length
) | 1506 if (member.type == "operation" && member.name && member.arguments.length
) |
1462 { | 1507 { |
1463 test(function() | 1508 var a_test = async_test( this.name + " interface: calling " + member
.name + |
| 1509 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }
) + |
| 1510 ") on " + desc + " with too few arguments must throw TypeError"); |
| 1511 a_test.step(function() |
1464 { | 1512 { |
1465 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1513 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1466 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1514 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1467 if (!member["static"]) { | 1515 if (!member["static"]) { |
1468 if (!this.is_global() && !member.isUnforgeable) { | 1516 if (!this.is_global() && !member.isUnforgeable) { |
1469 assert_inherits(obj, member.name); | 1517 assert_inherits(obj, member.name); |
1470 } else { | 1518 } else { |
1471 assert_own_property(obj, member.name); | 1519 assert_own_property(obj, member.name); |
1472 } | 1520 } |
1473 } | 1521 } |
1474 else | 1522 else |
1475 { | 1523 { |
1476 assert_false(member.name in obj); | 1524 assert_false(member.name in obj); |
1477 } | 1525 } |
1478 | 1526 |
1479 var minLength = minOverloadLength(this.members.filter(function(m
) { | 1527 var minLength = minOverloadLength(this.members.filter(function(m
) { |
1480 return m.type == "operation" && m.name == member.name; | 1528 return m.type == "operation" && m.name == member.name; |
1481 })); | 1529 })); |
1482 var args = []; | 1530 var args = []; |
| 1531 var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test)); |
1483 for (var i = 0; i < minLength; i++) { | 1532 for (var i = 0; i < minLength; i++) { |
1484 assert_throws(new TypeError(), function() | 1533 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 | 1534 |
1489 args.push(create_suitable_object(member.arguments[i].idlType
)); | 1535 args.push(create_suitable_object(member.arguments[i].idlType
)); |
1490 } | 1536 } |
1491 }.bind(this), this.name + " interface: calling " + member.name + | 1537 if (minLength === 0) { |
1492 "(" + member.arguments.map(function(m) { return m.idlType.idlType; }
) + | 1538 cb(); |
1493 ") on " + desc + " with too few arguments must throw TypeError"); | 1539 } |
| 1540 }.bind(this)); |
1494 } | 1541 } |
1495 } | 1542 } |
1496 }; | 1543 }; |
1497 | 1544 |
1498 //@} | 1545 //@} |
1499 IdlInterface.prototype.has_stringifier = function() | 1546 IdlInterface.prototype.has_stringifier = function() |
1500 //@{ | 1547 //@{ |
1501 { | 1548 { |
1502 if (this.members.some(function(member) { return member.stringifier; })) { | 1549 if (this.members.some(function(member) { return member.stringifier; })) { |
1503 return true; | 1550 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. */ | 1763 /** An array of values produced by the "typedef" production. */ |
1717 this.values = obj.values; | 1764 this.values = obj.values; |
1718 | 1765 |
1719 } | 1766 } |
1720 //@} | 1767 //@} |
1721 | 1768 |
1722 IdlTypedef.prototype = Object.create(IdlObject.prototype); | 1769 IdlTypedef.prototype = Object.create(IdlObject.prototype); |
1723 | 1770 |
1724 }()); | 1771 }()); |
1725 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: | 1772 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: |
OLD | NEW |