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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 { | 315 { |
316 ret = ret.concat(this.recursively_get_implements(ret[i])); | 316 ret = ret.concat(this.recursively_get_implements(ret[i])); |
317 if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) | 317 if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i])) |
318 { | 318 { |
319 throw "Circular implements statements involving " + ret[i]; | 319 throw "Circular implements statements involving " + ret[i]; |
320 } | 320 } |
321 } | 321 } |
322 return ret; | 322 return ret; |
323 }; | 323 }; |
324 | 324 |
| 325 function exposure_set(object, default_set) { |
| 326 var exposed = object.extAttrs.filter(function(a) { return a.name == "Exposed
" }); |
| 327 if (exposed.length > 1 || exposed.length < 0) { |
| 328 throw "Unexpected Exposed extended attributes on " + memberName + ": " +
exposed; |
| 329 } |
| 330 |
| 331 if (exposed.length === 0) { |
| 332 return default_set; |
| 333 } |
| 334 |
| 335 var set = exposed[0].rhs.value; |
| 336 // Could be a list or a string. |
| 337 if (typeof set == "string") { |
| 338 set = [ set ]; |
| 339 } |
| 340 return set; |
| 341 } |
| 342 |
325 function exposed_in(globals) { | 343 function exposed_in(globals) { |
326 if ('document' in self) { | 344 if ('document' in self) { |
327 return globals.indexOf("Window") >= 0; | 345 return globals.indexOf("Window") >= 0; |
328 } | 346 } |
329 if ('DedicatedWorkerGlobalScope' in self && | 347 if ('DedicatedWorkerGlobalScope' in self && |
330 self instanceof DedicatedWorkerGlobalScope) { | 348 self instanceof DedicatedWorkerGlobalScope) { |
331 return globals.indexOf("Worker") >= 0 || | 349 return globals.indexOf("Worker") >= 0 || |
332 globals.indexOf("DedicatedWorker") >= 0; | 350 globals.indexOf("DedicatedWorker") >= 0; |
333 } | 351 } |
334 if ('SharedWorkerGlobalScope' in self && | 352 if ('SharedWorkerGlobalScope' in self && |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 }.bind(this)); | 407 }.bind(this)); |
390 } | 408 } |
391 this["implements"] = {}; | 409 this["implements"] = {}; |
392 | 410 |
393 Object.getOwnPropertyNames(this.members).forEach(function(memberName) { | 411 Object.getOwnPropertyNames(this.members).forEach(function(memberName) { |
394 var member = this.members[memberName]; | 412 var member = this.members[memberName]; |
395 if (!(member instanceof IdlInterface)) { | 413 if (!(member instanceof IdlInterface)) { |
396 return; | 414 return; |
397 } | 415 } |
398 | 416 |
399 var exposed = member.extAttrs.filter(function(a) { return a.name == "Exp
osed" }); | 417 var globals = exposure_set(member, ["Window"]); |
400 if (exposed.length > 1) { | |
401 throw "Unexpected Exposed extended attributes on " + memberName + ":
" + exposed; | |
402 } | |
403 | |
404 var globals = exposed.length === 1 | |
405 ? exposed[0].rhs.value | |
406 : ["Window"]; | |
407 member.exposed = exposed_in(globals); | 418 member.exposed = exposed_in(globals); |
| 419 member.exposureSet = globals; |
408 }.bind(this)); | 420 }.bind(this)); |
409 | 421 |
410 // Now run test() on every member, and test_object() for every object. | 422 // Now run test() on every member, and test_object() for every object. |
411 for (var name in this.members) | 423 for (var name in this.members) |
412 { | 424 { |
413 this.members[name].test(); | 425 this.members[name].test(); |
414 if (name in this.objects) | 426 if (name in this.objects) |
415 { | 427 { |
416 this.objects[name].forEach(function(str) | 428 this.objects[name].forEach(function(str) |
417 { | 429 { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 463 } |
452 | 464 |
453 if (type.sequence) | 465 if (type.sequence) |
454 { | 466 { |
455 assert_true(Array.isArray(value), "is not array"); | 467 assert_true(Array.isArray(value), "is not array"); |
456 if (!value.length) | 468 if (!value.length) |
457 { | 469 { |
458 // Nothing we can do. | 470 // Nothing we can do. |
459 return; | 471 return; |
460 } | 472 } |
461 this.assert_type_is(value[0], type.idlType.idlType); | 473 this.assert_type_is(value[0], type.idlType); |
462 return; | 474 return; |
463 } | 475 } |
464 | 476 |
465 if (type.generic === "Promise") { | 477 if (type.generic === "Promise") { |
466 assert_true("then" in value, "Attribute with a Promise type has a then p
roperty"); | 478 assert_true("then" in value, "Attribute with a Promise type has a then p
roperty"); |
467 // TODO: Ideally, we would check on project fulfillment | 479 // TODO: Ideally, we would check on project fulfillment |
468 // that we get the right type | 480 // that we get the right type |
469 // but that would require making the type check async | 481 // but that would require making the type check async |
470 return; | 482 return; |
471 } | 483 } |
472 | 484 |
| 485 if (type.generic === "FrozenArray") { |
| 486 assert_true(Array.isArray(value), "Value should be array"); |
| 487 assert_true(Object.isFrozen(value), "Value should be frozen"); |
| 488 if (!value.length) |
| 489 { |
| 490 // Nothing we can do. |
| 491 return; |
| 492 } |
| 493 this.assert_type_is(value[0], type.idlType); |
| 494 return; |
| 495 } |
| 496 |
473 type = type.idlType; | 497 type = type.idlType; |
474 | 498 |
475 switch(type) | 499 switch(type) |
476 { | 500 { |
477 case "void": | 501 case "void": |
478 assert_equals(value, undefined); | 502 assert_equals(value, undefined); |
479 return; | 503 return; |
480 | 504 |
481 case "boolean": | 505 case "boolean": |
482 assert_equals(typeof value, "boolean"); | 506 assert_equals(typeof value, "boolean"); |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 // [NoInterfaceObject].) | 992 // [NoInterfaceObject].) |
969 // TODO: Aryeh thinks there's at least other place in this file where | 993 // TODO: Aryeh thinks there's at least other place in this file where |
970 // we try to figure out if an interface prototype object is | 994 // we try to figure out if an interface prototype object is |
971 // correct. Consolidate that code. | 995 // correct. Consolidate that code. |
972 | 996 |
973 // "The interface prototype object for a given interface A must have an | 997 // "The interface prototype object for a given interface A must have an |
974 // internal [[Prototype]] property whose value is returned from the | 998 // internal [[Prototype]] property whose value is returned from the |
975 // following steps: | 999 // following steps: |
976 // "If A is declared with the [Global] or [PrimaryGlobal] extended | 1000 // "If A is declared with the [Global] or [PrimaryGlobal] extended |
977 // attribute, and A supports named properties, then return the named | 1001 // attribute, and A supports named properties, then return the named |
978 // properties object for A, as defined in section 4.5.5 below. | 1002 // properties object for A, as defined in ยง3.6.4 Named properties |
| 1003 // object. |
979 // "Otherwise, if A is declared to inherit from another interface, then | 1004 // "Otherwise, if A is declared to inherit from another interface, then |
980 // return the interface prototype object for the inherited interface. | 1005 // return the interface prototype object for the inherited interface. |
981 // "Otherwise, if A is declared with the [ArrayClass] extended | 1006 // "Otherwise, if A is declared with the [LegacyArrayClass] extended |
982 // attribute, then return %ArrayPrototype% ([ECMA-262], section | 1007 // attribute, then return %ArrayPrototype%. |
983 // 6.1.7.4). | 1008 // "Otherwise, return %ObjectPrototype%. |
984 // "Otherwise, return %ObjectPrototype% ([ECMA-262], section 6.1.7.4). | |
985 // ([ECMA-262], section 15.2.4). | |
986 if (this.name === "Window") { | 1009 if (this.name === "Window") { |
987 assert_class_string(Object.getPrototypeOf(self[this.name].prototype)
, | 1010 assert_class_string(Object.getPrototypeOf(self[this.name].prototype)
, |
988 'WindowProperties', | 1011 'WindowProperties', |
989 'Class name for prototype of Window' + | 1012 'Class name for prototype of Window' + |
990 '.prototype is not "WindowProperties"'); | 1013 '.prototype is not "WindowProperties"'); |
991 } else { | 1014 } else { |
992 var inherit_interface, inherit_interface_has_interface_object; | 1015 var inherit_interface, inherit_interface_has_interface_object; |
993 if (this.base) { | 1016 if (this.base) { |
994 inherit_interface = this.base; | 1017 inherit_interface = this.base; |
995 inherit_interface_has_interface_object = | 1018 inherit_interface_has_interface_object = |
996 !this.array | 1019 !this.array |
997 .members[inherit_interface] | 1020 .members[inherit_interface] |
998 .has_extended_attribute("NoInterfaceObject"); | 1021 .has_extended_attribute("NoInterfaceObject"); |
999 } else if (this.has_extended_attribute('ArrayClass')) { | 1022 } else if (this.has_extended_attribute('LegacyArrayClass')) { |
1000 inherit_interface = 'Array'; | 1023 inherit_interface = 'Array'; |
1001 inherit_interface_has_interface_object = true; | 1024 inherit_interface_has_interface_object = true; |
1002 } else { | 1025 } else { |
1003 inherit_interface = 'Object'; | 1026 inherit_interface = 'Object'; |
1004 inherit_interface_has_interface_object = true; | 1027 inherit_interface_has_interface_object = true; |
1005 } | 1028 } |
1006 if (inherit_interface_has_interface_object) { | 1029 if (inherit_interface_has_interface_object) { |
1007 assert_own_property(self, inherit_interface, | 1030 assert_own_property(self, inherit_interface, |
1008 'should inherit from ' + inherit_interface +
', but self has no such property'); | 1031 'should inherit from ' + inherit_interface +
', but self has no such property'); |
1009 assert_own_property(self[inherit_interface], 'prototype', | 1032 assert_own_property(self[inherit_interface], 'prototype', |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 "calling operation with this = {} didn't throw TypeError",
cb); | 1375 "calling operation with this = {} didn't throw TypeError",
cb); |
1353 } else { | 1376 } else { |
1354 done(); | 1377 done(); |
1355 } | 1378 } |
1356 } | 1379 } |
1357 | 1380 |
1358 //@} | 1381 //@} |
1359 IdlInterface.prototype.add_iterable_members = function(member) | 1382 IdlInterface.prototype.add_iterable_members = function(member) |
1360 //@{ | 1383 //@{ |
1361 { | 1384 { |
1362 this.members.push({type: "operation", name: "entries", idlType: "iterator",
arguments: []}); | 1385 this.members.push(new IdlInterfaceMember( |
1363 this.members.push({type: "operation", name: "keys", idlType: "iterator", arg
uments: []}); | 1386 { type: "operation", name: "entries", idlType: "iterator", arguments: []
})); |
1364 this.members.push({type: "operation", name: "values", idlType: "iterator", a
rguments: []}); | 1387 this.members.push(new IdlInterfaceMember( |
1365 this.members.push({type: "operation", name: "forEach", idlType: "void", argu
ments: | 1388 { type: "operation", name: "keys", idlType: "iterator", arguments: []}))
; |
1366 [{ name: "callback", idlType: {idlType: "function"}}, | 1389 this.members.push(new IdlInterfaceMember( |
1367 { name: "thisValue", idlType: {idlType: "any"}, optional: true}]}); | 1390 { type: "operation", name: "values", idlType: "iterator", arguments: []}
)); |
| 1391 this.members.push(new IdlInterfaceMember( |
| 1392 { type: "operation", name: "forEach", idlType: "void", |
| 1393 arguments: |
| 1394 [{ name: "callback", idlType: {idlType: "function"}}, |
| 1395 { name: "thisValue", idlType: {idlType: "any"}, optional: true}]})); |
1368 }; | 1396 }; |
1369 | 1397 |
1370 //@} | 1398 //@} |
1371 IdlInterface.prototype.test_member_iterable = function(member) | 1399 IdlInterface.prototype.test_member_iterable = function(member) |
1372 //@{ | 1400 //@{ |
1373 { | 1401 { |
1374 var interfaceName = this.name; | 1402 var interfaceName = this.name; |
1375 var isPairIterator = member.idlType instanceof Array; | 1403 var isPairIterator = member.idlType instanceof Array; |
1376 test(function() | 1404 test(function() |
1377 { | 1405 { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 } | 1504 } |
1477 } | 1505 } |
1478 | 1506 |
1479 for (var i = 0; i < this.members.length; i++) | 1507 for (var i = 0; i < this.members.length; i++) |
1480 { | 1508 { |
1481 var member = this.members[i]; | 1509 var member = this.members[i]; |
1482 if (member.untested) { | 1510 if (member.untested) { |
1483 continue; | 1511 continue; |
1484 } | 1512 } |
1485 | 1513 |
| 1514 if (!exposed_in(exposure_set(member, this.exposureSet))) { |
| 1515 test(function() { |
| 1516 // It's not exposed, so we shouldn't find it anywhere. |
| 1517 assert_false(member.name in self[this.name], |
| 1518 "The interface object must not have a property " + |
| 1519 format_value(member.name)); |
| 1520 assert_false(member.name in self[this.name].prototype, |
| 1521 "The prototype object must not have a property " + |
| 1522 format_value(member.name)); |
| 1523 }.bind(this), this.name + " interface: member " + member.name); |
| 1524 continue; |
| 1525 } |
| 1526 |
1486 switch (member.type) { | 1527 switch (member.type) { |
1487 case "const": | 1528 case "const": |
1488 this.test_member_const(member); | 1529 this.test_member_const(member); |
1489 break; | 1530 break; |
1490 | 1531 |
1491 case "attribute": | 1532 case "attribute": |
1492 // For unforgeable attributes, we do the checks in | 1533 // For unforgeable attributes, we do the checks in |
1493 // test_interface_of instead. | 1534 // test_interface_of instead. |
1494 if (!member.isUnforgeable) | 1535 if (!member.isUnforgeable) |
1495 { | 1536 { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 //@} | 1650 //@} |
1610 IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect
ed_typeof) | 1651 IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect
ed_typeof) |
1611 //@{ | 1652 //@{ |
1612 { | 1653 { |
1613 // TODO: Indexed and named properties, more checks on interface members | 1654 // TODO: Indexed and named properties, more checks on interface members |
1614 this.already_tested = true; | 1655 this.already_tested = true; |
1615 | 1656 |
1616 for (var i = 0; i < this.members.length; i++) | 1657 for (var i = 0; i < this.members.length; i++) |
1617 { | 1658 { |
1618 var member = this.members[i]; | 1659 var member = this.members[i]; |
| 1660 if (!exposed_in(exposure_set(member, this.exposureSet))) { |
| 1661 test(function() { |
| 1662 assert_false(member.name in obj); |
| 1663 }.bind(this), this.name + "interface: " + desc + 'must not have prop
erty "' + member.name + '"'); |
| 1664 continue; |
| 1665 } |
1619 if (member.type == "attribute" && member.isUnforgeable) | 1666 if (member.type == "attribute" && member.isUnforgeable) |
1620 { | 1667 { |
1621 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); | 1668 var a_test = async_test(this.name + " interface: " + desc + ' must h
ave own property "' + member.name + '"'); |
1622 a_test.step(function() { | 1669 a_test.step(function() { |
1623 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); | 1670 assert_equals(exception, null, "Unexpected exception when evalua
ting object"); |
1624 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); | 1671 assert_equals(typeof obj, expected_typeof, "wrong typeof object"
); |
1625 // Call do_interface_attribute_asserts last, since it will call
a_test.done() | 1672 // Call do_interface_attribute_asserts last, since it will call
a_test.done() |
1626 this.do_interface_attribute_asserts(obj, member, a_test); | 1673 this.do_interface_attribute_asserts(obj, member, a_test); |
1627 }.bind(this)); | 1674 }.bind(this)); |
1628 } | 1675 } |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1959 /** An array of values produced by the "typedef" production. */ | 2006 /** An array of values produced by the "typedef" production. */ |
1960 this.values = obj.values; | 2007 this.values = obj.values; |
1961 | 2008 |
1962 } | 2009 } |
1963 //@} | 2010 //@} |
1964 | 2011 |
1965 IdlTypedef.prototype = Object.create(IdlObject.prototype); | 2012 IdlTypedef.prototype = Object.create(IdlObject.prototype); |
1966 | 2013 |
1967 }()); | 2014 }()); |
1968 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: | 2015 // vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker: |
OLD | NEW |