Bug 763169 - Part a: Update resources from upstream and update test names in the expected failures for Selection tests; r=jhammel

This commit is contained in:
Ms2ger 2012-06-17 09:51:22 +02:00
parent 8c778eb7cd
commit b9ba89999a
5 changed files with 1332 additions and 219 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,10 @@
"Selection interface: existence and properties of interface object":true,
"Selection interface: existence and properties of interface prototype object":true,
"Selection interface: existence and properties of interface prototype object's \"constructor\" property":true,
"Selection interface: calling collapse() on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling extend() on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling selectAllChildren() on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling getRangeAt() on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling addRange() on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling removeRange() on getSelection() with too few arguments must throw TypeError":true
"Selection interface: calling collapse(Node,unsigned long) on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling extend(Node,unsigned long) on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling selectAllChildren(Node) on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling getRangeAt(unsigned long) on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling addRange(Range) on getSelection() with too few arguments must throw TypeError":true,
"Selection interface: calling removeRange(Range) on getSelection() with too few arguments must throw TypeError":true
}

View File

@ -135,6 +135,8 @@ policies and contribution forms [3].
*/
"use strict";
(function(){
var interfaces = {};
/// IdlArray ///
//Entry point
window.IdlArray = function()
@ -223,6 +225,10 @@ IdlArray.prototype.internal_add_idls = function(parsed_idls)
//TODO
break;
case "enum":
//TODO
break;
default:
throw parsed_idl.name + ": " + parsed_idl.type + " not yet supported";
}
@ -569,12 +575,10 @@ IdlException.prototype.test_self = function()
//ECMA-262 section 15.3.5.3, unless otherwise specified."
//TODO
//"Its [[Class]] internal property is “Function”."
//String() and {}.toString.call() should be equivalent, since nothing
//defines a stringifier.
//String() returns something implementation-dependent, because it calls
//Function#toString.
assert_equals({}.toString.call(window[this.name]), "[object Function]",
"{}.toString.call(" + this.name + ")");
assert_equals(String(window[this.name]), "[object Function]",
"String(" + this.name + ")");
//TODO: Test 4.9.1.1. Exception interface object [[Call]] method (which
//does not match browsers: //http://www.w3.org/Bugs/Public/show_bug.cgi?id=14885)
@ -862,6 +866,7 @@ function IdlInterface(obj)
this.extAttrs = obj.extAttrs ? obj.extAttrs : [];
this.members = obj.members ? obj.members.map(function(m){return new IdlInterfaceMember(m)}) : [];
this.inheritance = obj.inheritance ? obj.inheritance : [];
interfaces[this.name] = this;
}
//@}
@ -926,12 +931,10 @@ IdlInterface.prototype.test_self = function()
//ECMA-262 section 15.3.5.3, unless otherwise specified."
//TODO
//"Its [[Class]] internal property is “Function”."
//String() and {}.toString.call() should be equivalent, since nothing
//defines a stringifier.
//String() returns something implementation-dependent, because it calls
//Function#toString.
assert_equals({}.toString.call(window[this.name]), "[object Function]",
"{}.toString.call(" + this.name + ")");
assert_equals(String(window[this.name]), "[object Function]",
"String(" + this.name + ")");
if (!this.has_extended_attribute("Constructor"))
{
@ -970,7 +973,7 @@ IdlInterface.prototype.test_self = function()
//support multiple operations with the same identifier).
var expected_length = this.extAttrs
.filter(function(attr) { return attr.name == "Constructor" })
.map(function(attr) { return attr.arguments.length })
.map(function(attr) { return attr.arguments ? attr.arguments.length : 0 })
.reduce(function(m, n) { return Math.max(m, n) });
assert_own_property(window[this.name], "length");
assert_equals(window[this.name].length, expected_length, "wrong value for " + this.name + ".length");
@ -1015,19 +1018,21 @@ IdlInterface.prototype.test_self = function()
//"Otherwise, A does inherit from another interface. The value of
//the internal [[Prototype]] property of A is the interface
//prototype object for the inherited interface."
var inherit_interface;
if (this.inheritance.length)
var inherit_interface = (function()
{
inherit_interface = this.inheritance[0];
}
else if (this.has_extended_attribute("ArrayClass"))
{
inherit_interface = "Array";
}
else
{
inherit_interface = "Object";
}
for (var i = 0; i < this.inheritance.length; ++i)
{
if (!interfaces[this.inheritance[i]].has_extended_attribute("NoInterfaceObject"))
{
return this.inheritance[i];
}
}
if (this.has_extended_attribute("ArrayClass"))
{
return "Array";
}
return "Object";
}).bind(this)();
assert_own_property(window, inherit_interface,
'should inherit from ' + inherit_interface + ', but window has no such property');
assert_own_property(window[inherit_interface], "prototype",
@ -1041,9 +1046,9 @@ IdlInterface.prototype.test_self = function()
//String() and {}.toString.call() should be equivalent, since nothing
//defines a stringifier.
assert_equals({}.toString.call(window[this.name].prototype), "[object " + this.name + "Prototype]",
"{}.toString.call(" + this.name + ")");
"{}.toString.call(" + this.name + ".prototype)");
assert_equals(String(window[this.name].prototype), "[object " + this.name + "Prototype]",
"String(" + this.name + ")");
"String(" + this.name + ".prototype)");
}.bind(this), this.name + " interface: existence and properties of interface prototype object");
test(function()
@ -1189,9 +1194,12 @@ IdlInterface.prototype.test_members = function()
//". . .
//"Return the maximum argument list length of the functions
//in the entries of S."
//TODO: Does this work for overloads?
assert_equals(window[this.name].prototype[member.name].length, member.arguments.length,
"property has wrong .length");
}.bind(this), this.name + " interface: operation " + member.name);
}.bind(this), this.name + " interface: operation " + member.name +
"(" + member.arguments.map(function(m) { return m.type.idlType; }) +
")");
}
//TODO: check more member types, like stringifier
}
@ -1319,19 +1327,25 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect
// Attributes are accessor properties, so they might
// legitimately throw an exception rather than returning
// anything.
var property, thrown = false;
try
{
this.array.assert_type_is(obj[member.name], member.idlType);
property = obj[member.name];
}
catch (e)
{
thrown = true;
}
if (!thrown)
{
this.array.assert_type_is(property, member.idlType);
}
}
if (member.type == "operation")
{
assert_equals(typeof obj[member.name], "function");
}
}.bind(this), this.name + " interface: " + desc + ' must inherit property "' + member.name + '" with the proper type');
}.bind(this), this.name + " interface: " + desc + ' must inherit property "' + member.name + '" with the proper type (' + i + ')');
}
//TODO: This is wrong if there are multiple operations with the same
//identifier.
@ -1357,7 +1371,9 @@ IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expect
args.push(create_suitable_object(member.arguments[i].type));
}
}.bind(this), this.name + " interface: calling " + member.name + "() on " + desc + " with too few arguments must throw TypeError");
}.bind(this), this.name + " interface: calling " + member.name +
"(" + member.arguments.map(function(m) { return m.type.idlType; }) +
") on " + desc + " with too few arguments must throw TypeError");
}
}
}

