| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 * | 42 * |
| 43 * (Note that the version of WebIDLParser.js we use might sometimes be | 43 * (Note that the version of WebIDLParser.js we use might sometimes be |
| 44 * out-of-date or forked.) | 44 * out-of-date or forked.) |
| 45 * | 45 * |
| 46 * The members and methods of the classes defined by this file are all at least | 46 * The members and methods of the classes defined by this file are all at least |
| 47 * briefly documented, hopefully. | 47 * briefly documented, hopefully. |
| 48 */ | 48 */ |
| 49 (function(){ | 49 (function(){ |
| 50 "use strict"; | 50 "use strict"; |
| 51 /// Helpers /// | 51 /// Helpers /// |
| 52 function constValue (cnt) { | 52 function constValue (cnt) |
| 53 //@{ |
| 54 { |
| 53 if (cnt.type === "null") return null; | 55 if (cnt.type === "null") return null; |
| 54 if (cnt.type === "NaN") return NaN; | 56 if (cnt.type === "NaN") return NaN; |
| 55 if (cnt.type === "Infinity") return cnt.negative ? -Infinity : Infinity; | 57 if (cnt.type === "Infinity") return cnt.negative ? -Infinity : Infinity; |
| 56 return cnt.value; | 58 return cnt.value; |
| 57 } | 59 } |
| 58 | 60 |
| 59 function minOverloadLength(overloads) { | 61 //@} |
| 62 function minOverloadLength(overloads) |
| 63 //@{ |
| 64 { |
| 60 if (!overloads.length) { | 65 if (!overloads.length) { |
| 61 return 0; | 66 return 0; |
| 62 } | 67 } |
| 63 | 68 |
| 64 return overloads.map(function(attr) { | 69 return overloads.map(function(attr) { |
| 65 return attr.arguments ? attr.arguments.filter(function(arg) { | 70 return attr.arguments ? attr.arguments.filter(function(arg) { |
| 66 return !arg.optional && !arg.variadic; | 71 return !arg.optional && !arg.variadic; |
| 67 }).length : 0; | 72 }).length : 0; |
| 68 }) | 73 }) |
| 69 .reduce(function(m, n) { return Math.min(m, n); }); | 74 .reduce(function(m, n) { return Math.min(m, n); }); |
| 70 } | 75 } |
| 71 | 76 |
| 72 function throwOrReject(a_test, operation, fn, obj, args, message, cb) { | 77 //@} |
| 78 function throwOrReject(a_test, operation, fn, obj, args, message, cb) |
| 79 //@{ |
| 80 { |
| 73 if (operation.idlType.generic !== "Promise") { | 81 if (operation.idlType.generic !== "Promise") { |
| 74 assert_throws(new TypeError(), function() { | 82 assert_throws(new TypeError(), function() { |
| 75 fn.apply(obj, args); | 83 fn.apply(obj, args); |
| 76 }, message); | 84 }, message); |
| 77 cb(); | 85 cb(); |
| 78 } else { | 86 } else { |
| 79 try { | 87 try { |
| 80 promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(c
b, cb); | 88 promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(c
b, cb); |
| 81 } catch (e){ | 89 } catch (e){ |
| 82 a_test.step(function() { | 90 a_test.step(function() { |
| 83 assert_unreached("Throws \"" + e + "\" instead of rejecting prom
ise"); | 91 assert_unreached("Throws \"" + e + "\" instead of rejecting prom
ise"); |
| 84 cb(); | 92 cb(); |
| 85 }); | 93 }); |
| 86 } | 94 } |
| 87 } | 95 } |
| 88 } | 96 } |
| 89 | 97 |
| 90 function awaitNCallbacks(n, cb, ctx) { | 98 //@} |
| 99 function awaitNCallbacks(n, cb, ctx) |
| 100 //@{ |
| 101 { |
| 91 var counter = 0; | 102 var counter = 0; |
| 92 return function() { | 103 return function() { |
| 93 counter++; | 104 counter++; |
| 94 if (counter >= n) { | 105 if (counter >= n) { |
| 95 cb(); | 106 cb(); |
| 96 } | 107 } |
| 97 }; | 108 }; |
| 98 } | 109 } |
| 99 | 110 |
| 100 var fround = (function(){ | 111 //@} |
| 112 var fround = |
| 113 //@{ |
| 114 (function(){ |
| 101 if (Math.fround) return Math.fround; | 115 if (Math.fround) return Math.fround; |
| 102 | 116 |
| 103 var arr = new Float32Array(1); | 117 var arr = new Float32Array(1); |
| 104 return function fround(n) { | 118 return function fround(n) { |
| 105 arr[0] = n; | 119 arr[0] = n; |
| 106 return arr[0]; | 120 return arr[0]; |
| 107 }; | 121 }; |
| 108 })(); | 122 })(); |
| 123 //@} |
| 109 | 124 |
| 110 /// IdlArray /// | 125 /// IdlArray /// |
| 111 // Entry point | 126 // Entry point |
| 112 self.IdlArray = function() | 127 self.IdlArray = function() |
| 113 //@{ | 128 //@{ |
| 114 { | 129 { |
| 115 /** | 130 /** |
| 116 * A map from strings to the corresponding named IdlObject, such as | 131 * A map from strings to the corresponding named IdlObject, such as |
| 117 * IdlInterface or IdlException. These are the things that test() will run | 132 * IdlInterface or IdlException. These are the things that test() will run |
| 118 * tests on. | 133 * tests on. |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 if (!value.length) | 456 if (!value.length) |
| 442 { | 457 { |
| 443 // Nothing we can do. | 458 // Nothing we can do. |
| 444 return; | 459 return; |
| 445 } | 460 } |
| 446 this.assert_type_is(value[0], type.idlType.idlType); | 461 this.assert_type_is(value[0], type.idlType.idlType); |
| 447 return; | 462 return; |
| 448 } | 463 } |
| 449 | 464 |
| 450 if (type.generic === "Promise") { | 465 if (type.generic === "Promise") { |
| 451 assert_own_property(value, "then", "Attribute with a Promise type has a
then property"); | 466 assert_true("then" in value, "Attribute with a Promise type has a then p
roperty"); |
| 452 // TODO: Ideally, we would check on project fulfillment | 467 // TODO: Ideally, we would check on project fulfillment |
| 453 // that we get the right type | 468 // that we get the right type |
| 454 // but that would require making the type check async | 469 // but that would require making the type check async |
| 455 return; | 470 return; |
| 456 } | 471 } |
| 457 | 472 |
| 458 type = type.idlType; | 473 type = type.idlType; |
| 459 | 474 |
| 460 switch(type) | 475 switch(type) |
| 461 { | 476 { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 * The name (as a string) of the dictionary type we inherit from, or null | 658 * The name (as a string) of the dictionary type we inherit from, or null |
| 644 * if there is none. | 659 * if there is none. |
| 645 */ | 660 */ |
| 646 this.base = obj.inheritance; | 661 this.base = obj.inheritance; |
| 647 } | 662 } |
| 648 | 663 |
| 649 //@} | 664 //@} |
| 650 IdlDictionary.prototype = Object.create(IdlObject.prototype); | 665 IdlDictionary.prototype = Object.create(IdlObject.prototype); |
| 651 | 666 |
| 652 /// IdlInterface /// | 667 /// IdlInterface /// |
| 653 function IdlInterface(obj, is_callback) { | 668 function IdlInterface(obj, is_callback) |
| 669 //@{ |
| 670 { |
| 654 /** | 671 /** |
| 655 * obj is an object produced by the WebIDLParser.js "interface" production. | 672 * obj is an object produced by the WebIDLParser.js "interface" production. |
| 656 */ | 673 */ |
| 657 | 674 |
| 658 /** Self-explanatory. */ | 675 /** Self-explanatory. */ |
| 659 this.name = obj.name; | 676 this.name = obj.name; |
| 660 | 677 |
| 661 /** A back-reference to our IdlArray. */ | 678 /** A back-reference to our IdlArray. */ |
| 662 this.array = obj.array; | 679 this.array = obj.array; |
| 663 | 680 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 680 } | 697 } |
| 681 | 698 |
| 682 /** | 699 /** |
| 683 * The name (as a string) of the type we inherit from, or null if there is | 700 * The name (as a string) of the type we inherit from, or null if there is |
| 684 * none. | 701 * none. |
| 685 */ | 702 */ |
| 686 this.base = obj.inheritance; | 703 this.base = obj.inheritance; |
| 687 | 704 |
| 688 this._is_callback = is_callback; | 705 this._is_callback = is_callback; |
| 689 } | 706 } |
| 707 //@} |
| 690 IdlInterface.prototype = Object.create(IdlObject.prototype); | 708 IdlInterface.prototype = Object.create(IdlObject.prototype); |
| 691 IdlInterface.prototype.is_callback = function() | 709 IdlInterface.prototype.is_callback = function() |
| 692 //@{ | 710 //@{ |
| 693 { | 711 { |
| 694 return this._is_callback; | 712 return this._is_callback; |
| 695 }; | 713 }; |
| 696 //@} | 714 //@} |
| 697 | 715 |
| 698 IdlInterface.prototype.has_constants = function() | 716 IdlInterface.prototype.has_constants = function() |
| 699 //@{ | 717 //@{ |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 "self does not have own property " + format_value(th
is.name)); | 794 "self does not have own property " + format_value(th
is.name)); |
| 777 var desc = Object.getOwnPropertyDescriptor(self, this.name); | 795 var desc = Object.getOwnPropertyDescriptor(self, this.name); |
| 778 assert_false("get" in desc, "self's property " + format_value(this.name)
+ " has getter"); | 796 assert_false("get" in desc, "self's property " + format_value(this.name)
+ " has getter"); |
| 779 assert_false("set" in desc, "self's property " + format_value(this.name)
+ " has setter"); | 797 assert_false("set" in desc, "self's property " + format_value(this.name)
+ " has setter"); |
| 780 assert_true(desc.writable, "self's property " + format_value(this.name)
+ " is not writable"); | 798 assert_true(desc.writable, "self's property " + format_value(this.name)
+ " is not writable"); |
| 781 assert_false(desc.enumerable, "self's property " + format_value(this.nam
e) + " is enumerable"); | 799 assert_false(desc.enumerable, "self's property " + format_value(this.nam
e) + " is enumerable"); |
| 782 assert_true(desc.configurable, "self's property " + format_value(this.na
me) + " is not configurable"); | 800 assert_true(desc.configurable, "self's property " + format_value(this.na
me) + " is not configurable"); |
| 783 | 801 |
| 784 if (this.is_callback()) { | 802 if (this.is_callback()) { |
| 785 // "The internal [[Prototype]] property of an interface object for | 803 // "The internal [[Prototype]] property of an interface object for |
| 786 // a callback interface MUST be the Object.prototype object." | 804 // a callback interface must be the Function.prototype object." |
| 787 assert_equals(Object.getPrototypeOf(self[this.name]), Object.prototy
pe, | 805 assert_equals(Object.getPrototypeOf(self[this.name]), Function.proto
type, |
| 788 "prototype of self's property " + format_value(this.na
me) + " is not Object.prototype"); | 806 "prototype of self's property " + format_value(this.na
me) + " is not Object.prototype"); |
| 789 | 807 |
| 790 return; | 808 return; |
| 791 } | 809 } |
| 792 | 810 |
| 793 // "The interface object for a given non-callback interface is a | 811 // "The interface object for a given non-callback interface is a |
| 794 // function object." | 812 // function object." |
| 795 // "If an object is defined to be a function object, then it has | 813 // "If an object is defined to be a function object, then it has |
| 796 // characteristics as follows:" | 814 // characteristics as follows:" |
| 797 | 815 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 assert_false(desc.writable, "property is writable"); | 1128 assert_false(desc.writable, "property is writable"); |
| 1111 assert_true(desc.enumerable, "property is not enumerable"); | 1129 assert_true(desc.enumerable, "property is not enumerable"); |
| 1112 assert_false(desc.configurable, "property is configurable"); | 1130 assert_false(desc.configurable, "property is configurable"); |
| 1113 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face prototype object"); | 1131 }.bind(this), this.name + " interface: constant " + member.name + " on inter
face prototype object"); |
| 1114 }; | 1132 }; |
| 1115 | 1133 |
| 1116 | 1134 |
| 1117 //@} | 1135 //@} |
| 1118 IdlInterface.prototype.test_member_attribute = function(member) | 1136 IdlInterface.prototype.test_member_attribute = function(member) |
| 1119 //@{ | 1137 //@{ |
| 1120 { | 1138 { |
| 1121 test(function() | 1139 var a_test = async_test(this.name + " interface: attribute " + member.name); |
| 1140 a_test.step(function() |
| 1122 { | 1141 { |
| 1123 if (this.is_callback() && !this.has_constants()) { | 1142 if (this.is_callback() && !this.has_constants()) { |
| 1143 a_test.done() |
| 1124 return; | 1144 return; |
| 1125 } | 1145 } |
| 1126 | 1146 |
| 1127 assert_own_property(self, this.name, | 1147 assert_own_property(self, this.name, |
| 1128 "self does not have own property " + format_value(th
is.name)); | 1148 "self does not have own property " + format_value(th
is.name)); |
| 1129 assert_own_property(self[this.name], "prototype", | 1149 assert_own_property(self[this.name], "prototype", |
| 1130 'interface "' + this.name + '" does not have own pro
perty "prototype"'); | 1150 'interface "' + this.name + '" does not have own pro
perty "prototype"'); |
| 1131 | 1151 |
| 1132 if (member["static"]) { | 1152 if (member["static"]) { |
| 1133 assert_own_property(self[this.name], member.name, | 1153 assert_own_property(self[this.name], member.name, |
| 1134 "The interface object must have a property " + | 1154 "The interface object must have a property " + |
| 1135 format_value(member.name)); | 1155 format_value(member.name)); |
| 1156 a_test.done(); |
| 1136 } else if (this.is_global()) { | 1157 } else if (this.is_global()) { |
| 1137 assert_own_property(self, member.name, | 1158 assert_own_property(self, member.name, |
| 1138 "The global object must have a property " + | 1159 "The global object must have a property " + |
| 1139 format_value(member.name)); | 1160 format_value(member.name)); |
| 1140 assert_false(member.name in self[this.name].prototype, | 1161 assert_false(member.name in self[this.name].prototype, |
| 1141 "The prototype object must not have a property " + | 1162 "The prototype object must not have a property " + |
| 1142 format_value(member.name)); | 1163 format_value(member.name)); |
| 1143 | 1164 |
| 1144 var getter = Object.getOwnPropertyDescriptor(self, member.name).get; | 1165 var getter = Object.getOwnPropertyDescriptor(self, member.name).get; |
| 1145 assert_equals(typeof(getter), "function", | 1166 assert_equals(typeof(getter), "function", |
| 1146 format_value(member.name) + " must have a getter"); | 1167 format_value(member.name) + " must have a getter"); |
| 1147 | 1168 |
| 1148 // Try/catch around the get here, since it can legitimately throw. | 1169 // Try/catch around the get here, since it can legitimately throw. |
| 1149 // If it does, we obviously can't check for equality with direct | 1170 // If it does, we obviously can't check for equality with direct |
| 1150 // invocation of the getter. | 1171 // invocation of the getter. |
| 1151 var gotValue; | 1172 var gotValue; |
| 1152 var propVal; | 1173 var propVal; |
| 1153 try { | 1174 try { |
| 1154 propVal = self[member.name]; | 1175 propVal = self[member.name]; |
| 1155 gotValue = true; | 1176 gotValue = true; |
| 1156 } catch (e) { | 1177 } catch (e) { |
| 1157 gotValue = false; | 1178 gotValue = false; |
| 1158 } | 1179 } |
| 1159 if (gotValue) { | 1180 if (gotValue) { |
| 1160 assert_equals(propVal, getter.call(undefined), | 1181 assert_equals(propVal, getter.call(undefined), |
| 1161 "Gets on a global should not require an explicit t
his"); | 1182 "Gets on a global should not require an explicit t
his"); |
| 1162 } | 1183 } |
| 1163 | 1184 |
| 1164 this.do_interface_attribute_asserts(self, member); | 1185 // do_interface_attribute_asserts must be the last thing we do, |
| 1186 // since it will call done() on a_test. |
| 1187 this.do_interface_attribute_asserts(self, member, a_test); |
| 1165 } else { | 1188 } else { |
| 1166 assert_true(member.name in self[this.name].prototype, | 1189 assert_true(member.name in self[this.name].prototype, |
| 1167 "The prototype object must have a property " + | 1190 "The prototype object must have a property " + |
| 1168 format_value(member.name)); | 1191 format_value(member.name)); |
| 1169 | 1192 |
| 1170 if (!member.has_extended_attribute("LenientThis")) { | 1193 if (!member.has_extended_attribute("LenientThis")) { |
| 1171 assert_throws(new TypeError(), function() { | 1194 if (member.idlType.generic !== "Promise") { |
| 1172 self[this.name].prototype[member.name]; | 1195 assert_throws(new TypeError(), function() { |
| 1173 }.bind(this), "getting property on prototype object must throw T
ypeError"); | 1196 self[this.name].prototype[member.name]; |
| 1197 }.bind(this), "getting property on prototype object must thr
ow TypeError"); |
| 1198 // do_interface_attribute_asserts must be the last thing we |
| 1199 // do, since it will call done() on a_test. |
| 1200 this.do_interface_attribute_asserts(self[this.name].prototyp
e, member, a_test); |
| 1201 } else { |
| 1202 promise_rejects(a_test, new TypeError(), |
| 1203 self[this.name].prototype[member.name]) |
| 1204 .then(function() { |
| 1205 // do_interface_attribute_asserts must be the last |
| 1206 // thing we do, since it will call done() on a_test. |
| 1207 this.do_interface_attribute_asserts(self[this.name].
prototype, |
| 1208 member, a_test); |
| 1209 }.bind(this)); |
| 1210 } |
| 1174 } else { | 1211 } else { |
| 1175 assert_equals(self[this.name].prototype[member.name], undefined, | 1212 assert_equals(self[this.name].prototype[member.name], undefined, |
| 1176 "getting property on prototype object must return
undefined"); | 1213 "getting property on prototype object must return
undefined"); |
| 1214 // do_interface_attribute_asserts must be the last thing we do, |
| 1215 // since it will call done() on a_test. |
| 1216 this.do_interface_attribute_asserts(self[this.name].prototype, mem
ber, a_test); |
| 1177 } | 1217 } |
| 1178 this.do_interface_attribute_asserts(self[this.name].prototype, membe
r); | 1218 |
| 1179 } | 1219 } |
| 1180 }.bind(this), this.name + " interface: attribute " + member.name); | 1220 }.bind(this)); |
| 1181 }; | 1221 }; |
| 1182 | 1222 |
| 1183 //@} | 1223 //@} |
| 1184 IdlInterface.prototype.test_member_operation = function(member) | 1224 IdlInterface.prototype.test_member_operation = function(member) |
| 1185 //@{ | 1225 //@{ |
| 1186 { | 1226 { |
| 1187 var a_test = async_test(this.name + " interface: operation " + member.name + | 1227 var a_test = async_test(this.name + " interface: operation " + member.name + |
| 1188 "(" + member.arguments.map( | 1228 "(" + member.arguments.map( |
| 1189 function(m) {return m.idlType.idlType; } ) | 1229 function(m) {return m.idlType.idlType; } ) |
| 1190 +")"); | 1230 +")"); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 // TODO: Test a platform object that implements some other | 1349 // TODO: Test a platform object that implements some other |
| 1310 // interface. (Have to be sure to get inheritance right.) | 1350 // interface. (Have to be sure to get inheritance right.) |
| 1311 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, | 1351 throwOrReject(a_test, member, memberHolderObject[member.name], {}, args, |
| 1312 "calling operation with this = {} didn't throw TypeError",
cb); | 1352 "calling operation with this = {} didn't throw TypeError",
cb); |
| 1313 } else { | 1353 } else { |
| 1314 done(); | 1354 done(); |
| 1315 } | 1355 } |
| 1316 } | 1356 } |
| 1317 | 1357 |
| 1318 //@} | 1358 //@} |
| 1359 IdlInterface.prototype.add_iterable_members = function(member) |
| 1360 //@{ |
| 1361 { |
| 1362 this.members.push({type: "operation", name: "entries", idlType: "iterator",
arguments: []}); |
| 1363 this.members.push({type: "operation", name: "keys", idlType: "iterator", arg
uments: []}); |
| 1364 this.members.push({type: "operation", name: "values", idlType: "iterator", a
rguments: []}); |
| 1365 this.members.push({type: "operation", name: "forEach", idlType: "void", argu
ments: |
| 1366 [{ name: "callback", idlType: {idlType: "function"}}, |
| 1367 { name: "thisValue", idlType: {idlType: "any"}, optional: true}]}); |
| 1368 }; |
| 1369 |
| 1370 //@} |
| 1371 IdlInterface.prototype.test_member_iterable = function(member) |
| 1372 //@{ |
| 1373 { |
| 1374 var interfaceName = this.name; |
| 1375 var isPairIterator = member.idlType instanceof Array; |
| 1376 test(function() |
| 1377 { |
| 1378 var descriptor = Object.getOwnPropertyDescriptor(self[interfaceName].pro
totype, Symbol.iterator); |
| 1379 assert_true(descriptor.writable, "property is not writable"); |
| 1380 assert_true(descriptor.configurable, "property is not configurable"); |
| 1381 assert_false(descriptor.enumerable, "property is enumerable"); |
| 1382 assert_equals(self[interfaceName].prototype[Symbol.iterator].name, isPai
rIterator ? "entries" : "values", "@@iterator function does not have the right n
ame"); |
| 1383 }, "Testing Symbol.iterator property of iterable interface " + interfaceName
); |
| 1384 |
| 1385 if (isPairIterator) { |
| 1386 test(function() { |
| 1387 assert_equals(self[interfaceName].prototype["entries"], self[interfa
ceName].prototype[Symbol.iterator], "entries method is not the same as @@iterato
r"); |
| 1388 }, "Testing pair iterable interface " + interfaceName); |
| 1389 } else { |
| 1390 test(function() { |
| 1391 ["entries", "keys", "values", "forEach", Symbol.Iterator].forEach(fu
nction(property) { |
| 1392 assert_equals(self[interfaceName].prototype[property], Array.pro
totype[property], property + " function is not the same as Array one"); |
| 1393 }); |
| 1394 }, "Testing value iterable interface " + interfaceName); |
| 1395 } |
| 1396 }; |
| 1397 |
| 1398 //@} |
| 1319 IdlInterface.prototype.test_member_stringifier = function(member) | 1399 IdlInterface.prototype.test_member_stringifier = function(member) |
| 1320 //@{ | 1400 //@{ |
| 1321 { | 1401 { |
| 1322 test(function() | 1402 test(function() |
| 1323 { | 1403 { |
| 1324 if (this.is_callback() && !this.has_constants()) { | 1404 if (this.is_callback() && !this.has_constants()) { |
| 1325 return; | 1405 return; |
| 1326 } | 1406 } |
| 1327 | 1407 |
| 1328 assert_own_property(self, this.name, | 1408 assert_own_property(self, this.name, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 }.bind(this), this.name + " interface: stringifier"); | 1459 }.bind(this), this.name + " interface: stringifier"); |
| 1380 }; | 1460 }; |
| 1381 | 1461 |
| 1382 //@} | 1462 //@} |
| 1383 IdlInterface.prototype.test_members = function() | 1463 IdlInterface.prototype.test_members = function() |
| 1384 //@{ | 1464 //@{ |
| 1385 { | 1465 { |
| 1386 for (var i = 0; i < this.members.length; i++) | 1466 for (var i = 0; i < this.members.length; i++) |
| 1387 { | 1467 { |
| 1388 var member = this.members[i]; | 1468 var member = this.members[i]; |
| 1469 switch (member.type) { |
| 1470 case "iterable": |
| 1471 this.add_iterable_members(member); |
| 1472 break; |
| 1473 // TODO: add setlike and maplike handling. |
| 1474 default: |
| 1475 break; |
| 1476 } |
| 1477 } |
| 1478 |
| 1479 for (var i = 0; i < this.members.length; i++) |
| 1480 { |
| 1481 var member = this.members[i]; |
| 1389 if (member.untested) { | 1482 if (member.untested) { |
| 1390 continue; | 1483 continue; |
| 1391 } | 1484 } |
| 1392 | 1485 |
| 1393 switch (member.type) { | 1486 switch (member.type) { |
| 1394 case "const": | 1487 case "const": |
| 1395 this.test_member_const(member); | 1488 this.test_member_const(member); |
| 1396 break; | 1489 break; |
| 1397 | 1490 |
| 1398 case "attribute": | 1491 case "attribute": |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1415 if (member.name) { | 1508 if (member.name) { |
| 1416 if (!member.isUnforgeable) | 1509 if (!member.isUnforgeable) |
| 1417 { | 1510 { |
| 1418 this.test_member_operation(member); | 1511 this.test_member_operation(member); |
| 1419 } | 1512 } |
| 1420 } else if (member.stringifier) { | 1513 } else if (member.stringifier) { |
| 1421 this.test_member_stringifier(member); | 1514 this.test_member_stringifier(member); |
| 1422 } | 1515 } |
| 1423 break; | 1516 break; |
| 1424 | 1517 |
| 1518 case "iterable": |
| 1519 this.test_member_iterable(member); |
| 1520 break; |
| 1425 default: | 1521 default: |
| 1426 // TODO: check more member types. | 1522 // TODO: check more member types. |
| 1427 break; | 1523 break; |
| 1428 } | 1524 } |
| 1429 } | 1525 } |
| 1430 }; | 1526 }; |
| 1431 | 1527 |
| 1432 //@} | 1528 //@} |
| 1433 IdlInterface.prototype.test_object = function(desc) | 1529 IdlInterface.prototype.test_object = function(desc) |
| 1434 //@{ | 1530 //@{ |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 //@{ | 1611 //@{ |
| 1516 { | 1612 { |
| 1517 // TODO: Indexed and named properties, more checks on interface members | 1613 // TODO: Indexed and named properties, more checks on interface members |
| 1518 this.already_tested = true; | 1614 this.already_tested = true; |
| 1519 | 1615 |
| 1520 for (var i = 0; i < this.members.length; i++) | 1616 for (var i = 0; i < this.members.length; i++) |
| 1521 { | 1617 { |
| 1522 var member = this.members[i]; | 1618 var member = this.members[i]; |
| 1523 if (member.type == "attribute" && member.isUnforgeable) | 1619 if (member.type == "attribute" && member.isUnforgeable) |
| 1524 { | 1620 { |
| 1525 test(function() | 1621 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); |
| 1526 { | 1622 a_test.step(function() { |
| 1527 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1623 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
| 1528 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1624 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
| 1529 this.do_interface_attribute_asserts(obj, member); | 1625 // Call do_interface_attribute_asserts last, since it will call
a_test.done() |
| 1530 }.bind(this), this.name + " interface: " + desc + ' must have own pr
operty "' + member.name + '"'); | 1626 this.do_interface_attribute_asserts(obj, member, a_test); |
| 1627 }.bind(this)); |
| 1531 } | 1628 } |
| 1532 else if (member.type == "operation" && | 1629 else if (member.type == "operation" && |
| 1533 member.name && | 1630 member.name && |
| 1534 member.isUnforgeable) | 1631 member.isUnforgeable) |
| 1535 { | 1632 { |
| 1536 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); | 1633 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); |
| 1537 a_test.step(function() | 1634 a_test.step(function() |
| 1538 { | 1635 { |
| 1539 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1636 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
| 1540 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1637 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1639 return true; | 1736 return true; |
| 1640 } | 1737 } |
| 1641 if (this.base && | 1738 if (this.base && |
| 1642 this.array.members[this.base].has_stringifier()) { | 1739 this.array.members[this.base].has_stringifier()) { |
| 1643 return true; | 1740 return true; |
| 1644 } | 1741 } |
| 1645 return false; | 1742 return false; |
| 1646 }; | 1743 }; |
| 1647 | 1744 |
| 1648 //@} | 1745 //@} |
| 1649 IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member) | 1746 IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member, a_
test) |
| 1650 //@{ | 1747 //@{ |
| 1651 { | 1748 { |
| 1652 // This function tests WebIDL as of 2015-01-27. | 1749 // This function tests WebIDL as of 2015-01-27. |
| 1653 // TODO: Consider [Exposed]. | 1750 // TODO: Consider [Exposed]. |
| 1654 | 1751 |
| 1655 // This is called by test_member_attribute() with the prototype as obj if | 1752 // This is called by test_member_attribute() with the prototype as obj if |
| 1656 // it is not a global, and the global otherwise, and by test_interface_of() | 1753 // it is not a global, and the global otherwise, and by test_interface_of() |
| 1657 // with the object as obj. | 1754 // with the object as obj. |
| 1658 | 1755 |
| 1756 var pendingPromises = []; |
| 1757 |
| 1659 // "For each exposed attribute of the interface, whether it was declared on | 1758 // "For each exposed attribute of the interface, whether it was declared on |
| 1660 // the interface itself or one of its consequential interfaces, there MUST | 1759 // the interface itself or one of its consequential interfaces, there MUST |
| 1661 // exist a corresponding property. The characteristics of this property are | 1760 // exist a corresponding property. The characteristics of this property are |
| 1662 // as follows:" | 1761 // as follows:" |
| 1663 | 1762 |
| 1664 // "The name of the property is the identifier of the attribute." | 1763 // "The name of the property is the identifier of the attribute." |
| 1665 assert_own_property(obj, member.name); | 1764 assert_own_property(obj, member.name); |
| 1666 | 1765 |
| 1667 // "The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]: | 1766 // "The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]: |
| 1668 // true, [[Configurable]]: configurable }, where: | 1767 // true, [[Configurable]]: configurable }, where: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1688 // is as follows:" | 1787 // is as follows:" |
| 1689 assert_equals(typeof desc.get, "function", "getter must be Function"); | 1788 assert_equals(typeof desc.get, "function", "getter must be Function"); |
| 1690 | 1789 |
| 1691 // "If the attribute is a regular attribute, then:" | 1790 // "If the attribute is a regular attribute, then:" |
| 1692 if (!member["static"]) { | 1791 if (!member["static"]) { |
| 1693 // "If O is not a platform object that implements I, then: | 1792 // "If O is not a platform object that implements I, then: |
| 1694 // "If the attribute was specified with the [LenientThis] extended | 1793 // "If the attribute was specified with the [LenientThis] extended |
| 1695 // attribute, then return undefined. | 1794 // attribute, then return undefined. |
| 1696 // "Otherwise, throw a TypeError." | 1795 // "Otherwise, throw a TypeError." |
| 1697 if (!member.has_extended_attribute("LenientThis")) { | 1796 if (!member.has_extended_attribute("LenientThis")) { |
| 1698 assert_throws(new TypeError(), function() { | 1797 if (member.idlType.generic !== "Promise") { |
| 1699 desc.get.call({}); | 1798 assert_throws(new TypeError(), function() { |
| 1700 }.bind(this), "calling getter on wrong object type must throw TypeEr
ror"); | 1799 desc.get.call({}); |
| 1800 }.bind(this), "calling getter on wrong object type must throw Ty
peError"); |
| 1801 } else { |
| 1802 pendingPromises.push( |
| 1803 promise_rejects(a_test, new TypeError(), desc.get.call({}), |
| 1804 "calling getter on wrong object type must re
ject the return promise with TypeError")); |
| 1805 } |
| 1701 } else { | 1806 } else { |
| 1702 assert_equals(desc.get.call({}), undefined, | 1807 assert_equals(desc.get.call({}), undefined, |
| 1703 "calling getter on wrong object type must return undef
ined"); | 1808 "calling getter on wrong object type must return undef
ined"); |
| 1704 } | 1809 } |
| 1705 } | 1810 } |
| 1706 | 1811 |
| 1707 // "The value of the Function object’s “length” property is the Number | 1812 // "The value of the Function object’s “length” property is the Number |
| 1708 // value 0." | 1813 // value 0." |
| 1709 assert_equals(desc.get.length, 0, "getter length must be 0"); | 1814 assert_equals(desc.get.length, 0, "getter length must be 0"); |
| 1710 | 1815 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1741 } else { | 1846 } else { |
| 1742 assert_equals(desc.set.call({}), undefined, | 1847 assert_equals(desc.set.call({}), undefined, |
| 1743 "calling setter on wrong object type must return u
ndefined"); | 1848 "calling setter on wrong object type must return u
ndefined"); |
| 1744 } | 1849 } |
| 1745 } | 1850 } |
| 1746 | 1851 |
| 1747 // "The value of the Function object’s “length” property is the Number | 1852 // "The value of the Function object’s “length” property is the Number |
| 1748 // value 1." | 1853 // value 1." |
| 1749 assert_equals(desc.set.length, 1, "setter length must be 1"); | 1854 assert_equals(desc.set.length, 1, "setter length must be 1"); |
| 1750 } | 1855 } |
| 1856 |
| 1857 Promise.all(pendingPromises).then(a_test.done.bind(a_test)); |
| 1751 } | 1858 } |
| 1752 //@} | 1859 //@} |
| 1753 | 1860 |
| 1754 /// IdlInterfaceMember /// | 1861 /// IdlInterfaceMember /// |
| 1755 function IdlInterfaceMember(obj) | 1862 function IdlInterfaceMember(obj) |
| 1756 //@{ | 1863 //@{ |
| 1757 { | 1864 { |
| 1758 /** | 1865 /** |
| 1759 * obj is an object produced by the WebIDLParser.js "ifMember" production. | 1866 * obj is an object produced by the WebIDLParser.js "ifMember" production. |
| 1760 * We just forward all properties to this object without modification, | 1867 * We just forward all properties to this object without modification, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 /** An array of values produced by the "typedef" production. */ | 1959 /** An array of values produced by the "typedef" production. */ |
| 1853 this.values = obj.values; | 1960 this.values = obj.values; |
| 1854 | 1961 |
| 1855 } | 1962 } |
| 1856 //@} | 1963 //@} |
| 1857 | 1964 |
| 1858 IdlTypedef.prototype = Object.create(IdlObject.prototype); | 1965 IdlTypedef.prototype = Object.create(IdlObject.prototype); |
| 1859 | 1966 |
| 1860 }()); | 1967 }()); |
| 1861 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: | 1968 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: |
| OLD | NEW |