зеркало из https://github.com/mozilla/gecko-dev.git
1079 строки
28 KiB
JavaScript
1079 строки
28 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
/**
|
|
* reflect.js is a collection of methods to test HTML attribute reflection.
|
|
* Each of attribute is reflected differently, depending on various parameters,
|
|
* see:
|
|
* http://www.whatwg.org/html/#reflecting-content-attributes-in-idl-attributes
|
|
*
|
|
* Do not forget to add these line at the beginning of each new reflect* method:
|
|
* ok(attr in element, attr + " should be an IDL attribute of this element");
|
|
* is(typeof element[attr], <type>, attr + " IDL attribute should be a <type>");
|
|
*/
|
|
|
|
/**
|
|
* Checks that a given attribute is correctly reflected as a string.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test
|
|
* - attribute String name of the attribute
|
|
* OR
|
|
* attribute Object object containing two attributes, 'content' and 'idl'
|
|
* - otherValues Array [optional] other values to test in addition of the default ones
|
|
* - extendedAttributes Object object which can have 'TreatNullAs': "EmptyString"
|
|
*/
|
|
function reflectString(aParameters) {
|
|
var element = aParameters.element;
|
|
var contentAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.content;
|
|
var idlAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.idl;
|
|
var otherValues =
|
|
aParameters.otherValues !== undefined ? aParameters.otherValues : [];
|
|
var treatNullAs = aParameters.extendedAttributes
|
|
? aParameters.extendedAttributes.TreatNullAs
|
|
: null;
|
|
|
|
ok(
|
|
idlAttr in element,
|
|
idlAttr + " should be an IDL attribute of this element"
|
|
);
|
|
is(
|
|
typeof element[idlAttr],
|
|
"string",
|
|
"'" + idlAttr + "' IDL attribute should be a string"
|
|
);
|
|
|
|
// Tests when the attribute isn't set.
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
null,
|
|
"When not set, the content attribute should be null."
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
"",
|
|
"When not set, the IDL attribute should return the empty string"
|
|
);
|
|
|
|
/**
|
|
* TODO: as long as null stringification doesn't follow the WebIDL
|
|
* specifications, don't add it to the loop below and keep it here.
|
|
*/
|
|
element.setAttribute(contentAttr, null);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
"null",
|
|
"null should have been stringified to 'null' for '" + contentAttr + "'"
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
"null",
|
|
"null should have been stringified to 'null' for '" + idlAttr + "'"
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = null;
|
|
if (treatNullAs == "EmptyString") {
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
"",
|
|
"null should have been stringified to '' for '" + contentAttr + "'"
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
"",
|
|
"null should have been stringified to '' for '" + idlAttr + "'"
|
|
);
|
|
} else {
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
"null",
|
|
"null should have been stringified to 'null' for '" + contentAttr + "'"
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
"null",
|
|
"null should have been stringified to 'null' for '" + contentAttr + "'"
|
|
);
|
|
}
|
|
element.removeAttribute(contentAttr);
|
|
|
|
// Tests various strings.
|
|
var stringsToTest = [
|
|
// [ test value, expected result ]
|
|
["", ""],
|
|
["null", "null"],
|
|
["undefined", "undefined"],
|
|
["foo", "foo"],
|
|
[contentAttr, contentAttr],
|
|
[idlAttr, idlAttr],
|
|
// TODO: uncomment this when null stringification will follow the specs.
|
|
// [ null, "null" ],
|
|
[undefined, "undefined"],
|
|
[true, "true"],
|
|
[false, "false"],
|
|
[42, "42"],
|
|
// ES5, verse 8.12.8.
|
|
[
|
|
{
|
|
toString() {
|
|
return "foo";
|
|
},
|
|
},
|
|
"foo",
|
|
],
|
|
[
|
|
{
|
|
valueOf() {
|
|
return "foo";
|
|
},
|
|
},
|
|
"[object Object]",
|
|
],
|
|
[
|
|
{
|
|
valueOf() {
|
|
return "quux";
|
|
},
|
|
toString: undefined,
|
|
},
|
|
"quux",
|
|
],
|
|
[
|
|
{
|
|
valueOf() {
|
|
return "foo";
|
|
},
|
|
toString() {
|
|
return "bar";
|
|
},
|
|
},
|
|
"bar",
|
|
],
|
|
];
|
|
|
|
otherValues.forEach(function(v) {
|
|
stringsToTest.push([v, v]);
|
|
});
|
|
|
|
stringsToTest.forEach(function([v, r]) {
|
|
element.setAttribute(contentAttr, v);
|
|
is(
|
|
element[idlAttr],
|
|
r,
|
|
"IDL attribute '" +
|
|
idlAttr +
|
|
"' should return the value it has been set to."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
r,
|
|
"Content attribute '" +
|
|
contentAttr +
|
|
"'should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v;
|
|
is(
|
|
element[idlAttr],
|
|
r,
|
|
"IDL attribute '" +
|
|
idlAttr +
|
|
"' should return the value it has been set to."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
r,
|
|
"Content attribute '" +
|
|
contentAttr +
|
|
"' should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
});
|
|
|
|
// Tests after removeAttribute() is called. Should be equivalent with not set.
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
null,
|
|
"When not set, the content attribute should be null."
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
"",
|
|
"When not set, the IDL attribute should return the empty string"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks that a given attribute name for a given element is correctly reflected
|
|
* as an unsigned int.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test on
|
|
* - attribute String name of the attribute
|
|
* - nonZero Boolean whether the attribute should be non-null
|
|
* - defaultValue Integer [optional] default value, if different from the default one
|
|
*/
|
|
function reflectUnsignedInt(aParameters) {
|
|
var element = aParameters.element;
|
|
var attr = aParameters.attribute;
|
|
var nonZero = aParameters.nonZero;
|
|
var defaultValue = aParameters.defaultValue;
|
|
var fallback = aParameters.fallback;
|
|
|
|
if (defaultValue === undefined) {
|
|
if (nonZero) {
|
|
defaultValue = 1;
|
|
} else {
|
|
defaultValue = 0;
|
|
}
|
|
}
|
|
|
|
if (fallback === undefined) {
|
|
fallback = false;
|
|
}
|
|
|
|
ok(attr in element, attr + " should be an IDL attribute of this element");
|
|
is(
|
|
typeof element[attr],
|
|
"number",
|
|
attr + " IDL attribute should be a number"
|
|
);
|
|
|
|
// Check default value.
|
|
is(element[attr], defaultValue, "default value should be " + defaultValue);
|
|
ok(!element.hasAttribute(attr), attr + " shouldn't be present");
|
|
|
|
var values = [1, 3, 42, 2147483647];
|
|
|
|
for (var value of values) {
|
|
element[attr] = value;
|
|
is(element[attr], value, "." + attr + " should be equals " + value);
|
|
is(
|
|
element.getAttribute(attr),
|
|
String(value),
|
|
"@" + attr + " should be equals " + value
|
|
);
|
|
|
|
element.setAttribute(attr, value);
|
|
is(element[attr], value, "." + attr + " should be equals " + value);
|
|
is(
|
|
element.getAttribute(attr),
|
|
String(value),
|
|
"@" + attr + " should be equals " + value
|
|
);
|
|
}
|
|
|
|
// -3000000000 is equivalent to 1294967296 when using the IDL attribute.
|
|
element[attr] = -3000000000;
|
|
is(element[attr], 1294967296, "." + attr + " should be equals to 1294967296");
|
|
is(
|
|
element.getAttribute(attr),
|
|
"1294967296",
|
|
"@" + attr + " should be equals to 1294967296"
|
|
);
|
|
|
|
// When setting the content attribute, it's a string so it will be invalid.
|
|
element.setAttribute(attr, -3000000000);
|
|
is(
|
|
element.getAttribute(attr),
|
|
"-3000000000",
|
|
"@" + attr + " should be equals to " + -3000000000
|
|
);
|
|
is(
|
|
element[attr],
|
|
defaultValue,
|
|
"." + attr + " should be equals to " + defaultValue
|
|
);
|
|
|
|
// When interpreted as unsigned 32-bit integers, all of these fall between
|
|
// 2^31 and 2^32 - 1, so per spec they return the default value.
|
|
var nonValidValues = [-2147483648, -1, 3147483647];
|
|
|
|
for (var value of nonValidValues) {
|
|
element[attr] = value;
|
|
is(
|
|
element.getAttribute(attr),
|
|
String(defaultValue),
|
|
"@" + attr + " should be equals to " + defaultValue
|
|
);
|
|
is(
|
|
element[attr],
|
|
defaultValue,
|
|
"." + attr + " should be equals to " + defaultValue
|
|
);
|
|
}
|
|
|
|
for (var values of nonValidValues) {
|
|
element.setAttribute(attr, values[0]);
|
|
is(
|
|
element.getAttribute(attr),
|
|
String(values[0]),
|
|
"@" + attr + " should be equals to " + values[0]
|
|
);
|
|
is(
|
|
element[attr],
|
|
defaultValue,
|
|
"." + attr + " should be equals to " + defaultValue
|
|
);
|
|
}
|
|
|
|
// Setting to 0 should throw an error if nonZero is true.
|
|
var caught = false;
|
|
try {
|
|
element[attr] = 0;
|
|
} catch (e) {
|
|
caught = true;
|
|
is(e.name, "IndexSizeError", "exception should be IndexSizeError");
|
|
is(
|
|
e.code,
|
|
DOMException.INDEX_SIZE_ERR,
|
|
"exception code should be INDEX_SIZE_ERR"
|
|
);
|
|
}
|
|
|
|
if (nonZero && !fallback) {
|
|
ok(caught, "an exception should have been caught");
|
|
} else {
|
|
ok(!caught, "no exception should have been caught");
|
|
}
|
|
|
|
// If 0 is set in @attr, it will be ignored when calling .attr.
|
|
element.setAttribute(attr, "0");
|
|
is(element.getAttribute(attr), "0", "@" + attr + " should be equals to 0");
|
|
if (nonZero) {
|
|
is(
|
|
element[attr],
|
|
defaultValue,
|
|
"." + attr + " should be equals to " + defaultValue
|
|
);
|
|
} else {
|
|
is(element[attr], 0, "." + attr + " should be equals to 0");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks that a given attribute is correctly reflected as limited to known
|
|
* values enumerated attribute.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test on
|
|
* - attribute String name of the attribute
|
|
* OR
|
|
* attribute Object object containing two attributes, 'content' and 'idl'
|
|
* - validValues Array valid values we support
|
|
* - invalidValues Array invalid values
|
|
* - defaultValue String [optional] default value when no valid value is set
|
|
* OR
|
|
* defaultValue Object [optional] object containing two attributes, 'invalid' and 'missing'
|
|
* - unsupportedValues Array [optional] valid values we do not support
|
|
* - nullable boolean [optional] whether the attribute is nullable
|
|
*/
|
|
function reflectLimitedEnumerated(aParameters) {
|
|
var element = aParameters.element;
|
|
var contentAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.content;
|
|
var idlAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.idl;
|
|
var validValues = aParameters.validValues;
|
|
var invalidValues = aParameters.invalidValues;
|
|
var defaultValueInvalid =
|
|
aParameters.defaultValue === undefined
|
|
? ""
|
|
: typeof aParameters.defaultValue === "string"
|
|
? aParameters.defaultValue
|
|
: aParameters.defaultValue.invalid;
|
|
var defaultValueMissing =
|
|
aParameters.defaultValue === undefined
|
|
? ""
|
|
: typeof aParameters.defaultValue === "string"
|
|
? aParameters.defaultValue
|
|
: aParameters.defaultValue.missing;
|
|
var unsupportedValues =
|
|
aParameters.unsupportedValues !== undefined
|
|
? aParameters.unsupportedValues
|
|
: [];
|
|
var nullable = aParameters.nullable;
|
|
|
|
ok(
|
|
idlAttr in element,
|
|
idlAttr + " should be an IDL attribute of this element"
|
|
);
|
|
if (nullable) {
|
|
// The missing value default is null, which is typeof == "object"
|
|
is(
|
|
typeof element[idlAttr],
|
|
"object",
|
|
"'" +
|
|
idlAttr +
|
|
"' IDL attribute should be null, which has typeof == object"
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
null,
|
|
"'" + idlAttr + "' IDL attribute should be null"
|
|
);
|
|
} else {
|
|
is(
|
|
typeof element[idlAttr],
|
|
"string",
|
|
"'" + idlAttr + "' IDL attribute should be a string"
|
|
);
|
|
}
|
|
|
|
if (nullable) {
|
|
element.setAttribute(contentAttr, "something");
|
|
// Now it will be a string
|
|
is(
|
|
typeof element[idlAttr],
|
|
"string",
|
|
"'" + idlAttr + "' IDL attribute should be a string"
|
|
);
|
|
}
|
|
|
|
// Explicitly check the default value.
|
|
element.removeAttribute(contentAttr);
|
|
is(
|
|
element[idlAttr],
|
|
defaultValueMissing,
|
|
"When no attribute is set, the value should be the default value."
|
|
);
|
|
|
|
// Check valid values.
|
|
validValues.forEach(function(v) {
|
|
element.setAttribute(contentAttr, v);
|
|
is(
|
|
element[idlAttr],
|
|
v,
|
|
"'" + v + "' should be accepted as a valid value for " + idlAttr
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element.setAttribute(contentAttr, v.toUpperCase());
|
|
is(
|
|
element[idlAttr],
|
|
v,
|
|
"Enumerated attributes should be case-insensitive."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.toUpperCase(),
|
|
"Content attribute should not be lower-cased."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v;
|
|
is(
|
|
element[idlAttr],
|
|
v,
|
|
"'" + v + "' should be accepted as a valid value for " + idlAttr
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v.toUpperCase();
|
|
is(
|
|
element[idlAttr],
|
|
v,
|
|
"Enumerated attributes should be case-insensitive."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.toUpperCase(),
|
|
"Content attribute should not be lower-cased."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
});
|
|
|
|
// Check invalid values.
|
|
invalidValues.forEach(function(v) {
|
|
element.setAttribute(contentAttr, v);
|
|
is(
|
|
element[idlAttr],
|
|
defaultValueInvalid,
|
|
"When the content attribute is set to an invalid value, the default value should be returned."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should not have been changed."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v;
|
|
is(
|
|
element[idlAttr],
|
|
defaultValueInvalid,
|
|
"When the value is set to an invalid value, the default value should be returned."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should not have been changed."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
});
|
|
|
|
// Check valid values we currently do not support.
|
|
// Basically, it's like the checks for the valid values but with some todo's.
|
|
unsupportedValues.forEach(function(v) {
|
|
element.setAttribute(contentAttr, v);
|
|
todo_is(
|
|
element[idlAttr],
|
|
v,
|
|
"'" + v + "' should be accepted as a valid value for " + idlAttr
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element.setAttribute(contentAttr, v.toUpperCase());
|
|
todo_is(
|
|
element[idlAttr],
|
|
v,
|
|
"Enumerated attributes should be case-insensitive."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.toUpperCase(),
|
|
"Content attribute should not be lower-cased."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v;
|
|
todo_is(
|
|
element[idlAttr],
|
|
v,
|
|
"'" + v + "' should be accepted as a valid value for " + idlAttr
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v,
|
|
"Content attribute should return the value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v.toUpperCase();
|
|
todo_is(
|
|
element[idlAttr],
|
|
v,
|
|
"Enumerated attributes should be case-insensitive."
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.toUpperCase(),
|
|
"Content attribute should not be lower-cased."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
});
|
|
|
|
if (nullable) {
|
|
is(
|
|
defaultValueMissing,
|
|
null,
|
|
"Missing default value should be null for nullable attributes"
|
|
);
|
|
ok(validValues.length > 0, "We better have at least one valid value");
|
|
element.setAttribute(contentAttr, validValues[0]);
|
|
ok(
|
|
element.hasAttribute(contentAttr),
|
|
"Should have content attribute: we just set it"
|
|
);
|
|
element[idlAttr] = null;
|
|
ok(
|
|
!element.hasAttribute(contentAttr),
|
|
"Should have removed content attribute"
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks that a given attribute is correctly reflected as a boolean.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test on
|
|
* - attribute String name of the attribute
|
|
* OR
|
|
* attribute Object object containing two attributes, 'content' and 'idl'
|
|
*/
|
|
function reflectBoolean(aParameters) {
|
|
var element = aParameters.element;
|
|
var contentAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.content;
|
|
var idlAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.idl;
|
|
|
|
ok(
|
|
idlAttr in element,
|
|
idlAttr + " should be an IDL attribute of this element"
|
|
);
|
|
is(
|
|
typeof element[idlAttr],
|
|
"boolean",
|
|
idlAttr + " IDL attribute should be a boolean"
|
|
);
|
|
|
|
// Tests when the attribute isn't set.
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
null,
|
|
"When not set, the content attribute should be null."
|
|
);
|
|
is(
|
|
element[idlAttr],
|
|
false,
|
|
"When not set, the IDL attribute should return false"
|
|
);
|
|
|
|
/**
|
|
* Test various values.
|
|
* Each value to test is actually an object containing a 'value' property
|
|
* containing the value to actually test, a 'stringified' property containing
|
|
* the stringified value and a 'result' property containing the expected
|
|
* result when the value is set to the IDL attribute.
|
|
*/
|
|
var valuesToTest = [
|
|
{ value: true, stringified: "true", result: true },
|
|
{ value: false, stringified: "false", result: false },
|
|
{ value: "true", stringified: "true", result: true },
|
|
{ value: "false", stringified: "false", result: true },
|
|
{ value: "foo", stringified: "foo", result: true },
|
|
{ value: idlAttr, stringified: idlAttr, result: true },
|
|
{ value: contentAttr, stringified: contentAttr, result: true },
|
|
{ value: "null", stringified: "null", result: true },
|
|
{ value: "undefined", stringified: "undefined", result: true },
|
|
{ value: "", stringified: "", result: false },
|
|
{ value: undefined, stringified: "undefined", result: false },
|
|
{ value: null, stringified: "null", result: false },
|
|
{ value: +0, stringified: "0", result: false },
|
|
{ value: -0, stringified: "0", result: false },
|
|
{ value: NaN, stringified: "NaN", result: false },
|
|
{ value: 42, stringified: "42", result: true },
|
|
{ value: Infinity, stringified: "Infinity", result: true },
|
|
{ value: -Infinity, stringified: "-Infinity", result: true },
|
|
// ES5, verse 9.2.
|
|
{
|
|
value: {
|
|
toString() {
|
|
return "foo";
|
|
},
|
|
},
|
|
stringified: "foo",
|
|
result: true,
|
|
},
|
|
{
|
|
value: {
|
|
valueOf() {
|
|
return "foo";
|
|
},
|
|
},
|
|
stringified: "[object Object]",
|
|
result: true,
|
|
},
|
|
{
|
|
value: {
|
|
valueOf() {
|
|
return "quux";
|
|
},
|
|
toString: undefined,
|
|
},
|
|
stringified: "quux",
|
|
result: true,
|
|
},
|
|
{
|
|
value: {
|
|
valueOf() {
|
|
return "foo";
|
|
},
|
|
toString() {
|
|
return "bar";
|
|
},
|
|
},
|
|
stringified: "bar",
|
|
result: true,
|
|
},
|
|
{
|
|
value: {
|
|
valueOf() {
|
|
return false;
|
|
},
|
|
},
|
|
stringified: "[object Object]",
|
|
result: true,
|
|
},
|
|
{
|
|
value: { foo: false, bar: false },
|
|
stringified: "[object Object]",
|
|
result: true,
|
|
},
|
|
{ value: {}, stringified: "[object Object]", result: true },
|
|
];
|
|
|
|
valuesToTest.forEach(function(v) {
|
|
element.setAttribute(contentAttr, v.value);
|
|
is(
|
|
element[idlAttr],
|
|
true,
|
|
"IDL attribute should return always return 'true' if the content attribute has been set"
|
|
);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.stringified,
|
|
"Content attribute should return the stringified value it has been set to."
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
|
|
element[idlAttr] = v.value;
|
|
is(element[idlAttr], v.result, "IDL attribute should return " + v.result);
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
v.result ? "" : null,
|
|
v.result
|
|
? "Content attribute should return the empty string."
|
|
: "Content attribute should return null."
|
|
);
|
|
is(
|
|
element.hasAttribute(contentAttr),
|
|
v.result,
|
|
v.result
|
|
? contentAttr + " should not be present"
|
|
: contentAttr + " should be present"
|
|
);
|
|
element.removeAttribute(contentAttr);
|
|
});
|
|
|
|
// Tests after removeAttribute() is called. Should be equivalent with not set.
|
|
is(
|
|
element.getAttribute(contentAttr),
|
|
null,
|
|
"When not set, the content attribute should be null."
|
|
);
|
|
is(
|
|
element[contentAttr],
|
|
false,
|
|
"When not set, the IDL attribute should return false"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks that a given attribute name for a given element is correctly reflected
|
|
* as an signed integer.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test on
|
|
* - attribute String name of the attribute
|
|
* - nonNegative Boolean true if the attribute is limited to 'non-negative numbers', false otherwise
|
|
* - defaultValue Integer [optional] default value, if one exists
|
|
*/
|
|
function reflectInt(aParameters) {
|
|
// Expected value returned by .getAttribute() when |value| has been previously passed to .setAttribute().
|
|
function expectedGetAttributeResult(value) {
|
|
return String(value);
|
|
}
|
|
|
|
function stringToInteger(value, nonNegative, defaultValue) {
|
|
// Parse: Ignore leading whitespace, find [+/-][numbers]
|
|
var result = /^[ \t\n\f\r]*([\+\-]?[0-9]+)/.exec(value);
|
|
if (result) {
|
|
var resultInt = parseInt(result[1], 10);
|
|
if (
|
|
(nonNegative ? 0 : -0x80000000) <= resultInt &&
|
|
resultInt <= 0x7fffffff
|
|
) {
|
|
// If the value is within allowed value range for signed/unsigned
|
|
// integer, return it -- but add 0 to it to convert a possible -0 into
|
|
// +0, the only zero present in the signed integer range.
|
|
return resultInt + 0;
|
|
}
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
// Expected value returned by .getAttribute(attr) or .attr if |value| has been set via the IDL attribute.
|
|
function expectedIdlAttributeResult(value) {
|
|
// This returns the result of calling the ES ToInt32 algorithm on value.
|
|
return value << 0;
|
|
}
|
|
|
|
var element = aParameters.element;
|
|
var attr = aParameters.attribute;
|
|
var nonNegative = aParameters.nonNegative;
|
|
|
|
var defaultValue =
|
|
aParameters.defaultValue !== undefined
|
|
? aParameters.defaultValue
|
|
: nonNegative
|
|
? -1
|
|
: 0;
|
|
|
|
ok(attr in element, attr + " should be an IDL attribute of this element");
|
|
is(
|
|
typeof element[attr],
|
|
"number",
|
|
attr + " IDL attribute should be a number"
|
|
);
|
|
|
|
// Check default value.
|
|
is(element[attr], defaultValue, "default value should be " + defaultValue);
|
|
ok(!element.hasAttribute(attr), attr + " shouldn't be present");
|
|
|
|
/**
|
|
* Test various values.
|
|
* value: The test value that will be set using both setAttribute(value) and
|
|
* element[attr] = value
|
|
*/
|
|
var valuesToTest = [
|
|
// Test numeric inputs up to max signed integer
|
|
0,
|
|
1,
|
|
55555,
|
|
2147483647,
|
|
+42,
|
|
// Test string inputs up to max signed integer
|
|
"0",
|
|
"1",
|
|
"777777",
|
|
"2147483647",
|
|
"+42",
|
|
// Test negative numeric inputs up to min signed integer
|
|
-0,
|
|
-1,
|
|
-3333,
|
|
-2147483648,
|
|
// Test negative string inputs up to min signed integer
|
|
"-0",
|
|
"-1",
|
|
"-222",
|
|
"-2147483647",
|
|
"-2147483648",
|
|
// Test numeric inputs that are outside legal 32 bit signed values
|
|
-2147483649,
|
|
-3000000000,
|
|
-4294967296,
|
|
2147483649,
|
|
4000000000,
|
|
-4294967297,
|
|
// Test string inputs with extra padding
|
|
" 1111111",
|
|
" 23456 ",
|
|
// Test non-numeric string inputs
|
|
"",
|
|
" ",
|
|
"+",
|
|
"-",
|
|
"foo",
|
|
"+foo",
|
|
"-foo",
|
|
"+ foo",
|
|
"- foo",
|
|
"+-2",
|
|
"-+2",
|
|
"++2",
|
|
"--2",
|
|
"hello1234",
|
|
"1234hello",
|
|
"444 world 555",
|
|
"why 567 what",
|
|
"-3 nots",
|
|
"2e5",
|
|
"300e2",
|
|
"42+-$",
|
|
"+42foo",
|
|
"-514not",
|
|
"\vblah",
|
|
"0x10FFFF",
|
|
"-0xABCDEF",
|
|
// Test decimal numbers
|
|
1.2345,
|
|
42.0,
|
|
3456789.1,
|
|
-2.3456,
|
|
-6789.12345,
|
|
-2147483649.1234,
|
|
// Test decimal strings
|
|
"1.2345",
|
|
"42.0",
|
|
"3456789.1",
|
|
"-2.3456",
|
|
"-6789.12345",
|
|
"-2147483649.1234",
|
|
// Test special values
|
|
undefined,
|
|
null,
|
|
NaN,
|
|
Infinity,
|
|
-Infinity,
|
|
];
|
|
|
|
valuesToTest.forEach(function(v) {
|
|
var intValue = stringToInteger(v, nonNegative, defaultValue);
|
|
|
|
element.setAttribute(attr, v);
|
|
|
|
is(
|
|
element.getAttribute(attr),
|
|
expectedGetAttributeResult(v),
|
|
element.localName +
|
|
".setAttribute(" +
|
|
attr +
|
|
", " +
|
|
v +
|
|
"), " +
|
|
element.localName +
|
|
".getAttribute(" +
|
|
attr +
|
|
") "
|
|
);
|
|
|
|
is(
|
|
element[attr],
|
|
intValue,
|
|
element.localName +
|
|
".setAttribute(" +
|
|
attr +
|
|
", " +
|
|
v +
|
|
"), " +
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] "
|
|
);
|
|
element.removeAttribute(attr);
|
|
|
|
if (nonNegative && expectedIdlAttributeResult(v) < 0) {
|
|
try {
|
|
element[attr] = v;
|
|
ok(
|
|
false,
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] = " +
|
|
v +
|
|
" should throw IndexSizeError"
|
|
);
|
|
} catch (e) {
|
|
is(
|
|
e.name,
|
|
"IndexSizeError",
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] = " +
|
|
v +
|
|
" should throw IndexSizeError"
|
|
);
|
|
is(
|
|
e.code,
|
|
DOMException.INDEX_SIZE_ERR,
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] = " +
|
|
v +
|
|
" should throw INDEX_SIZE_ERR"
|
|
);
|
|
}
|
|
} else {
|
|
element[attr] = v;
|
|
is(
|
|
element[attr],
|
|
expectedIdlAttributeResult(v),
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] = " +
|
|
v +
|
|
", " +
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] "
|
|
);
|
|
is(
|
|
element.getAttribute(attr),
|
|
String(expectedIdlAttributeResult(v)),
|
|
element.localName +
|
|
"[" +
|
|
attr +
|
|
"] = " +
|
|
v +
|
|
", " +
|
|
element.localName +
|
|
".getAttribute(" +
|
|
attr +
|
|
") "
|
|
);
|
|
}
|
|
element.removeAttribute(attr);
|
|
});
|
|
|
|
// Tests after removeAttribute() is called. Should be equivalent with not set.
|
|
is(
|
|
element.getAttribute(attr),
|
|
null,
|
|
"When not set, the content attribute should be null."
|
|
);
|
|
is(
|
|
element[attr],
|
|
defaultValue,
|
|
"When not set, the IDL attribute should return default value."
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Checks that a given attribute is correctly reflected as a url.
|
|
*
|
|
* @param aParameters Object object containing the parameters, which are:
|
|
* - element Element node to test
|
|
* - attribute String name of the attribute
|
|
* OR
|
|
* attribute Object object containing two attributes, 'content' and 'idl'
|
|
*/
|
|
function reflectURL(aParameters) {
|
|
var element = aParameters.element;
|
|
var contentAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.content;
|
|
var idlAttr =
|
|
typeof aParameters.attribute === "string"
|
|
? aParameters.attribute
|
|
: aParameters.attribute.idl;
|
|
|
|
element[idlAttr] = "";
|
|
is(
|
|
element[idlAttr],
|
|
document.URL,
|
|
"Empty string should resolve to document URL"
|
|
);
|
|
}
|