test_valueasnumber_attribute.html (27864B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=636737 5 --> 6 <head> 7 <title>Test for Bug input.valueAsNumber</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 10 </head> 11 <body> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=636737">Mozilla Bug 636737</a> 13 <p id="display"></p> 14 <pre id="test"> 15 <script type="application/javascript"> 16 17 /** Test for Bug 636737 */ 18 19 /** 20 * This test is checking .valueAsNumber. 21 */ 22 23 function checkAvailability() 24 { 25 var testData = 26 [ 27 ["text", false], 28 ["password", false], 29 ["search", false], 30 ["tel", false], 31 ["email", false], 32 ["url", false], 33 ["hidden", false], 34 ["checkbox", false], 35 ["radio", false], 36 ["file", false], 37 ["submit", false], 38 ["image", false], 39 ["reset", false], 40 ["button", false], 41 ["number", true], 42 ["range", true], 43 ["date", true], 44 ["time", true], 45 ["color", false], 46 ["month", true], 47 ["week", true], 48 ["datetime-local", true], 49 ]; 50 51 var element = document.createElement('input'); 52 53 for (let data of testData) { 54 var exceptionCatched = false; 55 element.type = data[0]; 56 try { 57 element.valueAsNumber; 58 } catch (e) { 59 exceptionCatched = true; 60 } 61 is(exceptionCatched, false, 62 "valueAsNumber shouldn't throw exception on getting"); 63 64 exceptionCatched = false; 65 try { 66 element.valueAsNumber = 42; 67 } catch (e) { 68 exceptionCatched = true; 69 } 70 is(exceptionCatched, !data[1], "valueAsNumber for " + data[0] + 71 " availability is not correct"); 72 } 73 } 74 75 function checkNumberGet() 76 { 77 var testData = 78 [ 79 ["42", 42], 80 ["-42", -42], // should work for negative values 81 ["42.1234", 42.1234], 82 ["123.123456789123", 123.123456789123], // double precision 83 ["1e2", 100], // e should be usable 84 ["2e1", 20], 85 ["1e-1", 0.1], // value after e can be negative 86 ["1E2", 100], // E can be used instead of e 87 ["e", null], 88 ["e2", null], 89 ["1e0.1", null], 90 ["", null], // the empty string is not a number 91 ["foo", null], 92 ["42,13", null], // comma can't be used as a decimal separator 93 ]; 94 95 var element = document.createElement('input'); 96 element.type = "number"; 97 for (let data of testData) { 98 element.value = data[0]; 99 100 // Given that NaN != NaN, we have to use null when the expected value is NaN. 101 if (data[1] != null) { 102 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 103 "floating point representation of the value"); 104 } else { 105 ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + 106 "when the element value is not a number"); 107 } 108 } 109 } 110 111 function checkNumberSet() 112 { 113 var testData = 114 [ 115 [42, "42"], 116 [-42, "-42"], // should work for negative values 117 [42.1234, "42.1234"], 118 [123.123456789123, "123.123456789123"], // double precision 119 [1e2, "100"], // e should be usable 120 [2e1, "20"], 121 [1e-1, "0.1"], // value after e can be negative 122 [1E2, "100"], // E can be used instead of e 123 // Setting a string will set NaN. 124 ["foo", ""], 125 // "" is converted to 0. 126 ["", "0"], 127 [42, "42"], // Keep this here, it is used by the next test. 128 // Setting Infinity should throw and not change the current value. 129 [Infinity, "42", true], 130 [-Infinity, "42", true], 131 // Setting NaN should change the value to the empty string. 132 [NaN, ""], 133 ]; 134 135 var element = document.createElement('input'); 136 element.type = "number"; 137 for (let data of testData) { 138 var caught = false; 139 try { 140 element.valueAsNumber = data[0]; 141 is(element.value, data[1], 142 "valueAsNumber should be able to set the value"); 143 } catch (e) { 144 caught = true; 145 } 146 147 if (data[2]) { 148 ok(caught, "valueAsNumber should have thrown"); 149 is(element.value, data[1], "value should not have changed"); 150 } else { 151 ok(!caught, "valueAsNumber should not have thrown"); 152 } 153 } 154 } 155 156 function checkRangeGet() 157 { 158 // For type=range we should never get NaN since the user agent is required 159 // to fix up the input's value to be something sensible. 160 161 var min = -200; 162 var max = 200; 163 var defaultValue = min + (max - min)/2; 164 165 var testData = 166 [ 167 ["42", 42], 168 ["-42", -42], // should work for negative values 169 ["42.1234", 42.1234], 170 ["123.123456789123", 123.123456789123], // double precision 171 ["1e2", 100], // e should be usable 172 ["2e1", 20], 173 ["1e-1", 0.1], // value after e can be negative 174 ["1E2", 100], // E can be used instead of e 175 ["e", defaultValue], 176 ["e2", defaultValue], 177 ["1e0.1", defaultValue], 178 ["", defaultValue], 179 ["foo", defaultValue], 180 ["42,13", defaultValue], 181 ]; 182 183 var element = document.createElement('input'); 184 element.type = "range"; 185 element.setAttribute("min", min); // avoids out of range sanitization 186 element.setAttribute("max", max); 187 element.setAttribute("step", "any"); // avoids step mismatch sanitization 188 for (let data of testData) { 189 element.value = data[0]; 190 191 // Given that NaN != NaN, we have to use null when the expected value is NaN. 192 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 193 "floating point representation of the value"); 194 } 195 } 196 197 function checkRangeSet() 198 { 199 var min = -200; 200 var max = 200; 201 var defaultValue = String(min + (max - min)/2); 202 203 var testData = 204 [ 205 [42, "42"], 206 [-42, "-42"], // should work for negative values 207 [42.1234, "42.1234"], 208 [123.123456789123, "123.123456789123"], // double precision 209 [1e2, "100"], // e should be usable 210 [2e1, "20"], 211 [1e-1, "0.1"], // value after e can be negative 212 [1E2, "100"], // E can be used instead of e 213 ["foo", defaultValue], 214 ["", defaultValue], 215 [42, "42"], // Keep this here, it is used by the next test. 216 // Setting Infinity should throw and not change the current value. 217 [Infinity, "42", true], 218 [-Infinity, "42", true], 219 // Setting NaN should change the value to the empty string. 220 [NaN, defaultValue], 221 ]; 222 223 var element = document.createElement('input'); 224 element.type = "range"; 225 element.setAttribute("min", min); // avoids out of range sanitization 226 element.setAttribute("max", max); 227 element.setAttribute("step", "any"); // avoids step mismatch sanitization 228 for (let data of testData) { 229 var caught = false; 230 try { 231 element.valueAsNumber = data[0]; 232 is(element.value, data[1], 233 "valueAsNumber should be able to set the value"); 234 } catch (e) { 235 caught = true; 236 } 237 238 if (data[2]) { 239 ok(caught, "valueAsNumber should have thrown"); 240 is(element.value, data[1], "value should not have changed"); 241 } else { 242 ok(!caught, "valueAsNumber should not have thrown"); 243 } 244 } 245 } 246 247 function checkDateGet() 248 { 249 var validData = 250 [ 251 [ "2012-07-12", 1342051200000 ], 252 [ "1970-01-01", 0 ], 253 // We are supposed to support at least until this date. 254 // (corresponding to the date object maximal value) 255 [ "275760-09-13", 8640000000000000 ], 256 // Minimum valid date (limited by the input element minimum valid value) 257 [ "0001-01-01", -62135596800000 ], 258 [ "2012-02-29", 1330473600000 ], 259 [ "2011-02-28", 1298851200000 ], 260 ]; 261 262 var invalidData = 263 [ 264 "invaliddate", 265 "", 266 "275760-09-14", 267 "999-12-31", 268 "-001-12-31", 269 "0000-01-01", 270 "2011-02-29", 271 "1901-13-31", 272 "1901-12-32", 273 "1901-00-12", 274 "1901-01-00", 275 "1900-02-29", 276 ]; 277 278 var element = document.createElement('input'); 279 element.type = "date"; 280 for (let data of validData) { 281 element.value = data[0]; 282 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 283 "timestamp representing this date"); 284 } 285 286 for (let data of invalidData) { 287 element.value = data; 288 ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + 289 "when the element value is not a valid date"); 290 } 291 } 292 293 function checkDateSet() 294 { 295 var testData = 296 [ 297 [ 1342051200000, "2012-07-12" ], 298 [ 0, "1970-01-01" ], 299 // Maximum valid date (limited by the ecma date object range). 300 [ 8640000000000000, "275760-09-13" ], 301 // Minimum valid date (limited by the input element minimum valid value) 302 [ -62135596800000, "0001-01-01" ], 303 [ 1330473600000, "2012-02-29" ], 304 [ 1298851200000, "2011-02-28" ], 305 // "Values must be truncated to valid dates" 306 [ 42.1234, "1970-01-01" ], 307 [ 123.123456789123, "1970-01-01" ], 308 [ 1e2, "1970-01-01" ], 309 [ 1E9, "1970-01-12" ], 310 [ 1e-1, "1970-01-01" ], 311 [ 2e10, "1970-08-20" ], 312 [ 1298851200010, "2011-02-28" ], 313 [ -1, "1969-12-31" ], 314 [ -86400000, "1969-12-31" ], 315 [ 86400000, "1970-01-02" ], 316 // Invalid numbers. 317 // Those are implicitly converted to numbers 318 [ "", "1970-01-01" ], 319 [ true, "1970-01-01" ], 320 [ false, "1970-01-01" ], 321 [ null, "1970-01-01" ], 322 // Those are converted to NaN, the corresponding date string is the empty string 323 [ "invaliddatenumber", "" ], 324 [ NaN, "" ], 325 [ undefined, "" ], 326 // Out of range, the corresponding date string is the empty string 327 [ -62135596800001, "" ], 328 // Infinity will keep the current value and throw (so we need to set a current value). 329 [ 1298851200010, "2011-02-28" ], 330 [ Infinity, "2011-02-28", true ], 331 [ -Infinity, "2011-02-28", true ], 332 ]; 333 334 var element = document.createElement('input'); 335 element.type = "date"; 336 for (let data of testData) { 337 var caught = false; 338 339 try { 340 element.valueAsNumber = data[0]; 341 is(element.value, data[1], "valueAsNumber should set the value to " + data[1]); 342 } catch(e) { 343 caught = true; 344 } 345 346 if (data[2]) { 347 ok(caught, "valueAsNumber should have thrown"); 348 is(element.value, data[1], "the value should not have changed"); 349 } else { 350 ok(!caught, "valueAsNumber should not have thrown"); 351 } 352 } 353 354 } 355 356 function checkTimeGet() 357 { 358 var tests = [ 359 // Some invalid values to begin. 360 { value: "", result: NaN }, 361 { value: "foobar", result: NaN }, 362 { value: "00:", result: NaN }, 363 { value: "24:00", result: NaN }, 364 { value: "00:99", result: NaN }, 365 { value: "00:00:", result: NaN }, 366 { value: "00:00:99", result: NaN }, 367 { value: "00:00:00:", result: NaN }, 368 { value: "00:00:00.", result: NaN }, 369 { value: "00:00:00.0000", result: NaN }, 370 // Some simple valid values. 371 { value: "00:00", result: 0 }, 372 { value: "00:01", result: 60000 }, 373 { value: "01:00", result: 3600000 }, 374 { value: "01:01", result: 3660000 }, 375 { value: "13:37", result: 49020000 }, 376 // Valid values including seconds. 377 { value: "00:00:01", result: 1000 }, 378 { value: "13:37:42", result: 49062000 }, 379 // Valid values including seconds fractions. 380 { value: "00:00:00.001", result: 1 }, 381 { value: "00:00:00.123", result: 123 }, 382 { value: "00:00:00.100", result: 100 }, 383 { value: "00:00:00.000", result: 0 }, 384 { value: "20:17:31.142", result: 73051142 }, 385 // Highest possible value. 386 { value: "23:59:59.999", result: 86399999 }, 387 // Some values with one or two digits for the fraction of seconds. 388 { value: "00:00:00.1", result: 100 }, 389 { value: "00:00:00.14", result: 140 }, 390 { value: "13:37:42.7", result: 49062700 }, 391 { value: "23:31:12.23", result: 84672230 }, 392 ]; 393 394 var element = document.createElement('input'); 395 element.type = 'time'; 396 397 for (let test of tests) { 398 element.value = test.value; 399 if (isNaN(test.result)) { 400 ok(isNaN(element.valueAsNumber), 401 "invalid value should have .valueAsNumber return NaN"); 402 } else { 403 is(element.valueAsNumber, test.result, 404 ".valueAsNumber should return " + test.result); 405 } 406 } 407 } 408 409 function checkTimeSet() 410 { 411 var tests = [ 412 // Some NaN values (should set to empty string). 413 { value: NaN, result: "" }, 414 { value: "foobar", result: "" }, 415 { value() {}, result: "" }, 416 // Inifinity (should throw). 417 { value: Infinity, throw: true }, 418 { value: -Infinity, throw: true }, 419 // "" converts to 0... JS is fun :) 420 { value: "", result: "00:00" }, 421 // Simple tests. 422 { value: 0, result: "00:00" }, 423 { value: 1, result: "00:00:00.001" }, 424 { value: 100, result: "00:00:00.100" }, 425 { value: 1000, result: "00:00:01" }, 426 { value: 60000, result: "00:01" }, 427 { value: 3600000, result: "01:00" }, 428 { value: 83622234, result: "23:13:42.234" }, 429 // Some edge cases. 430 { value: 86400000, result: "00:00" }, 431 { value: 86400001, result: "00:00:00.001" }, 432 { value: 170022234, result: "23:13:42.234" }, 433 { value: 432000000, result: "00:00" }, 434 { value: -1, result: "23:59:59.999" }, 435 { value: -86400000, result: "00:00" }, 436 { value: -86400001, result: "23:59:59.999" }, 437 { value: -56789, result: "23:59:03.211" }, 438 { value: 0.9, result: "00:00" }, 439 ]; 440 441 var element = document.createElement('input'); 442 element.type = 'time'; 443 444 for (let test of tests) { 445 try { 446 var caught = false; 447 element.valueAsNumber = test.value; 448 is(element.value, test.result, "value should return " + test.result); 449 } catch(e) { 450 caught = true; 451 } 452 453 if (!test.throw) { 454 test.throw = false; 455 } 456 457 is(caught, test.throw, "the test throwing status should be " + test.throw); 458 } 459 } 460 461 function checkMonthGet() 462 { 463 var validData = 464 [ 465 [ "2016-07", 558 ], 466 [ "1970-01", 0 ], 467 [ "1969-12", -1 ], 468 [ "0001-01", -23628 ], 469 [ "10000-12", 96371 ], 470 [ "275760-09", 3285488 ], 471 ]; 472 473 var invalidData = 474 [ 475 "invalidmonth", 476 "0000-01", 477 "2000-00", 478 "2012-13", 479 // Out of range. 480 "275760-10", 481 ]; 482 483 var element = document.createElement('input'); 484 element.type = "month"; 485 for (let data of validData) { 486 element.value = data[0]; 487 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 488 "integer value representing this month"); 489 } 490 491 for (let data of invalidData) { 492 element.value = data; 493 ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + 494 "when the element value is not a valid month"); 495 } 496 } 497 498 function checkMonthSet() 499 { 500 var testData = 501 [ 502 [ 558, "2016-07" ], 503 [ 0, "1970-01" ], 504 [ -1, "1969-12" ], 505 [ 96371, "10000-12" ], 506 [ 12, "1971-01" ], 507 [ -12, "1969-01" ], 508 // Maximum valid month (limited by the ecma date object range) 509 [ 3285488, "275760-09" ], 510 // Minimum valid month (limited by the input element minimum valid value) 511 [ -23628, "0001-01" ], 512 // "Values must be truncated to valid months" 513 [ 0.3, "1970-01" ], 514 [ -1.1, "1969-11" ], 515 [ 1e2, "1978-05" ], 516 [ 1e-1, "1970-01" ], 517 // Invalid numbers. 518 // Those are implicitly converted to numbers 519 [ "", "1970-01" ], 520 [ true, "1970-02" ], 521 [ false, "1970-01" ], 522 [ null, "1970-01" ], 523 // Those are converted to NaN, the corresponding month string is the empty string 524 [ "invalidmonth", "" ], 525 [ NaN, "" ], 526 [ undefined, "" ], 527 // Out of range, the corresponding month string is the empty string 528 [ -23629, "" ], 529 [ 3285489, "" ], 530 // Infinity will keep the current value and throw (so we need to set a current value) 531 [ 558, "2016-07" ], 532 [ Infinity, "2016-07", true ], 533 [ -Infinity, "2016-07", true ], 534 ]; 535 536 var element = document.createElement('input'); 537 element.type = "month"; 538 for (let data of testData) { 539 var caught = false; 540 541 try { 542 element.valueAsNumber = data[0]; 543 is(element.value, data[1], "valueAsNumber should set the value to " + data[1]); 544 } catch(e) { 545 caught = true; 546 } 547 548 if (data[2]) { 549 ok(caught, "valueAsNumber should have thrown"); 550 is(element.value, data[1], "the value should not have changed"); 551 } else { 552 ok(!caught, "valueAsNumber should not have thrown"); 553 } 554 } 555 } 556 557 function checkWeekGet() 558 { 559 var validData = 560 [ 561 // Common years starting on different days of week. 562 [ "2007-W01", Date.UTC(2007, 0, 1) ], // Mon 563 [ "2013-W01", Date.UTC(2012, 11, 31) ], // Tue 564 [ "2014-W01", Date.UTC(2013, 11, 30) ], // Wed 565 [ "2015-W01", Date.UTC(2014, 11, 29) ], // Thu 566 [ "2010-W01", Date.UTC(2010, 0, 4) ], // Fri 567 [ "2011-W01", Date.UTC(2011, 0, 3) ], // Sat 568 [ "2017-W01", Date.UTC(2017, 0, 2) ], // Sun 569 // Common years ending on different days of week. 570 [ "2007-W52", Date.UTC(2007, 11, 24) ], // Mon 571 [ "2013-W52", Date.UTC(2013, 11, 23) ], // Tue 572 [ "2014-W52", Date.UTC(2014, 11, 22) ], // Wed 573 [ "2015-W53", Date.UTC(2015, 11, 28) ], // Thu 574 [ "2010-W52", Date.UTC(2010, 11, 27) ], // Fri 575 [ "2011-W52", Date.UTC(2011, 11, 26) ], // Sat 576 [ "2017-W52", Date.UTC(2017, 11, 25) ], // Sun 577 // Leap years starting on different days of week. 578 [ "1996-W01", Date.UTC(1996, 0, 1) ], // Mon 579 [ "2008-W01", Date.UTC(2007, 11, 31) ], // Tue 580 [ "2020-W01", Date.UTC(2019, 11, 30) ], // Wed 581 [ "2004-W01", Date.UTC(2003, 11, 29) ], // Thu 582 [ "2016-W01", Date.UTC(2016, 0, 4) ], // Fri 583 [ "2000-W01", Date.UTC(2000, 0, 3) ], // Sat 584 [ "2012-W01", Date.UTC(2012, 0, 2) ], // Sun 585 // Leap years ending on different days of week. 586 [ "2012-W52", Date.UTC(2012, 11, 24) ], // Mon 587 [ "2024-W52", Date.UTC(2024, 11, 23) ], // Tue 588 [ "1980-W52", Date.UTC(1980, 11, 22) ], // Wed 589 [ "1992-W53", Date.UTC(1992, 11, 28) ], // Thu 590 [ "2004-W53", Date.UTC(2004, 11, 27) ], // Fri 591 [ "1988-W52", Date.UTC(1988, 11, 26) ], // Sat 592 [ "2000-W52", Date.UTC(2000, 11, 25) ], // Sun 593 // Other normal cases. 594 [ "2015-W53", Date.UTC(2015, 11, 28) ], 595 [ "2016-W36", Date.UTC(2016, 8, 5) ], 596 [ "1970-W01", Date.UTC(1969, 11, 29) ], 597 [ "275760-W37", Date.UTC(275760, 8, 8) ], 598 ]; 599 600 var invalidData = 601 [ 602 "invalidweek", 603 "0000-W01", 604 "2016-W00", 605 "2016-W53", 606 // Out of range. 607 "275760-W38", 608 ]; 609 610 var element = document.createElement('input'); 611 element.type = "week"; 612 for (let data of validData) { 613 element.value = data[0]; 614 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 615 "integer value representing this week"); 616 } 617 618 for (let data of invalidData) { 619 element.value = data; 620 ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + 621 "when the element value is not a valid week"); 622 } 623 } 624 625 function checkWeekSet() 626 { 627 var testData = 628 [ 629 // Common years starting on different days of week. 630 [ Date.UTC(2007, 0, 1), "2007-W01" ], // Mon 631 [ Date.UTC(2013, 0, 1), "2013-W01" ], // Tue 632 [ Date.UTC(2014, 0, 1), "2014-W01" ], // Wed 633 [ Date.UTC(2015, 0, 1), "2015-W01" ], // Thu 634 [ Date.UTC(2010, 0, 1), "2009-W53" ], // Fri 635 [ Date.UTC(2011, 0, 1), "2010-W52" ], // Sat 636 [ Date.UTC(2017, 0, 1), "2016-W52" ], // Sun 637 // Common years ending on different days of week. 638 [ Date.UTC(2007, 11, 31), "2008-W01" ], // Mon 639 [ Date.UTC(2013, 11, 31), "2014-W01" ], // Tue 640 [ Date.UTC(2014, 11, 31), "2015-W01" ], // Wed 641 [ Date.UTC(2015, 11, 31), "2015-W53" ], // Thu 642 [ Date.UTC(2010, 11, 31), "2010-W52" ], // Fri 643 [ Date.UTC(2011, 11, 31), "2011-W52" ], // Sat 644 [ Date.UTC(2017, 11, 31), "2017-W52" ], // Sun 645 // Leap years starting on different days of week. 646 [ Date.UTC(1996, 0, 1), "1996-W01" ], // Mon 647 [ Date.UTC(2008, 0, 1), "2008-W01" ], // Tue 648 [ Date.UTC(2020, 0, 1), "2020-W01" ], // Wed 649 [ Date.UTC(2004, 0, 1), "2004-W01" ], // Thu 650 [ Date.UTC(2016, 0, 1), "2015-W53" ], // Fri 651 [ Date.UTC(2000, 0, 1), "1999-W52" ], // Sat 652 [ Date.UTC(2012, 0, 1), "2011-W52" ], // Sun 653 // Leap years ending on different days of week. 654 [ Date.UTC(2012, 11, 31), "2013-W01" ], // Mon 655 [ Date.UTC(2024, 11, 31), "2025-W01" ], // Tue 656 [ Date.UTC(1980, 11, 31), "1981-W01" ], // Wed 657 [ Date.UTC(1992, 11, 31), "1992-W53" ], // Thu 658 [ Date.UTC(2004, 11, 31), "2004-W53" ], // Fri 659 [ Date.UTC(1988, 11, 31), "1988-W52" ], // Sat 660 [ Date.UTC(2000, 11, 31), "2000-W52" ], // Sun 661 // Other normal cases. 662 [ Date.UTC(2008, 8, 26), "2008-W39" ], 663 [ Date.UTC(2016, 0, 4), "2016-W01" ], 664 [ Date.UTC(2016, 0, 10), "2016-W01" ], 665 [ Date.UTC(2016, 0, 11), "2016-W02" ], 666 // Maximum valid week (limited by the ecma date object range). 667 [ 8640000000000000, "275760-W37" ], 668 // Minimum valid week (limited by the input element minimum valid value) 669 [ -62135596800000, "0001-W01" ], 670 // "Values must be truncated to valid weeks" 671 [ 0.3, "1970-W01" ], 672 [ 1e-1, "1970-W01" ], 673 [ -1.1, "1970-W01" ], 674 [ -345600000, "1969-W52" ], 675 // Invalid numbers. 676 // Those are implicitly converted to numbers 677 [ "", "1970-W01" ], 678 [ true, "1970-W01" ], 679 [ false, "1970-W01" ], 680 [ null, "1970-W01" ], 681 // Those are converted to NaN, the corresponding week string is the empty string 682 [ "invalidweek", "" ], 683 [ NaN, "" ], 684 [ undefined, "" ], 685 // Infinity will keep the current value and throw (so we need to set a current value). 686 [ Date.UTC(2016, 8, 8), "2016-W36" ], 687 [ Infinity, "2016-W36", true ], 688 [ -Infinity, "2016-W36", true ], 689 ]; 690 691 var element = document.createElement('input'); 692 element.type = "week"; 693 for (let data of testData) { 694 var caught = false; 695 696 try { 697 element.valueAsNumber = data[0]; 698 is(element.value, data[1], "valueAsNumber should set the value to " + 699 data[1]); 700 } catch(e) { 701 caught = true; 702 } 703 704 if (data[2]) { 705 ok(caught, "valueAsNumber should have thrown"); 706 is(element.value, data[1], "the value should not have changed"); 707 } else { 708 ok(!caught, "valueAsNumber should not have thrown"); 709 } 710 } 711 } 712 713 function checkDatetimeLocalGet() { 714 var validData = 715 [ 716 // Simple cases. 717 [ "2016-12-20T09:58", Date.UTC(2016, 11, 20, 9, 58) ], 718 [ "2016-12-20T09:58:30", Date.UTC(2016, 11, 20, 9, 58, 30) ], 719 [ "2016-12-20T09:58:30.123", Date.UTC(2016, 11, 20, 9, 58, 30, 123) ], 720 [ "2017-01-01T10:00", Date.UTC(2017, 0, 1, 10, 0, 0) ], 721 [ "1969-12-31T12:00:00", Date.UTC(1969, 11, 31, 12, 0, 0) ], 722 [ "1970-01-01T00:00", 0 ], 723 // Leap years. 724 [ "1804-02-29 12:34", Date.UTC(1804, 1, 29, 12, 34, 0) ], 725 [ "2016-02-29T12:34", Date.UTC(2016, 1, 29, 12, 34, 0) ], 726 [ "2016-12-31T12:34:56", Date.UTC(2016, 11, 31, 12, 34, 56) ], 727 [ "2016-01-01T12:34:56.789", Date.UTC(2016, 0, 1, 12, 34, 56, 789) ], 728 [ "2017-01-01 12:34:56.789", Date.UTC(2017, 0, 1, 12, 34, 56, 789) ], 729 // Maximum valid datetime-local (limited by the ecma date object range). 730 [ "275760-09-13T00:00", 8640000000000000 ], 731 // Minimum valid datetime-local (limited by the input element minimum valid value). 732 [ "0001-01-01T00:00", -62135596800000 ], 733 ]; 734 735 var invalidData = 736 [ 737 "invaliddatetime-local", 738 "0000-01-01T00:00", 739 "2016-12-25T00:00Z", 740 "2015-02-29T12:34", 741 "1-1-1T12:00", 742 // Out of range. 743 "275760-09-13T12:00", 744 ]; 745 746 var element = document.createElement('input'); 747 element.type = "datetime-local"; 748 for (let data of validData) { 749 element.value = data[0]; 750 is(element.valueAsNumber, data[1], "valueAsNumber should return the " + 751 "integer value representing this datetime-local"); 752 } 753 754 for (let data of invalidData) { 755 element.value = data; 756 ok(isNaN(element.valueAsNumber), "valueAsNumber should return NaN " + 757 "when the element value is not a valid datetime-local"); 758 } 759 } 760 761 function checkDatetimeLocalSet() 762 { 763 var testData = 764 [ 765 // Simple cases. 766 [ Date.UTC(2016, 11, 20, 9, 58, 0), "2016-12-20T09:58", ], 767 [ Date.UTC(2016, 11, 20, 9, 58, 30), "2016-12-20T09:58:30" ], 768 [ Date.UTC(2016, 11, 20, 9, 58, 30, 123), "2016-12-20T09:58:30.123" ], 769 [ Date.UTC(2017, 0, 1, 10, 0, 0), "2017-01-01T10:00" ], 770 [ Date.UTC(1969, 11, 31, 12, 0, 0), "1969-12-31T12:00" ], 771 [ 0, "1970-01-01T00:00" ], 772 // Maximum valid week (limited by the ecma date object range). 773 [ 8640000000000000, "275760-09-13T00:00" ], 774 // Minimum valid datetime-local (limited by the input element minimum valid value). 775 [ -62135596800000, "0001-01-01T00:00" ], 776 // Leap years. 777 [ Date.UTC(1804, 1, 29, 12, 34, 0), "1804-02-29T12:34" ], 778 [ Date.UTC(2016, 1, 29, 12, 34, 0), "2016-02-29T12:34" ], 779 [ Date.UTC(2016, 11, 31, 12, 34, 56), "2016-12-31T12:34:56" ], 780 [ Date.UTC(2016, 0, 1, 12, 34, 56, 789), "2016-01-01T12:34:56.789" ], 781 [ Date.UTC(2017, 0, 1, 12, 34, 56, 789), "2017-01-01T12:34:56.789" ], 782 // "Values must be truncated to valid datetime-local" 783 [ 0.3, "1970-01-01T00:00" ], 784 [ 1e-1, "1970-01-01T00:00" ], 785 [ -1 , "1969-12-31T23:59:59.999" ], 786 [ -345600000, "1969-12-28T00:00" ], 787 // Invalid numbers. 788 // Those are implicitly converted to numbers 789 [ "", "1970-01-01T00:00" ], 790 [ true, "1970-01-01T00:00:00.001" ], 791 [ false, "1970-01-01T00:00" ], 792 [ null, "1970-01-01T00:00" ], 793 // Those are converted to NaN, the corresponding week string is the empty string 794 [ "invaliddatetime-local", "" ], 795 [ NaN, "" ], 796 [ undefined, "" ], 797 // Infinity will keep the current value and throw (so we need to set a current value). 798 [ Date.UTC(2016, 11, 27, 15, 10, 0), "2016-12-27T15:10" ], 799 [ Infinity, "2016-12-27T15:10", true ], 800 [ -Infinity, "2016-12-27T15:10", true ], 801 ]; 802 803 var element = document.createElement('input'); 804 element.type = "datetime-local"; 805 for (let data of testData) { 806 var caught = false; 807 808 try { 809 element.valueAsNumber = data[0]; 810 is(element.value, data[1], "valueAsNumber should set the value to " + 811 data[1]); 812 } catch(e) { 813 caught = true; 814 } 815 816 if (data[2]) { 817 ok(caught, "valueAsNumber should have thrown"); 818 is(element.value, data[1], "the value should not have changed"); 819 } else { 820 ok(!caught, "valueAsNumber should not have thrown"); 821 } 822 } 823 } 824 825 checkAvailability(); 826 827 // <input type='number'> test 828 checkNumberGet(); 829 checkNumberSet(); 830 831 // <input type='range'> test 832 checkRangeGet(); 833 checkRangeSet(); 834 835 // <input type='date'> test 836 checkDateGet(); 837 checkDateSet(); 838 839 // <input type='time'> test 840 checkTimeGet(); 841 checkTimeSet(); 842 843 // <input type='month'> test 844 checkMonthGet(); 845 checkMonthSet(); 846 847 // <input type='week'> test 848 checkWeekGet(); 849 checkWeekSet(); 850 851 // <input type='datetime-local'> test 852 checkDatetimeLocalGet(); 853 checkDatetimeLocalSet(); 854 855 </script> 856 </pre> 857 </body> 858 </html>