summaryrefslogtreecommitdiffstats
path: root/dom/html/test/reflect.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /dom/html/test/reflect.js
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/html/test/reflect.js')
-rw-r--r--dom/html/test/reflect.js1078
1 files changed, 1078 insertions, 0 deletions
diff --git a/dom/html/test/reflect.js b/dom/html/test/reflect.js
new file mode 100644
index 0000000000..44f73ae4a2
--- /dev/null
+++ b/dom/html/test/reflect.js
@@ -0,0 +1,1078 @@
+/* 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, "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"
+ );
+}