diff options
Diffstat (limited to 'dom/html/test/forms/test_valueasnumber_attribute.html')
-rw-r--r-- | dom/html/test/forms/test_valueasnumber_attribute.html | 744 |
1 files changed, 744 insertions, 0 deletions
diff --git a/dom/html/test/forms/test_valueasnumber_attribute.html b/dom/html/test/forms/test_valueasnumber_attribute.html new file mode 100644 index 000000000..d7471502b --- /dev/null +++ b/dom/html/test/forms/test_valueasnumber_attribute.html @@ -0,0 +1,744 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=636737 +--> +<head> + <title>Test for Bug input.valueAsNumber</title> + <script type="application/javascript" src="/MochiKit/packed.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=636737">Mozilla Bug 636737</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 636737 **/ + +/** + * This test is checking .valueAsNumber. + */ + +function checkAvailability() +{ + var testData = + [ + ["text", false], + ["password", false], + ["search", false], + ["tel", false], + ["email", false], + ["url", false], + ["hidden", false], + ["checkbox", false], + ["radio", false], + ["file", false], + ["submit", false], + ["image", false], + ["reset", false], + ["button", false], + ["number", true], + ["range", true], + ["date", true], + ["time", true], + ["color", false], + ["month", true], + ["week", true], + // TODO: temporary set to false until bug 888331 is fixed. + ["datetime-local", false], + ]; + + var element = document.createElement('input'); + + for (let data of testData) { + var exceptionCatched = false; + element.type = data[0]; + try { + element.valueAsNumber; + } catch (e) { + exceptionCatched = true; + } + is(exceptionCatched, false, + "valueAsNumber shouldn't throw exception on getting"); + + exceptionCatched = false; + try { + element.valueAsNumber = 42; + } catch (e) { + exceptionCatched = true; + } + is(exceptionCatched, !data[1], "valueAsNumber for " + data[0] + + " availability is not correct"); + } +} + +function checkNumberGet() +{ + var testData = + [ + ["42", 42], + ["-42", -42], // should work for negative values + ["42.1234", 42.1234], + ["123.123456789123", 123.123456789123], // double precision + ["1e2", 100], // e should be usable + ["2e1", 20], + ["1e-1", 0.1], // value after e can be negative + ["1E2", 100], // E can be used instead of e + ["e", null], + ["e2", null], + ["1e0.1", null], + ["", null], // the empty string is not a number + ["foo", null], + ["42,13", null], // comma can't be used as a decimal separator + ]; + + var element = document.createElement('input'); + element.type = "number"; + for (let data of testData) { + element.value = data[0]; + + // Given that NaN != NaN, we have to use null when the expected value is NaN. + if (data[1] != null) { + is(element.valueAsNumber, data[1], "valueAsNumber should return the " + + "floating point representation of the value"); + } else { + ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + + "when the element value is not a number"); + } + } +} + +function checkNumberSet() +{ + var testData = + [ + [42, "42"], + [-42, "-42"], // should work for negative values + [42.1234, "42.1234"], + [123.123456789123, "123.123456789123"], // double precision + [1e2, "100"], // e should be usable + [2e1, "20"], + [1e-1, "0.1"], // value after e can be negative + [1E2, "100"], // E can be used instead of e + // Setting a string will set NaN. + ["foo", ""], + // "" is converted to 0. + ["", "0"], + [42, "42"], // Keep this here, it is used by the next test. + // Setting Infinity should throw and not change the current value. + [Infinity, "42", true], + [-Infinity, "42", true], + // Setting NaN should change the value to the empty string. + [NaN, ""], + ]; + + var element = document.createElement('input'); + element.type = "number"; + for (let data of testData) { + var caught = false; + try { + element.valueAsNumber = data[0]; + is(element.value, data[1], + "valueAsNumber should be able to set the value"); + } catch (e) { + caught = true; + } + + if (data[2]) { + ok(caught, "valueAsNumber should have thrown"); + is(element.value, data[1], "value should not have changed"); + } else { + ok(!caught, "valueAsNumber should not have thrown"); + } + } +} + +function checkRangeGet() +{ + // For type=range we should never get NaN since the user agent is required + // to fix up the input's value to be something sensible. + + var min = -200; + var max = 200; + var defaultValue = min + (max - min)/2; + + var testData = + [ + ["42", 42], + ["-42", -42], // should work for negative values + ["42.1234", 42.1234], + ["123.123456789123", 123.123456789123], // double precision + ["1e2", 100], // e should be usable + ["2e1", 20], + ["1e-1", 0.1], // value after e can be negative + ["1E2", 100], // E can be used instead of e + ["e", defaultValue], + ["e2", defaultValue], + ["1e0.1", defaultValue], + ["", defaultValue], + ["foo", defaultValue], + ["42,13", defaultValue], + ]; + + var element = document.createElement('input'); + element.type = "range"; + element.setAttribute("min", min); // avoids out of range sanitization + element.setAttribute("max", max); + element.setAttribute("step", "any"); // avoids step mismatch sanitization + for (let data of testData) { + element.value = data[0]; + + // Given that NaN != NaN, we have to use null when the expected value is NaN. + is(element.valueAsNumber, data[1], "valueAsNumber should return the " + + "floating point representation of the value"); + } +} + +function checkRangeSet() +{ + var min = -200; + var max = 200; + var defaultValue = String(min + (max - min)/2); + + var testData = + [ + [42, "42"], + [-42, "-42"], // should work for negative values + [42.1234, "42.1234"], + [123.123456789123, "123.123456789123"], // double precision + [1e2, "100"], // e should be usable + [2e1, "20"], + [1e-1, "0.1"], // value after e can be negative + [1E2, "100"], // E can be used instead of e + ["foo", defaultValue], + ["", defaultValue], + [42, "42"], // Keep this here, it is used by the next test. + // Setting Infinity should throw and not change the current value. + [Infinity, "42", true], + [-Infinity, "42", true], + // Setting NaN should change the value to the empty string. + [NaN, defaultValue], + ]; + + var element = document.createElement('input'); + element.type = "range"; + element.setAttribute("min", min); // avoids out of range sanitization + element.setAttribute("max", max); + element.setAttribute("step", "any"); // avoids step mismatch sanitization + for (let data of testData) { + var caught = false; + try { + element.valueAsNumber = data[0]; + is(element.value, data[1], + "valueAsNumber should be able to set the value"); + } catch (e) { + caught = true; + } + + if (data[2]) { + ok(caught, "valueAsNumber should have thrown"); + is(element.value, data[1], "value should not have changed"); + } else { + ok(!caught, "valueAsNumber should not have thrown"); + } + } +} + +function checkDateGet() +{ + var validData = + [ + [ "2012-07-12", 1342051200000 ], + [ "1970-01-01", 0 ], + // We are supposed to support at least until this date. + // (corresponding to the date object maximal value) + [ "275760-09-13", 8640000000000000 ], + // Minimum valid date (limited by the input element minimum valid value) + [ "0001-01-01", -62135596800000 ], + [ "2012-02-29", 1330473600000 ], + [ "2011-02-28", 1298851200000 ], + ]; + + var invalidData = + [ + "invaliddate", + "", + "275760-09-14", + "999-12-31", + "-001-12-31", + "0000-01-01", + "2011-02-29", + "1901-13-31", + "1901-12-32", + "1901-00-12", + "1901-01-00", + "1900-02-29", + ]; + + var element = document.createElement('input'); + element.type = "date"; + for (let data of validData) { + element.value = data[0]; + is(element.valueAsNumber, data[1], "valueAsNumber should return the " + + "timestamp representing this date"); + } + + for (let data of invalidData) { + element.value = data; + ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + + "when the element value is not a valid date"); + } +} + +function checkDateSet() +{ + var testData = + [ + [ 1342051200000, "2012-07-12" ], + [ 0, "1970-01-01" ], + // Maximum valid date (limited by the ecma date object range). + [ 8640000000000000, "275760-09-13" ], + // Minimum valid date (limited by the input element minimum valid value) + [ -62135596800000, "0001-01-01" ], + [ 1330473600000, "2012-02-29" ], + [ 1298851200000, "2011-02-28" ], + // "Values must be truncated to valid dates" + [ 42.1234, "1970-01-01" ], + [ 123.123456789123, "1970-01-01" ], + [ 1e2, "1970-01-01" ], + [ 1E9, "1970-01-12" ], + [ 1e-1, "1970-01-01" ], + [ 2e10, "1970-08-20" ], + [ 1298851200010, "2011-02-28" ], + [ -1, "1969-12-31" ], + [ -86400000, "1969-12-31" ], + [ 86400000, "1970-01-02" ], + // Invalid numbers. + // Those are implicitly converted to numbers + [ "", "1970-01-01" ], + [ true, "1970-01-01" ], + [ false, "1970-01-01" ], + [ null, "1970-01-01" ], + // Those are converted to NaN, the corresponding date string is the empty string + [ "invaliddatenumber", "" ], + [ NaN, "" ], + [ undefined, "" ], + // Out of range, the corresponding date string is the empty string + [ -62135596800001, "" ], + // Infinity will keep the current value and throw (so we need to set a current value). + [ 1298851200010, "2011-02-28" ], + [ Infinity, "2011-02-28", true ], + [ -Infinity, "2011-02-28", true ], + ]; + + var element = document.createElement('input'); + element.type = "date"; + for (let data of testData) { + var caught = false; + + try { + element.valueAsNumber = data[0]; + is(element.value, data[1], "valueAsNumber should set the value to " + data[1]); + } catch(e) { + caught = true; + } + + if (data[2]) { + ok(caught, "valueAsNumber should have thrown"); + is(element.value, data[1], "the value should not have changed"); + } else { + ok(!caught, "valueAsNumber should not have thrown"); + } + } + +} + +function checkTimeGet() +{ + var tests = [ + // Some invalid values to begin. + { value: "", result: NaN }, + { value: "foobar", result: NaN }, + { value: "00:", result: NaN }, + { value: "24:00", result: NaN }, + { value: "00:99", result: NaN }, + { value: "00:00:", result: NaN }, + { value: "00:00:99", result: NaN }, + { value: "00:00:00:", result: NaN }, + { value: "00:00:00.", result: NaN }, + { value: "00:00:00.0000", result: NaN }, + // Some simple valid values. + { value: "00:00", result: 0 }, + { value: "00:01", result: 60000 }, + { value: "01:00", result: 3600000 }, + { value: "01:01", result: 3660000 }, + { value: "13:37", result: 49020000 }, + // Valid values including seconds. + { value: "00:00:01", result: 1000 }, + { value: "13:37:42", result: 49062000 }, + // Valid values including seconds fractions. + { value: "00:00:00.001", result: 1 }, + { value: "00:00:00.123", result: 123 }, + { value: "00:00:00.100", result: 100 }, + { value: "00:00:00.000", result: 0 }, + { value: "20:17:31.142", result: 73051142 }, + // Highest possible value. + { value: "23:59:59.999", result: 86399999 }, + // Some values with one or two digits for the fraction of seconds. + { value: "00:00:00.1", result: 100 }, + { value: "00:00:00.14", result: 140 }, + { value: "13:37:42.7", result: 49062700 }, + { value: "23:31:12.23", result: 84672230 }, + ]; + + var element = document.createElement('input'); + element.type = 'time'; + + for (let test of tests) { + element.value = test.value; + if (isNaN(test.result)) { + ok(isNaN(element.valueAsNumber), + "invalid value should have .valueAsNumber return NaN"); + } else { + is(element.valueAsNumber, test.result, + ".valueAsNumber should return " + test.result); + } + } +} + +function checkTimeSet() +{ + var tests = [ + // Some NaN values (should set to empty string). + { value: NaN, result: "" }, + { value: "foobar", result: "" }, + { value: function() {}, result: "" }, + // Inifinity (should throw). + { value: Infinity, throw: true }, + { value: -Infinity, throw: true }, + // "" converts to 0... JS is fun :) + { value: "", result: "00:00" }, + // Simple tests. + { value: 0, result: "00:00" }, + { value: 1, result: "00:00:00.001" }, + { value: 100, result: "00:00:00.100" }, + { value: 1000, result: "00:00:01" }, + { value: 60000, result: "00:01" }, + { value: 3600000, result: "01:00" }, + { value: 83622234, result: "23:13:42.234" }, + // Some edge cases. + { value: 86400000, result: "00:00" }, + { value: 86400001, result: "00:00:00.001" }, + { value: 170022234, result: "23:13:42.234" }, + { value: 432000000, result: "00:00" }, + { value: -1, result: "23:59:59.999" }, + { value: -86400000, result: "00:00" }, + { value: -86400001, result: "23:59:59.999" }, + { value: -56789, result: "23:59:03.211" }, + { value: 0.9, result: "00:00" }, + ]; + + var element = document.createElement('input'); + element.type = 'time'; + + for (let test of tests) { + try { + var caught = false; + element.valueAsNumber = test.value; + is(element.value, test.result, "value should return " + test.result); + } catch(e) { + caught = true; + } + + if (!test.throw) { + test.throw = false; + } + + is(caught, test.throw, "the test throwing status should be " + test.throw); + } +} + +function checkMonthGet() +{ + var validData = + [ + [ "2016-07", 558 ], + [ "1970-01", 0 ], + [ "1969-12", -1 ], + [ "0001-01", -23628 ], + [ "10000-12", 96371 ], + [ "275760-09", 3285488 ], + ]; + + var invalidData = + [ + "invalidmonth", + "0000-01", + "2000-00", + "2012-13", + // Out of range. + "275760-10", + ]; + + var element = document.createElement('input'); + element.type = "month"; + for (let data of validData) { + element.value = data[0]; + is(element.valueAsNumber, data[1], "valueAsNumber should return the " + + "integer value representing this month"); + } + + for (let data of invalidData) { + element.value = data; + ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + + "when the element value is not a valid month"); + } +} + +function checkMonthSet() +{ + var testData = + [ + [ 558, "2016-07" ], + [ 0, "1970-01" ], + [ -1, "1969-12" ], + [ 96371, "10000-12" ], + [ 12, "1971-01" ], + [ -12, "1969-01" ], + // Maximum valid month (limited by the ecma date object range) + [ 3285488, "275760-09" ], + // Minimum valid month (limited by the input element minimum valid value) + [ -23628, "0001-01" ], + // "Values must be truncated to valid months" + [ 0.3, "1970-01" ], + [ -1.1, "1969-11" ], + [ 1e2, "1978-05" ], + [ 1e-1, "1970-01" ], + // Invalid numbers. + // Those are implicitly converted to numbers + [ "", "1970-01" ], + [ true, "1970-02" ], + [ false, "1970-01" ], + [ null, "1970-01" ], + // Those are converted to NaN, the corresponding month string is the empty string + [ "invalidmonth", "" ], + [ NaN, "" ], + [ undefined, "" ], + // Out of range, the corresponding month string is the empty string + [ -23629, "" ], + [ 3285489, "" ], + // Infinity will keep the current value and throw (so we need to set a current value) + [ 558, "2016-07" ], + [ Infinity, "2016-07", true ], + [ -Infinity, "2016-07", true ], + ]; + + var element = document.createElement('input'); + element.type = "month"; + for (let data of testData) { + var caught = false; + + try { + element.valueAsNumber = data[0]; + is(element.value, data[1], "valueAsNumber should set the value to " + data[1]); + } catch(e) { + caught = true; + } + + if (data[2]) { + ok(caught, "valueAsNumber should have thrown"); + is(element.value, data[1], "the value should not have changed"); + } else { + ok(!caught, "valueAsNumber should not have thrown"); + } + } +} + +function checkWeekGet() +{ + var validData = + [ + // Common years starting on different days of week. + [ "2007-W01", Date.UTC(2007, 0, 1) ], // Mon + [ "2013-W01", Date.UTC(2012, 11, 31) ], // Tue + [ "2014-W01", Date.UTC(2013, 11, 30) ], // Wed + [ "2015-W01", Date.UTC(2014, 11, 29) ], // Thu + [ "2010-W01", Date.UTC(2010, 0, 4) ], // Fri + [ "2011-W01", Date.UTC(2011, 0, 3) ], // Sat + [ "2017-W01", Date.UTC(2017, 0, 2) ], // Sun + // Common years ending on different days of week. + [ "2007-W52", Date.UTC(2007, 11, 24) ], // Mon + [ "2013-W52", Date.UTC(2013, 11, 23) ], // Tue + [ "2014-W52", Date.UTC(2014, 11, 22) ], // Wed + [ "2015-W53", Date.UTC(2015, 11, 28) ], // Thu + [ "2010-W52", Date.UTC(2010, 11, 27) ], // Fri + [ "2011-W52", Date.UTC(2011, 11, 26) ], // Sat + [ "2017-W52", Date.UTC(2017, 11, 25) ], // Sun + // Leap years starting on different days of week. + [ "1996-W01", Date.UTC(1996, 0, 1) ], // Mon + [ "2008-W01", Date.UTC(2007, 11, 31) ], // Tue + [ "2020-W01", Date.UTC(2019, 11, 30) ], // Wed + [ "2004-W01", Date.UTC(2003, 11, 29) ], // Thu + [ "2016-W01", Date.UTC(2016, 0, 4) ], // Fri + [ "2000-W01", Date.UTC(2000, 0, 3) ], // Sat + [ "2012-W01", Date.UTC(2012, 0, 2) ], // Sun + // Leap years ending on different days of week. + [ "2012-W52", Date.UTC(2012, 11, 24) ], // Mon + [ "2024-W52", Date.UTC(2024, 11, 23) ], // Tue + [ "1980-W52", Date.UTC(1980, 11, 22) ], // Wed + [ "1992-W53", Date.UTC(1992, 11, 28) ], // Thu + [ "2004-W53", Date.UTC(2004, 11, 27) ], // Fri + [ "1988-W52", Date.UTC(1988, 11, 26) ], // Sat + [ "2000-W52", Date.UTC(2000, 11, 25) ], // Sun + // Other normal cases. + [ "2015-W53", Date.UTC(2015, 11, 28) ], + [ "2016-W36", Date.UTC(2016, 8, 5) ], + [ "1970-W01", Date.UTC(1969, 11, 29) ], + [ "275760-W37", Date.UTC(275760, 8, 8) ], + ]; + + var invalidData = + [ + "invalidweek", + "0000-W01", + "2016-W00", + "2016-W53", + // Out of range. + "275760-W38", + ]; + + var element = document.createElement('input'); + element.type = "week"; + for (let data of validData) { + dump("Test: " + data[0]); + element.value = data[0]; + is(element.valueAsNumber, data[1], "valueAsNumber should return the " + + "integer value representing this week"); + } + + for (let data of invalidData) { + element.value = data; + ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + + "when the element value is not a valid week"); + } +} + +function checkWeekSet() +{ + var testData = + [ + // Common years starting on different days of week. + [ Date.UTC(2007, 0, 1), "2007-W01" ], // Mon + [ Date.UTC(2013, 0, 1), "2013-W01" ], // Tue + [ Date.UTC(2014, 0, 1), "2014-W01" ], // Wed + [ Date.UTC(2015, 0, 1), "2015-W01" ], // Thu + [ Date.UTC(2010, 0, 1), "2009-W53" ], // Fri + [ Date.UTC(2011, 0, 1), "2010-W52" ], // Sat + [ Date.UTC(2017, 0, 1), "2016-W52" ], // Sun + // Common years ending on different days of week. + [ Date.UTC(2007, 11, 31), "2008-W01" ], // Mon + [ Date.UTC(2013, 11, 31), "2014-W01" ], // Tue + [ Date.UTC(2014, 11, 31), "2015-W01" ], // Wed + [ Date.UTC(2015, 11, 31), "2015-W53" ], // Thu + [ Date.UTC(2010, 11, 31), "2010-W52" ], // Fri + [ Date.UTC(2011, 11, 31), "2011-W52" ], // Sat + [ Date.UTC(2017, 11, 31), "2017-W52" ], // Sun + // Leap years starting on different days of week. + [ Date.UTC(1996, 0, 1), "1996-W01" ], // Mon + [ Date.UTC(2008, 0, 1), "2008-W01" ], // Tue + [ Date.UTC(2020, 0, 1), "2020-W01" ], // Wed + [ Date.UTC(2004, 0, 1), "2004-W01" ], // Thu + [ Date.UTC(2016, 0, 1), "2015-W53" ], // Fri + [ Date.UTC(2000, 0, 1), "1999-W52" ], // Sat + [ Date.UTC(2012, 0, 1), "2011-W52" ], // Sun + // Leap years ending on different days of week. + [ Date.UTC(2012, 11, 31), "2013-W01" ], // Mon + [ Date.UTC(2024, 11, 31), "2025-W01" ], // Tue + [ Date.UTC(1980, 11, 31), "1981-W01" ], // Wed + [ Date.UTC(1992, 11, 31), "1992-W53" ], // Thu + [ Date.UTC(2004, 11, 31), "2004-W53" ], // Fri + [ Date.UTC(1988, 11, 31), "1988-W52" ], // Sat + [ Date.UTC(2000, 11, 31), "2000-W52" ], // Sun + // Other normal cases. + [ Date.UTC(2008, 8, 26), "2008-W39" ], + [ Date.UTC(2016, 0, 4), "2016-W01" ], + [ Date.UTC(2016, 0, 10), "2016-W01" ], + [ Date.UTC(2016, 0, 11), "2016-W02" ], + // Maximum valid week (limited by the ecma date object range). + [ 8640000000000000, "275760-W37" ], + // Minimum valid week (limited by the input element minimum valid value) + [ -62135596800000, "0001-W01" ], + // "Values must be truncated to valid weeks" + [ 0.3, "1970-W01" ], + [ 1e-1, "1970-W01" ], + [ -1.1, "1970-W01" ], + [ -345600000, "1969-W52" ], + // Invalid numbers. + // Those are implicitly converted to numbers + [ "", "1970-W01" ], + [ true, "1970-W01" ], + [ false, "1970-W01" ], + [ null, "1970-W01" ], + // Those are converted to NaN, the corresponding week string is the empty string + [ "invalidweek", "" ], + [ NaN, "" ], + [ undefined, "" ], + // Infinity will keep the current value and throw (so we need to set a current value). + [ Date.UTC(2016, 8, 8), "2016-W36" ], + [ Infinity, "2016-W36", true ], + [ -Infinity, "2016-W36", true ], + ]; + + var element = document.createElement('input'); + element.type = "week"; + for (let data of testData) { + var caught = false; + + try { + element.valueAsNumber = data[0]; + is(element.value, data[1], "valueAsNumber should set the value to " + data[1]); + } catch(e) { + caught = true; + } + + if (data[2]) { + ok(caught, "valueAsNumber should have thrown"); + is(element.value, data[1], "the value should not have changed"); + } else { + ok(!caught, "valueAsNumber should not have thrown"); + } + } +} + +checkAvailability(); + +// <input type='number'> test +checkNumberGet(); +checkNumberSet(); + +// <input type='range'> test +checkRangeGet(); +checkRangeSet(); + +// <input type='date'> test +checkDateGet(); +checkDateSet(); + +// <input type='time'> test +checkTimeGet(); +checkTimeSet(); + +// <input type='month'> test +checkMonthGet(); +checkMonthSet(); + +// <input type='week'> test +checkWeekGet(); +checkWeekSet(); + +</script> +</pre> +</body> +</html> |