diff options
Diffstat (limited to 'testing/web-platform/tests/html/semantics/forms/constraints/support')
-rw-r--r-- | testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js b/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js new file mode 100644 index 0000000000..aa43b3a2f6 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js @@ -0,0 +1,481 @@ +var validator = { + + test_tooLong: function(ctl, data) { + var self = this; + test(function() { + self.pre_check(ctl, 'tooLong'); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.tooLong, + 'The validity.tooLong should be true' + condStr); + else + assert_false( + ctl.validity.tooLong, + 'The validity.tooLong should be false' + condStr); + }); + }, data.name); + }, + + test_tooShort: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "tooShort"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.tooShort, + 'The validity.tooShort should be true' + condStr); + else + assert_false( + ctl.validity.tooShort, + 'The validity.tooShort should be false' + condStr); + }); + }, data.name); + }, + + test_patternMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "patternMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.patternMismatch, + 'The validity.patternMismatch should be true' + condStr); + else + assert_false( + ctl.validity.patternMismatch, + 'The validity.patternMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_valueMissing: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "valueMissing"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.valueMissing, + 'The validity.valueMissing should be true' + condStr); + else + assert_false( + ctl.validity.valueMissing, + 'The validity.valueMissing should be false' + condStr); + }); + }, data.name); + }, + + test_typeMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "typeMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.typeMismatch, + 'The validity.typeMismatch should be true' + condStr); + else + assert_false( + ctl.validity.typeMismatch, + 'The validity.typeMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_rangeOverflow: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "rangeOverflow"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.rangeOverflow, + 'The validity.rangeOverflow should be true' + condStr); + else + assert_false( + ctl.validity.rangeOverflow, + 'The validity.rangeOverflow should be false' + condStr); + }); + }, data.name); + }, + + test_rangeUnderflow: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "rangeUnderflow"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.rangeUnderflow, + 'The validity.rangeUnderflow should be true' + condStr); + else + assert_false( + ctl.validity.rangeUnderflow, + 'The validity.rangeUnderflow should be false' + condStr); + }); + }, data.name); + }, + + test_stepMismatch: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "stepMismatch"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.stepMismatch, + 'The validity.stepMismatch should be true' + condStr); + else + assert_false( + ctl.validity.stepMismatch, + 'The validity.stepMismatch should be false' + condStr); + }); + }, data.name); + }, + + test_badInput: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "badInput"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.badInput, + 'The validity.badInput should be true' + condStr); + else + assert_false( + ctl.validity.badInput, + 'The validity.badInput should be false' + condStr); + }); + }, data.name); + }, + + test_customError: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "customError"); + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) { + assert_true( + ctl.validity.customError, + 'The validity.customError attribute should be true' + condStr); + // validationMessage returns the empty string if ctl is barred from + // constraint validation, which happens if ctl is disabled or readOnly. + if (ctl.disabled || ctl.readOnly) { + assert_equals( + ctl.validationMessage, '', + 'The validationMessage attribute must be empty' + condStr); + } else { + assert_equals( + ctl.validationMessage, data.conditions.message, + 'The validationMessage attribute should be \'' + + data.conditions.message + '\'' + condStr); + } + } else { + assert_false( + ctl.validity.customError, + 'The validity.customError attribute should be false' + condStr); + assert_equals( + ctl.validationMessage, '', + 'The validationMessage attribute must be empty' + condStr); + } + }); + }, data.name); + }, + + test_isValid: function(ctl, data) { + var self = this; + test(function () { + self.iterate_over(ctl, data).forEach(function(val) { + const {ctl, expected, condStr} = val; + if (expected) + assert_true( + ctl.validity.valid, + 'The validity.valid should be true' + condStr); + else + assert_false( + ctl.validity.valid, + 'The validity.valid should be false' + condStr); + }); + }, data.name); + }, + + test_willValidate: function(ctl, data) { + var self = this; + test(function () { + self.pre_check(ctl, "willValidate"); + self.set_conditions(ctl, data.conditions); + if (data.ancestor) { + var dl = document.createElement("datalist"); + dl.appendChild(ctl); + } + + if (data.expected) + assert_true(ctl.willValidate, "The willValidate attribute should be true."); + else + assert_false(ctl.willValidate, "The willValidate attribute should be false."); + }, data.name); + }, + + test_checkValidity: function(ctl, data) { + var self = this; + test(function () { + var eventFired = false; + self.pre_check(ctl, "checkValidity"); + self.set_conditions(ctl, data.conditions); + if (data.dirty) + self.set_dirty(ctl); + + on_event(ctl, "invalid", function(e){ + assert_equals(e.type, "invalid", "The invalid event should be fired."); + eventFired = true; + }); + + if (data.expected) { + assert_true(ctl.checkValidity(), "The checkValidity method should be true."); + assert_false(eventFired, "The invalid event should not be fired."); + } else { + assert_false(ctl.checkValidity(), "The checkValidity method should be false."); + assert_true(eventFired, "The invalid event should be fired."); + } + }, data.name); + + test(function () { + var fm = document.createElement("form"); + var ctl2 = ctl.cloneNode(true); + + self.pre_check(ctl, "checkValidity"); + self.set_conditions(ctl2, data.conditions); + fm.appendChild(ctl2); + document.body.appendChild(fm); + if (data.dirty) + self.set_dirty(ctl2); + + var result = fm.checkValidity(); + document.body.removeChild(fm); + + if (data.expected) + assert_true(result, "The checkValidity method of the element's form owner should return true."); + else + assert_false(result, "The checkValidity method of the element's form owner should return false."); + }, data.name + " (in a form)"); + }, + + test_reportValidity: function(ctl, data) { + var self = this; + test(function () { + var eventFired = false; + + self.pre_check(ctl, "reportValidity"); + self.set_conditions(ctl, data.conditions); + if (data.dirty) + self.set_dirty(ctl); + + on_event(ctl, "invalid", function(e){ + assert_equals(e.type, "invalid", "The invalid event should be fired."); + eventFired = true; + }); + + if (data.expected) { + assert_true(ctl.reportValidity(), "The reportValidity method should be true."); + assert_false(eventFired, "The invalid event should not be fired."); + } else { + assert_false(ctl.reportValidity(), "The reportValidity method should be false."); + assert_true(eventFired, "The invalid event should be fired."); + } + }, data.name); + + test(function () { + var fm = document.createElement("form"); + var ctl2 = ctl.cloneNode(true); + + self.pre_check(ctl, "reportValidity"); + self.set_conditions(ctl2, data.conditions); + fm.appendChild(ctl2); + document.body.appendChild(fm); + if (data.dirty) + self.set_dirty(ctl2); + + var result = fm.reportValidity(); + document.body.removeChild(fm); + + if (data.expected) + assert_true(result, "The reportValidity method of the element's form owner should return true."); + else + assert_false(result, "The reportValidity method of the element's form owner should return false."); + }, data.name + " (in a form)"); + }, + + set_conditions: function(ctl, obj) { + [ + "checked", + "disabled", + "max", + "maxlength", + "min", + "minlength", + "multiple", + "pattern", + "readonly", + "required", + "selected", + "step", + "value" + ].forEach(function(item) { + ctl.removeAttribute(item); + }); + for (var attr in obj) { + if (attr === "message") + ctl.setCustomValidity(obj[attr]); + else if (attr === "checked" || obj[attr] || obj[attr] === "") + ctl[attr] = obj[attr]; + } + }, + + set_dirty: function(ctl) { + ctl.focus(); + var old_value = ctl.value; + ctl.value = "a"; + ctl.value = old_value; + }, + + pre_check: function(ctl, item) { + switch (item) { + case "willValidate": + assert_true(item in ctl, "The " + item + " attribute doesn't exist."); + break; + case "checkValidity": + case "reportValidity": + assert_true(item in ctl, "The " + item + " method doesn't exist."); + break; + case "tooLong": + case "tooShort": + case "patternMismatch": + case "typeMismatch": + case "stepMismatch": + case "rangeOverflow": + case "rangeUnderflow": + case "valueMissing": + case "badInput": + case "valid": + assert_true("validity" in ctl, "The validity attribute doesn't exist."); + assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist."); + break; + case "customError": + assert_true("validity" in ctl, "The validity attribute doesn't exist."); + assert_true("setCustomValidity" in ctl, "The validity attribute doesn't exist."); + assert_true("validationMessage" in ctl, "The validity attribute doesn't exist."); + assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist."); + break; + } + }, + + iterate_over: function(ctl, data) { + // Iterate over normal, disabled, readonly, and both (if applicable). + var ctlNormal = ctl.cloneNode(true); + this.set_conditions(ctlNormal, data.conditions); + if (data.dirty) + this.set_dirty(ctlNormal); + + var ctlDisabled = ctl.cloneNode(true); + this.set_conditions(ctlDisabled, data.conditions); + if (data.dirty) + this.set_dirty(ctlDisabled); + ctlDisabled.disabled = true; + + var expectedImmutable = + data.expectedImmutable !== undefined ? data.expectedImmutable : data.expected; + + var variants = [ + {ctl: ctlNormal, expected: data.expected, condStr: '.'}, + {ctl: ctlDisabled, expected: expectedImmutable, condStr: ', when control is disabled.'}, + ]; + + if ('readOnly' in ctl) { + var ctlReadonly = ctl.cloneNode(true); + this.set_conditions(ctlReadonly, data.conditions); + if (data.dirty) + this.set_dirty(ctlReadonly); + ctlReadonly.readOnly = true; + + var ctlBoth = ctl.cloneNode(true); + this.set_conditions(ctlBoth, data.conditions); + if (data.dirty) + this.set_dirty(ctlBoth); + ctlBoth.disabled = true; + ctlBoth.readOnly = true; + + variants.push({ + ctl: ctlReadonly, + expected: expectedImmutable, + condStr: ', when control is readonly.' + }); + + variants.push({ + ctl: ctlBoth, + expected: expectedImmutable, + condStr: ', when control is disabled & readonly.' + }); + } + + return variants; + }, + + run_test: function(testee, method) { + var testMethod = "test_" + method; + if (typeof this[testMethod] !== "function") { + return false; + } + + var ele = null, + prefix = ""; + + for (var i = 0; i < testee.length; i++) { + if (testee[i].types.length > 0) { + for (var typ in testee[i].types) { + ele = document.createElement(testee[i].tag); + document.body.appendChild(ele); + try { + ele.type = testee[i].types[typ]; + } catch (e) { + //Do nothing, avoid the runtime error breaking the test + } + + prefix = "[" + testee[i].tag.toUpperCase() + " in " + testee[i].types[typ].toUpperCase() + " status] "; + + for (var j = 0; j < testee[i].testData.length; j++) { + testee[i].testData[j].name = testee[i].testData[j].name.replace(/\[.*\]\s/g, prefix); + this[testMethod](ele, testee[i].testData[j]); + } + } + } else { + ele = document.createElement(testee[i].tag); + document.body.appendChild(ele); + prefix = "[" + testee[i].tag + "] "; + + if (testElements[i].tag === "select") { + ele.add(new Option('test1', '')); // Placeholder + ele.add(new Option("test2", 1)); + } + + for (var item in testee[i].testData) { + testee[i].testData[item].name = testee[i].testData[item].name.replace("[target]", prefix); + this[testMethod](ele, testee[i].testData[item]); + } + } + } + } +} |