From 1f3656e0dcdd59c323a9ab7d9b962e42250f0aa3 Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Mon, 14 Jan 2013 13:22:54 +0200 Subject: [PATCH] Most validators should accept null or empty string (#10561, #10713). Change-Id: I1e8d6015aefdc184af6383cb22cdf3e13be351cf --- .../vaadin/data/validator/EmailValidator.java | 21 +-- .../vaadin/data/validator/RangeValidator.java | 3 +- .../data/validator/RegexpValidator.java | 8 + .../data/validator/TestRegexpValidator.java | 44 +++++ .../TextFieldWithConverterAndValidator.java | 53 ++++++ .../textfield/TextFieldWithValidator.java | 172 ++++++++++++++++++ 6 files changed, 285 insertions(+), 16 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/data/validator/TestRegexpValidator.java create mode 100644 server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidator.java create mode 100644 server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithValidator.java diff --git a/server/src/com/vaadin/data/validator/EmailValidator.java b/server/src/com/vaadin/data/validator/EmailValidator.java index 2217b3cf2c..aa7a921d51 100644 --- a/server/src/com/vaadin/data/validator/EmailValidator.java +++ b/server/src/com/vaadin/data/validator/EmailValidator.java @@ -23,6 +23,12 @@ package com.vaadin.data.validator; * See {@link com.vaadin.data.validator.AbstractStringValidator} for more * information. * + *

+ * An empty string or a null is always accepted - use the required flag on + * fields or a separate validator (or override {@link #isValidValue(String)}) to + * fail on empty values. + *

+ * * @author Vaadin Ltd. * @since 5.4 */ @@ -41,19 +47,4 @@ public class EmailValidator extends RegexpValidator { "^([a-zA-Z0-9_\\.\\-+])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$", true, errorMessage); } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object - * ) - */ - @Override - protected boolean isValidValue(String value) { - if (value == null || value.isEmpty()) { - return true; - } - return super.isValidValue(value); - } } diff --git a/server/src/com/vaadin/data/validator/RangeValidator.java b/server/src/com/vaadin/data/validator/RangeValidator.java index d92e259cf6..5e82a37b51 100644 --- a/server/src/com/vaadin/data/validator/RangeValidator.java +++ b/server/src/com/vaadin/data/validator/RangeValidator.java @@ -154,7 +154,8 @@ public class RangeValidator extends AbstractValidator { */ @Override protected boolean isValidValue(T value) { - if (value == null) { + if (value == null + || (String.class.equals(getType()) && "".equals(value))) { return true; } diff --git a/server/src/com/vaadin/data/validator/RegexpValidator.java b/server/src/com/vaadin/data/validator/RegexpValidator.java index ea659fcfe2..f85bce9281 100644 --- a/server/src/com/vaadin/data/validator/RegexpValidator.java +++ b/server/src/com/vaadin/data/validator/RegexpValidator.java @@ -30,6 +30,11 @@ import java.util.regex.Pattern; * See {@link com.vaadin.data.validator.AbstractStringValidator} for more * information. *

+ *

+ * An empty string or a null is always accepted - use the required flag on + * fields or a separate validator (or override {@link #isValidValue(String)}) to + * fail on empty values. + *

* * @author Vaadin Ltd. * @since 5.4 @@ -81,6 +86,9 @@ public class RegexpValidator extends AbstractStringValidator { */ @Override protected boolean isValidValue(String value) { + if (value == null || value.isEmpty()) { + return true; + } if (complete) { return getMatcher(value).matches(); } else { diff --git a/server/tests/src/com/vaadin/tests/data/validator/TestRegexpValidator.java b/server/tests/src/com/vaadin/tests/data/validator/TestRegexpValidator.java new file mode 100644 index 0000000000..bcff224451 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/data/validator/TestRegexpValidator.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.data.validator; + +import junit.framework.TestCase; + +import com.vaadin.data.validator.RegexpValidator; + +public class TestRegexpValidator extends TestCase { + + private RegexpValidator completeValidator = new RegexpValidator("pattern", + true, "Complete match validator error"); + private RegexpValidator partialValidator = new RegexpValidator("pattern", + false, "Partial match validator error"); + + public void testRegexpValidatorWithNull() { + assertTrue(completeValidator.isValid(null)); + assertTrue(partialValidator.isValid(null)); + } + + public void testRegexpValidatorWithEmptyString() { + assertTrue(completeValidator.isValid("")); + assertTrue(partialValidator.isValid("")); + } + + public void testCompleteRegexpValidatorWithFaultyString() { + assertFalse(completeValidator.isValid("mismatch")); + assertFalse(completeValidator.isValid("pattern2")); + assertFalse(completeValidator.isValid("1pattern")); + } + + public void testCompleteRegexpValidatorWithOkString() { + assertTrue(completeValidator.isValid("pattern")); + } + + public void testPartialRegexpValidatorWithFaultyString() { + assertFalse(partialValidator.isValid("mismatch")); + } + + public void testPartialRegexpValidatorWithOkString() { + assertTrue(partialValidator.isValid("pattern")); + assertTrue(partialValidator.isValid("1pattern")); + assertTrue(partialValidator.isValid("pattern2")); + assertTrue(partialValidator.isValid("1pattern2")); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidator.java b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidator.java new file mode 100644 index 0000000000..89d21728e4 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithConverterAndValidator.java @@ -0,0 +1,53 @@ +package com.vaadin.tests.server.component.textfield; + +import junit.framework.TestCase; + +import com.vaadin.data.Validator.InvalidValueException; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.validator.RangeValidator; +import com.vaadin.tests.data.converter.ConverterFactory.ConvertTo42; +import com.vaadin.ui.TextField; + +public class TextFieldWithConverterAndValidator extends TestCase { + + private TextField field; + private ObjectProperty property; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + field = new TextField(); + field.setInvalidAllowed(false); + } + + public void testConvert42AndValidator() { + property = new ObjectProperty(123); + field.setConverter(new ConvertTo42()); + field.setPropertyDataSource(property); + + field.addValidator(new RangeValidator("Incorrect value", + Integer.class, 42, 42)); + + // succeeds + field.setValue("a"); + // succeeds + field.setValue("42"); + // succeeds - no validation + property.setValue(42); + + // nulls + + // fails + try { + property.setValue(null); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue(null); + } + + // TODO test converter changing value to null with validator +} diff --git a/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithValidator.java b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithValidator.java new file mode 100644 index 0000000000..2a79d1fe27 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/textfield/TextFieldWithValidator.java @@ -0,0 +1,172 @@ +package com.vaadin.tests.server.component.textfield; + +import junit.framework.TestCase; + +import com.vaadin.data.Validator; +import com.vaadin.data.Validator.InvalidValueException; +import com.vaadin.data.util.ObjectProperty; +import com.vaadin.data.validator.EmailValidator; +import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.data.validator.StringLengthValidator; +import com.vaadin.ui.TextField; + +public class TextFieldWithValidator extends TestCase { + + private TextField field; + private ObjectProperty property; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + field = new TextField(); + field.setInvalidAllowed(false); + property = new ObjectProperty("original"); + field.setPropertyDataSource(property); + } + + public void testMultipleValidators() { + field.addValidator(new StringLengthValidator( + "Length not between 1 and 3", 1, 3, false)); + field.addValidator(new StringLengthValidator( + "Length not between 2 and 4", 2, 4, false)); + + // fails + try { + field.setValue("a"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("ab"); + // fails + try { + field.setValue("abcd"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + + public void testRemoveValidator() { + Validator validator1 = new StringLengthValidator( + "Length not between 1 and 3", 1, 3, false); + Validator validator2 = new StringLengthValidator( + "Length not between 2 and 4", 2, 4, false); + + field.addValidator(validator1); + field.addValidator(validator2); + field.removeValidator(validator1); + + // fails + try { + field.setValue("a"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("ab"); + // succeeds + field.setValue("abcd"); + } + + public void testRemoveAllValidators() { + Validator validator1 = new StringLengthValidator( + "Length not between 1 and 3", 1, 3, false); + Validator validator2 = new StringLengthValidator( + "Length not between 2 and 4", 2, 4, false); + + field.addValidator(validator1); + field.addValidator(validator2); + field.removeAllValidators(); + + // all should succeed now + field.setValue("a"); + field.setValue("ab"); + field.setValue("abcd"); + } + + public void testEmailValidator() { + field.addValidator(new EmailValidator("Invalid e-mail address")); + + // not required + + field.setRequired(false); + // succeeds + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue("test@example.com"); + // fails + try { + field.setValue("invalid e-mail"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + + // required + + field.setRequired(true); + // fails + try { + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // fails + try { + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + fail(); + } catch (InvalidValueException e) { + // should fail + } + // succeeds + field.setValue("test@example.com"); + // fails + try { + field.setValue("invalid e-mail"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + + public void testRegexpValidator() { + field.addValidator(new RegexpValidator("pattern", true, + "Validation failed")); + field.setRequired(false); + + // succeeds + field.setValue(""); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue(null); + // needed as required flag not checked by setValue() + field.validate(); + // succeeds + field.setValue("pattern"); + + // fails + try { + field.setValue("mismatch"); + fail(); + } catch (InvalidValueException e) { + // should fail + } + } + +} -- 2.39.5