test_min_attribute.html (13685B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=635553 5 --> 6 <head> 7 <title>Test for Bug 635553</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=635499">Mozilla Bug 635499</a> 13 <p id="display"></p> 14 <div id="content" style="display: none"> 15 </div> 16 <pre id="test"> 17 <script type="application/javascript"> 18 19 /** Test for Bug 635553 */ 20 21 var data = [ 22 { type: 'hidden', apply: false }, 23 { type: 'text', apply: false }, 24 { type: 'search', apply: false }, 25 { type: 'tel', apply: false }, 26 { type: 'url', apply: false }, 27 { type: 'email', apply: false }, 28 { type: 'password', apply: false }, 29 { type: 'date', apply: true }, 30 { type: 'month', apply: true }, 31 { type: 'week', apply: true }, 32 { type: 'time', apply: true }, 33 { type: 'datetime-local', apply: true }, 34 { type: 'number', apply: true }, 35 { type: 'range', apply: true }, 36 { type: 'color', apply: false }, 37 { type: 'checkbox', apply: false }, 38 { type: 'radio', apply: false }, 39 { type: 'file', apply: false }, 40 { type: 'submit', apply: false }, 41 { type: 'image', apply: false }, 42 { type: 'reset', apply: false }, 43 { type: 'button', apply: false }, 44 ]; 45 46 var input = document.createElement("input"); 47 document.getElementById('content').appendChild(input); 48 49 /** 50 * @param {boolean} aValidity 51 * Indicates whether the element is expected to be valid 52 * (aElement.validity.valid is true) or not. The value passed is ignored and 53 * overridden with true if aApply is false. 54 * @param {boolean} aApply 55 * Indicating whether the min/max attributes apply to this element type. 56 * @param {boolean} aRangeApply 57 * Set to true if the current input type is a "[candidate] for constraint 58 * validation" and it "[has] range limitations" per 59 * http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#selector-in-range 60 * (in other words, one of the pseudo classes :in-range and :out-of-range 61 * should apply (which, depends on aValidity)). 62 * Else (neither :in-range or :out-of-range should match) set to false. 63 */ 64 function checkValidity(aElement, aValidity, aApply, aRangeApply) 65 { 66 aValidity = aApply ? aValidity : true; 67 68 is(aElement.validity.valid, aValidity, 69 "element validity should be " + aValidity); 70 is(aElement.validity.rangeUnderflow, !aValidity, 71 "element underflow status should be " + !aValidity); 72 var underflowMsg = 73 (aElement.type == "date" || aElement.type == "time" || 74 aElement.type == "month" || aElement.type == "week" || 75 aElement.type == "datetime-local") ? 76 ("Please select a value that is no earlier than " + aElement.min + ".") : 77 ("Please select a value that is no less than " + aElement.min + "."); 78 is(aElement.validationMessage, 79 aValidity ? "" : underflowMsg, "Checking range underflow validation message"); 80 81 is(aElement.matches(":valid"), aElement.willValidate && aValidity, 82 (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply"); 83 is(aElement.matches(":invalid"), aElement.willValidate && !aValidity, 84 (aElement.wil && aValidity) ? ":invalid shouldn't apply" : "valid should apply"); 85 86 if (!aRangeApply) { 87 ok(!aElement.matches(":in-range"), ":in-range should not match"); 88 ok(!aElement.matches(":out-of-range"), 89 ":out-of-range should not match"); 90 } else { 91 is(aElement.matches(":in-range"), aValidity, 92 ":in-range matches status should be " + aValidity); 93 is(aElement.matches(":out-of-range"), !aValidity, 94 ":out-of-range matches status should be " + !aValidity); 95 } 96 } 97 98 for (var test of data) { 99 input.type = test.type; 100 var apply = test.apply; 101 102 if (test.todo) { 103 todo_is(input.type, test.type, test.type + " isn't implemented yet"); 104 continue; 105 } 106 107 // The element should be valid. Range should not apply when @min and @max are 108 // undefined, except if the input type is 'range' (since that type has a 109 // default minimum and maximum). 110 if (input.type == 'range') { 111 checkValidity(input, true, apply, true); 112 } else { 113 checkValidity(input, true, apply, false); 114 } 115 116 switch (input.type) { 117 case 'hidden': 118 case 'text': 119 case 'search': 120 case 'password': 121 case 'url': 122 case 'tel': 123 case 'email': 124 case 'number': 125 case 'checkbox': 126 case 'radio': 127 case 'file': 128 case 'submit': 129 case 'reset': 130 case 'button': 131 case 'image': 132 case 'color': 133 input.min = '999'; 134 break; 135 case 'date': 136 input.min = '2012-06-27'; 137 break; 138 case 'time': 139 input.min = '20:20'; 140 break; 141 case 'range': 142 // range is special, since setting min to 999 will make it invalid since 143 // it's default maximum is 100, its value would be 999, and it would 144 // suffer from overflow. 145 break; 146 case 'month': 147 input.min = '2016-06'; 148 break; 149 case 'week': 150 input.min = '2016-W39'; 151 break; 152 case 'datetime-local': 153 input.min = '2017-01-01T00:00'; 154 break; 155 default: 156 ok(false, 'please, add a case for this new type (' + input.type + ')'); 157 } 158 159 // The element should still be valid and range should apply if it can. 160 checkValidity(input, true, apply, apply); 161 162 switch (input.type) { 163 case 'text': 164 case 'hidden': 165 case 'search': 166 case 'password': 167 case 'tel': 168 case 'radio': 169 case 'checkbox': 170 case 'reset': 171 case 'button': 172 case 'submit': 173 case 'image': 174 case 'color': 175 input.value = '0'; 176 checkValidity(input, true, apply, apply); 177 break; 178 case 'url': 179 input.value = 'http://mozilla.org'; 180 checkValidity(input, true, apply, apply); 181 break; 182 case 'email': 183 input.value = 'foo@bar.com'; 184 checkValidity(input, true, apply, apply); 185 break; 186 case 'file': 187 var file = new File([''], '635499_file'); 188 189 SpecialPowers.wrap(input).mozSetFileArray([file]); 190 checkValidity(input, true, apply, apply); 191 192 break; 193 case 'date': 194 input.value = '2012-06-28'; 195 checkValidity(input, true, apply, apply); 196 197 input.value = '2012-06-27'; 198 checkValidity(input, true, apply, apply); 199 200 input.value = 'foo'; 201 checkValidity(input, true, apply, apply); 202 203 input.value = '2012-06-26'; 204 checkValidity(input, false, apply, apply); 205 206 input.min = '2012-02-29'; 207 checkValidity(input, true, apply, apply); 208 209 input.value = '2012-02-28'; 210 checkValidity(input, false, apply, apply); 211 212 input.value = '1000-01-01'; 213 checkValidity(input, false, apply, apply); 214 215 input.value = '20120-01-01'; 216 checkValidity(input, true, apply, apply); 217 218 input.min = '0050-01-01'; 219 checkValidity(input, true, apply, apply); 220 221 input.value = '0049-01-01'; 222 checkValidity(input, false, apply, apply); 223 224 input.min = ''; 225 checkValidity(input, true, apply, false); 226 227 input.min = 'foo'; 228 checkValidity(input, true, apply, false); 229 break; 230 case 'number': 231 input.min = '0'; 232 input.value = '1'; 233 checkValidity(input, true, apply, apply); 234 235 input.value = '0'; 236 checkValidity(input, true, apply, apply); 237 238 input.value = 'foo'; 239 checkValidity(input, true, apply, apply); 240 241 input.value = '-1'; 242 checkValidity(input, false, apply, apply); 243 244 input.min = '-1'; 245 checkValidity(input, true, apply, apply); 246 247 input.value = '-42'; 248 checkValidity(input, false, apply, apply); 249 250 input.min = ''; 251 checkValidity(input, true, apply, false); 252 253 input.min = 'foo'; 254 checkValidity(input, true, apply, false); 255 256 // Check that we correctly convert input.min to a double in 257 // validationMessage. 258 input.min = "4.333333333333333333333333333333333331"; 259 input.value = "2"; 260 is(input.validationMessage, 261 "Please select a value that is no less than 4.33333333333333.", 262 "validation message"); 263 break; 264 case 'range': 265 input.min = '0'; 266 input.value = '1'; 267 checkValidity(input, true, apply, apply); 268 269 input.value = '0'; 270 checkValidity(input, true, apply, apply); 271 272 input.value = 'foo'; 273 checkValidity(input, true, apply, apply); 274 275 input.value = '-1'; 276 checkValidity(input, true, apply, apply); 277 278 is(input.value, input.min, "the value should have been set to min"); 279 280 input.min = '-1'; 281 checkValidity(input, true, apply, apply); 282 283 input.value = '-42'; 284 checkValidity(input, true, apply, apply); 285 286 is(input.value, input.min, "the value should have been set to min"); 287 288 input.min = ''; 289 checkValidity(input, true, apply, true); 290 291 input.min = 'foo'; 292 checkValidity(input, true, apply, true); 293 294 // We don't check the conversion of input.min to a double in 295 // validationMessage for 'range' since range will always clamp the value 296 // up to at least the minimum (so we will never see the min in a 297 // validationMessage). 298 299 break; 300 case 'time': 301 // Don't worry about that. 302 input.step = 'any'; 303 304 input.min = '20:20'; 305 input.value = '20:20:01'; 306 checkValidity(input, true, apply, apply); 307 308 input.value = '20:20:00'; 309 checkValidity(input, true, apply, apply); 310 311 input.value = 'foo'; 312 checkValidity(input, true, apply, apply); 313 314 input.value = '10:00'; 315 checkValidity(input, false, apply, apply); 316 317 input.min = '20:20:00.001'; 318 input.value = '20:20'; 319 checkValidity(input, false, apply, apply); 320 321 input.value = '00:00'; 322 checkValidity(input, false, apply, apply); 323 324 input.value = '23:59'; 325 checkValidity(input, true, apply, apply); 326 327 input.value = '20:20:01'; 328 checkValidity(input, true, apply, apply); 329 330 input.value = '20:20:00.01'; 331 checkValidity(input, true, apply, apply); 332 333 input.value = '20:20:00.1'; 334 checkValidity(input, true, apply, apply); 335 336 input.min = '00:00:00'; 337 input.value = '01:00'; 338 checkValidity(input, true, apply, apply); 339 340 input.value = '00:00:00.000'; 341 checkValidity(input, true, apply, apply); 342 343 input.min = ''; 344 checkValidity(input, true, apply, false); 345 346 input.min = 'foo'; 347 checkValidity(input, true, apply, false); 348 break; 349 case 'month': 350 input.value = '2016-07'; 351 checkValidity(input, true, apply, apply); 352 353 input.value = '2016-06'; 354 checkValidity(input, true, apply, apply); 355 356 input.value = 'foo'; 357 checkValidity(input, true, apply, apply); 358 359 input.value = '2016-05'; 360 checkValidity(input, false, apply, apply); 361 362 input.min = '2016-01'; 363 checkValidity(input, true, apply, apply); 364 365 input.value = '2015-12'; 366 checkValidity(input, false, apply, apply); 367 368 input.value = '1000-01'; 369 checkValidity(input, false, apply, apply); 370 371 input.value = '10000-01'; 372 checkValidity(input, true, apply, apply); 373 374 input.min = '0010-01'; 375 checkValidity(input, true, apply, apply); 376 377 input.value = '0001-01'; 378 checkValidity(input, false, apply, apply); 379 380 input.min = ''; 381 checkValidity(input, true, apply, false); 382 383 input.min = 'foo'; 384 checkValidity(input, true, apply, false); 385 break; 386 case 'week': 387 input.value = '2016-W40'; 388 checkValidity(input, true, apply, apply); 389 390 input.value = '2016-W39'; 391 checkValidity(input, true, apply, apply); 392 393 input.value = 'foo'; 394 checkValidity(input, true, apply, apply); 395 396 input.value = '2016-W38'; 397 checkValidity(input, false, apply, apply); 398 399 input.min = '2016-W01'; 400 checkValidity(input, true, apply, apply); 401 402 input.value = '2015-W53'; 403 checkValidity(input, false, apply, apply); 404 405 input.value = '1000-W01'; 406 checkValidity(input, false, apply, apply); 407 408 input.value = '10000-01'; 409 checkValidity(input, true, apply, apply); 410 411 input.min = '0010-W01'; 412 checkValidity(input, true, apply, apply); 413 414 input.value = '0001-W01'; 415 checkValidity(input, false, apply, apply); 416 417 input.min = ''; 418 checkValidity(input, true, apply, false); 419 420 input.min = 'foo'; 421 checkValidity(input, true, apply, false); 422 break; 423 case 'datetime-local': 424 input.value = '2017-12-31T23:59'; 425 checkValidity(input, true, apply, apply); 426 427 input.value = '2017-01-01T00:00'; 428 checkValidity(input, true, apply, apply); 429 430 input.value = '2017-01-01T00:00:00.123'; 431 checkValidity(input, true, apply, apply); 432 433 input.value = 'foo'; 434 checkValidity(input, true, apply, apply); 435 436 input.value = '2016-12-31T23:59'; 437 checkValidity(input, false, apply, apply); 438 439 input.min = '2016-01-01T00:00'; 440 checkValidity(input, true, apply, apply); 441 442 input.value = '2015-12-31T23:59'; 443 checkValidity(input, false, apply, apply); 444 445 input.value = '1000-01-01T00:00'; 446 checkValidity(input, false, apply, apply); 447 448 input.value = '10000-01-01T00:00'; 449 checkValidity(input, true, apply, apply); 450 451 input.min = '0010-01-01T12:00'; 452 checkValidity(input, true, apply, apply); 453 454 input.value = '0010-01-01T10:00'; 455 checkValidity(input, false, apply, apply); 456 457 input.min = ''; 458 checkValidity(input, true, apply, false); 459 460 input.min = 'foo'; 461 checkValidity(input, true, apply, false); 462 break; 463 default: 464 ok(false, 'write tests for ' + input.type); 465 } 466 467 // Cleaning up, 468 input.removeAttribute('min'); 469 input.value = ''; 470 } 471 472 </script> 473 </pre> 474 </body> 475 </html>