View File

@ -2,6 +2,23 @@ html {
font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans;
}
#log .warning,
#log .warning a {
color: black;
background: yellow;
}
#log .error,
#log .error a {
color: white;
background: red;
}
#log pre {
border: 1px solid black;
padding: 1em;
}
section#summary {
margin-bottom:1em;
}
@ -22,6 +39,11 @@ table#results td:last-child {
width:50%;
}
table#results.assertions th:last-child,
table#results.assertions td:last-child {
width:35%;
}
table#results th {
padding:0;
padding-bottom:0.5em;

View File

@ -33,8 +33,8 @@ policies and contribution forms [3].
* the tests have run.
*
* NOTE: By default tests must be created before the load event fires. For ways
* to create tests after the load event, see "Determining when all tests are
* complete", below
* to create tests after the load event, see "Determining when all tests
* are complete", below
*
* == Synchronous Tests ==
*
@ -49,8 +49,8 @@ policies and contribution forms [3].
*
* The function passed in is run in the test() call.
*
* properties is an object that overrides default test properties. The recognised properties
* are:
* properties is an object that overrides default test properties. The
* recognised properties are:
* timeout - the test timeout in ms
*
* e.g.
@ -58,6 +58,19 @@ policies and contribution forms [3].
*
* would run test_function with a timeout of 1s.
*
* Additionally, test-specific metadata can be passed in the properties. These
* are used when the individual test has different metadata from that stored
* in the <head>.
* The recognized metadata properties are:
*
* help - The url of the part of the specification being tested
*
* assert - A human readable description of what the test is attempting
* to prove
*
* author - Name and contact information for the author of the test in the
* format: "Name <email_addr>" or "Name http://contact/url"
*
* == Asynchronous Tests ==
*
* Testing asynchronous features is somewhat more complex since the result of
@ -124,12 +137,18 @@ policies and contribution forms [3].
* tests to complete (this is different to the per-test timeout
* because async tests do not start their timer until .step is called)
*
* explicit_done - Wait for an explicit call to done() before declaring all tests
* complete (see below)
* explicit_done - Wait for an explicit call to done() before declaring all
* tests complete (see below)
*
* output_document - The document to which results should be logged. By default this is
* the current document but could be an ancestor document in some cases
* e.g. a SVG test loaded in an HTML wrapper
* output_document - The document to which results should be logged. By default
* this is the current document but could be an ancestor
* document in some cases e.g. a SVG test loaded in an HTML
* wrapper
*
* explicit_timeout - disable file timeout; only stop waiting for results
* when the timeout() function is called (typically for
* use when integrating with some existing test framework
* that has its own timeout mechanism).
*
* == Determining when all tests are complete ==
*
@ -138,10 +157,10 @@ policies and contribution forms [3].
* 1) There are no Test objects that have been created but not completed
* 2) The load event on the document has fired
*
* This behaviour can be overridden by setting the explicit_done property to true
* in a call to setup(). If explicit_done is true, the test harness will not assume
* it is done until the global done() function is called. Once done() is called, the
* two conditions above apply like normal.
* This behaviour can be overridden by setting the explicit_done property to
* true in a call to setup(). If explicit_done is true, the test harness will
* not assume it is done until the global done() function is called. Once done()
* is called, the two conditions above apply like normal.
*
* == Generating tests ==
*
@ -152,7 +171,7 @@ policies and contribution forms [3].
* used. To make this easier, the generate_tests function allows a single
* function to be called with each set of parameters in a list:
*
* generate_tests(test_function, parameter_lists)
* generate_tests(test_function, parameter_lists, properties)
*
* For example:
*
@ -169,6 +188,9 @@ policies and contribution forms [3].
* Note that the first item in each parameter list corresponds to the name of
* the test.
*
* The properties argument is identical to that for test(). This may be a
* single object (used for all generated tests) or an array.
*
* == Callback API ==
*
* The framework provides callbacks corresponding to 3 events:
@ -254,15 +276,16 @@ policies and contribution forms [3].
* assert that property property_name on object is readonly
*
* assert_throws(code, func, description)
* code - a DOMException/RangeException code as a string, e.g. "HIERARCHY_REQUEST_ERR"
* code - the expected exception:
* o string: the thrown exception must be a DOMException with the given
* name, e.g., "TimeoutError" (for compatibility with existing
* tests, a constant is also supported, e.g., "TIMEOUT_ERR")
* o object: the thrown exception must have a property called "name" that
* matches code.name
* o null: allow any exception (in general, one of the options above
* should be used)
* func - a function that should throw
*
* assert that func throws a DOMException or RangeException (as appropriate)
* with the given code. If an object is passed for code instead of a string,
* checks that the thrown exception has a property called "name" that matches
* the property of code called "name". Note, this function will probably be
* rewritten sometime to make more sense.
*
* assert_unreached(description)
* asserts if called. Used to ensure that some codepath is *not* taken e.g.
* an event does not fire.
@ -369,14 +392,16 @@ policies and contribution forms [3].
tests.end_wait();
}
function generate_tests(func, args) {
forEach(args, function(x)
function generate_tests(func, args, properties) {
forEach(args, function(x, i)
{
var name = x[0];
test(function()
{
func.apply(this, x.slice(1));
}, name);
},
name,
Array.isArray(properties) ? properties[i] : properties);
});
}
@ -751,6 +776,10 @@ policies and contribution forms [3].
if (e instanceof AssertionError) {
throw(e);
}
if (code === null)
{
return;
}
if (typeof code === "object")
{
assert(typeof e == "object" && "name" in e && e.name == code.name,
@ -761,40 +790,78 @@ policies and contribution forms [3].
expected_name:code.name});
return;
}
var required_props = {};
required_props.code = {
INDEX_SIZE_ERR: 1,
HIERARCHY_REQUEST_ERR: 3,
WRONG_DOCUMENT_ERR: 4,
INVALID_CHARACTER_ERR: 5,
NO_MODIFICATION_ALLOWED_ERR: 7,
NOT_FOUND_ERR: 8,
NOT_SUPPORTED_ERR: 9,
INVALID_STATE_ERR: 11,
SYNTAX_ERR: 12,
INVALID_MODIFICATION_ERR: 13,
NAMESPACE_ERR: 14,
INVALID_ACCESS_ERR: 15,
TYPE_MISMATCH_ERR: 17,
SECURITY_ERR: 18,
NETWORK_ERR: 19,
ABORT_ERR: 20,
URL_MISMATCH_ERR: 21,
QUOTA_EXCEEDED_ERR: 22,
TIMEOUT_ERR: 23,
INVALID_NODE_TYPE_ERR: 24,
DATA_CLONE_ERR: 25,
}[code];
if (required_props.code === undefined)
var code_name_map = {
INDEX_SIZE_ERR: 'IndexSizeError',
HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',
WRONG_DOCUMENT_ERR: 'WrongDocumentError',
INVALID_CHARACTER_ERR: 'InvalidCharacterError',
NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',
NOT_FOUND_ERR: 'NotFoundError',
NOT_SUPPORTED_ERR: 'NotSupportedError',
INVALID_STATE_ERR: 'InvalidStateError',
SYNTAX_ERR: 'SyntaxError',
INVALID_MODIFICATION_ERR: 'InvalidModificationError',
NAMESPACE_ERR: 'NamespaceError',
INVALID_ACCESS_ERR: 'InvalidAccessError',
TYPE_MISMATCH_ERR: 'TypeMismatchError',
SECURITY_ERR: 'SecurityError',
NETWORK_ERR: 'NetworkError',
ABORT_ERR: 'AbortError',
URL_MISMATCH_ERR: 'URLMismatchError',
QUOTA_EXCEEDED_ERR: 'QuotaExceededError',
TIMEOUT_ERR: 'TimeoutError',
INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError',
DATA_CLONE_ERR: 'DataCloneError',
};
var name = code in code_name_map ? code_name_map[code] : code;
var name_code_map = {
IndexSizeError: 1,
HierarchyRequestError: 3,
WrongDocumentError: 4,
InvalidCharacterError: 5,
NoModificationAllowedError: 7,
NotFoundError: 8,
NotSupportedError: 9,
InvalidStateError: 11,
SyntaxError: 12,
InvalidModificationError: 13,
NamespaceError: 14,
InvalidAccessError: 15,
TypeMismatchError: 17,
SecurityError: 18,
NetworkError: 19,
AbortError: 20,
URLMismatchError: 21,
QuotaExceededError: 22,
TimeoutError: 23,
InvalidNodeTypeError: 24,
DataCloneError: 25,
UnknownError: 0,
ConstraintError: 0,
DataError: 0,
TransactionInactiveError: 0,
ReadOnlyError: 0,
VersionError: 0,
};
if (!(name in name_code_map))
{
throw new AssertionError('Test bug: unrecognized DOMException code "' + code + '" passed to assert_throws()');
}
required_props[code] = required_props.code;
//Uncomment this when the latest version of every browser
//actually implements the spec; otherwise it just creates
//zillions of failures. Also do required_props.type.
//required_props.name = code;
//
var required_props = { code: name_code_map[name] };
if (required_props.code === 0
|| ("name" in e && e.name !== e.name.toUpperCase() && e.name !== "DOMException"))
{
// New style exception: also test the name property.
required_props.name = name;
}
//We'd like to test that e instanceof the appropriate interface,
//but we can't, because we don't know what window it was created
//in. It might be an instanceof the appropriate interface on some
@ -829,6 +896,7 @@ policies and contribution forms [3].
this.timeout_id = null;
this.is_done = false;
this.properties = properties;
this.timeout_length = properties.timeout ? properties.timeout : settings.test_timeout;
this.message = null;
@ -881,7 +949,7 @@ policies and contribution forms [3].
return;
}
this.status = this.FAIL;
this.message = e.message;
this.message = (typeof e === "object" && e !== null) ? e.message : e;
if (typeof e.stack != "undefined" && typeof e.message == "string") {
//Try to make it more informative for some exceptions, at least
//in Gecko and WebKit. This results in a stack dump instead of
@ -973,6 +1041,8 @@ policies and contribution forms [3].
};
this.phase = this.phases.INITIAL;
this.properties = {};
//All tests can't be done until the load event fires
this.all_loaded = false;
this.wait_for_finish = false;
@ -980,7 +1050,6 @@ policies and contribution forms [3].
this.timeout_length = settings.timeout;
this.timeout_id = null;
this.set_timeout();
this.start_callbacks = [];
this.test_done_callbacks = [];
@ -999,7 +1068,8 @@ policies and contribution forms [3].
this_obj.complete();
}
});
this.properties = {};
this.set_timeout();
}
Tests.prototype.setup = function(func, properties)
@ -1024,12 +1094,14 @@ policies and contribution forms [3].
if (properties.timeout)
{
this.timeout_length = properties.timeout;
this.set_timeout();
}
if (properties.explicit_done)
{
this.wait_for_finish = true;
}
if (properties.explicit_timeout) {
this.timeout_length = null;
}
if (func)
{
@ -1042,15 +1114,19 @@ policies and contribution forms [3].
this.status.message = e;
};
}
this.set_timeout();
};
Tests.prototype.set_timeout = function()
{
var this_obj = this;
clearTimeout(this.timeout_id);
this.timeout_id = setTimeout(function() {
this_obj.timeout();
}, this.timeout_length);
if (this.timeout_length !== null)
{
this.timeout_id = setTimeout(function() {
this_obj.timeout();
}, this.timeout_length);
}
};
Tests.prototype.timeout = function() {
@ -1069,7 +1145,7 @@ policies and contribution forms [3].
Tests.prototype.push = function(test)
{
if (this.phase < this.phases.HAVE_TESTS) {
this.notify_start();
this.start();
}
this.num_pending++;
this.tests.push(test);
@ -1201,6 +1277,14 @@ policies and contribution forms [3].
var tests = new Tests();
function timeout() {
if (tests.timeout_length === null)
{
tests.timeout();
}
}
expose(timeout, 'timeout');
function add_start_callback(callback) {
tests.start_callbacks.push(callback);
}
@ -1415,9 +1499,33 @@ policies and contribution forms [3].
.replace(/'/g, "&#39;");
}
function has_assertions()
{
for (var i = 0; i < tests.length; i++) {
if (tests[i].properties.hasOwnProperty("assert")) {
return true;
}
}
return false;
}
function get_assertion(test)
{
if (test.properties.hasOwnProperty("assert")) {
if (Array.isArray(test.properties.assert)) {
return test.properties.assert.join(' ');
}
return test.properties.assert;
}
return '';
}
log.appendChild(document.createElement("section"));
var html = "<h2>Details</h2><table id='results'>"
+ "<thead><tr><th>Result</th><th>Test Name</th><th>Message</th></tr></thead>"
var assertions = has_assertions();
var html = "<h2>Details</h2><table id='results' " + (assertions ? "class='assertions'" : "" ) + ">"
+ "<thead><tr><th>Result</th><th>Test Name</th>"
+ (assertions ? "<th>Assertion</th>" : "")
+ "<th>Message</th></tr></thead>"
+ "<tbody>";
for (var i = 0; i < tests.length; i++) {
html += '<tr class="'
@ -1427,6 +1535,7 @@ policies and contribution forms [3].
+ "</td><td>"
+ escape_html(tests[i].name)
+ "</td><td>"
+ (assertions ? escape_html(get_assertion(tests[i])) + "</td><td>" : "")
+ escape_html(tests[i].message ? tests[i].message : " ")
+ "</td></tr>";
}
@ -1755,4 +1864,4 @@ policies and contribution forms [3].
}
})();
// vim: set expandtab shiftwidth=4 tabstop=4:
// vim: set expandtab shiftwidth=4 tabstop=4: