Change-Id: I2ac99adf1fdb60dc0638e6fe98c4542ebd5f21a5tags/8.0.0.alpha6
@Override | @Override | ||||
public Result<T> convertToModel(T value, ValueContext context) { | public Result<T> convertToModel(T value, ValueContext context) { | ||||
Result<? super T> validationResult = validator.apply(value); | |||||
Result<? super T> validationResult = validator.apply(value, | |||||
context); | |||||
if (validationResult.isError()) { | if (validationResult.isError()) { | ||||
return Result.error(validationResult.getMessage().get()); | return Result.error(validationResult.getMessage().get()); | ||||
} else { | } else { | ||||
return this; | return this; | ||||
} | } | ||||
/** | |||||
* A convenience method to add a validator to this binder using the | |||||
* {@link Validator#from(SerializablePredicate, String)} factory method. | |||||
* <p> | |||||
* Bean level validators are applied on the bean instance after the bean is | |||||
* updated. If the validators fail, the bean instance is reverted to its | |||||
* previous state. | |||||
* | |||||
* @see #save(Object) | |||||
* @see #saveIfValid(Object) | |||||
* | |||||
* @param predicate | |||||
* the predicate performing validation, not null | |||||
* @param message | |||||
* the error message to report in case validation failure | |||||
* @return this binder, for chaining | |||||
*/ | |||||
public Binder<BEAN> withValidator(SerializablePredicate<BEAN> predicate, | |||||
String message) { | |||||
return withValidator(Validator.from(predicate, message)); | |||||
} | |||||
/** | /** | ||||
* Validates the values of all bound fields and returns the validation | * Validates the values of all bound fields and returns the validation | ||||
* status. | * status. | ||||
*/ | */ | ||||
private List<Result<?>> validateBean(BEAN bean) { | private List<Result<?>> validateBean(BEAN bean) { | ||||
Objects.requireNonNull(bean, "bean cannot be null"); | Objects.requireNonNull(bean, "bean cannot be null"); | ||||
List<Result<?>> results = Collections.unmodifiableList( | |||||
validators.stream().map(validator -> validator.apply(bean)) | |||||
.collect(Collectors.toList())); | |||||
List<Result<?>> results = Collections.unmodifiableList(validators | |||||
.stream() | |||||
.map(validator -> validator.apply(bean, new ValueContext())) | |||||
.collect(Collectors.toList())); | |||||
return results; | return results; | ||||
} | } | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.Objects; | import java.util.Objects; | ||||
import java.util.function.Function; | |||||
import java.util.function.Predicate; | |||||
import java.util.function.BiFunction; | |||||
import com.vaadin.data.util.converter.ValueContext; | |||||
import com.vaadin.server.SerializablePredicate; | import com.vaadin.server.SerializablePredicate; | ||||
/** | /** | ||||
* @see Result | * @see Result | ||||
*/ | */ | ||||
@FunctionalInterface | @FunctionalInterface | ||||
public interface Validator<T> extends Function<T, Result<T>>, Serializable { | |||||
/** | |||||
* Returns a validator that chains this validator with the given function. | |||||
* Specifically, the function may be another validator. The resulting | |||||
* validator first applies this validator, and if the value passes, then the | |||||
* given validator. | |||||
* <p> | |||||
* For instance, the following chained validator checks if a number is | |||||
* between 0 and 10, inclusive: | |||||
* | |||||
* <pre> | |||||
* Validator<Integer> v = Validator.from(num -> num >= 0, "number must be >= 0") | |||||
* .chain(Validator.from(num -> num <= 10, "number must be <= 10")); | |||||
* </pre> | |||||
* | |||||
* @param next | |||||
* the validator to apply next, not null | |||||
* @return a chained validator | |||||
* | |||||
* @see #from(Predicate, String) | |||||
*/ | |||||
public default Validator<T> chain(Function<T, Result<T>> next) { | |||||
Objects.requireNonNull(next, "next cannot be null"); | |||||
return val -> apply(val).flatMap(next); | |||||
} | |||||
public interface Validator<T> | |||||
extends BiFunction<T, ValueContext, Result<T>>, Serializable { | |||||
/** | /** | ||||
* Validates the given value. Returns a {@code Result} instance representing | * Validates the given value. Returns a {@code Result} instance representing | ||||
* | * | ||||
* @param value | * @param value | ||||
* the input value to validate | * the input value to validate | ||||
* @param context | |||||
* the value context for validation | |||||
* @return the validation result | * @return the validation result | ||||
*/ | */ | ||||
@Override | @Override | ||||
public Result<T> apply(T value); | |||||
public Result<T> apply(T value, ValueContext context); | |||||
/** | /** | ||||
* Returns a validator that passes any value. | * Returns a validator that passes any value. | ||||
* @return an always-passing validator | * @return an always-passing validator | ||||
*/ | */ | ||||
public static <T> Validator<T> alwaysPass() { | public static <T> Validator<T> alwaysPass() { | ||||
return v -> Result.ok(v); | |||||
return (v, ctx) -> Result.ok(v); | |||||
} | } | ||||
/** | /** | ||||
String errorMessage) { | String errorMessage) { | ||||
Objects.requireNonNull(guard, "guard cannot be null"); | Objects.requireNonNull(guard, "guard cannot be null"); | ||||
Objects.requireNonNull(errorMessage, "errorMessage cannot be null"); | Objects.requireNonNull(errorMessage, "errorMessage cannot be null"); | ||||
return value -> { | |||||
return (value, context) -> { | |||||
try { | try { | ||||
if (guard.test(value)) { | if (guard.test(value)) { | ||||
return Result.ok(value); | return Result.ok(value); |
* Constructor for {@code ValueContext} without a {@code Locale}. | * Constructor for {@code ValueContext} without a {@code Locale}. | ||||
*/ | */ | ||||
public ValueContext() { | public ValueContext() { | ||||
this.locale = null; | |||||
this.component = null; | this.component = null; | ||||
this.locale = findLocale(); | |||||
} | } | ||||
/** | /** |
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.Validator; | import com.vaadin.data.Validator; | ||||
import com.vaadin.data.util.BeanUtil; | import com.vaadin.data.util.BeanUtil; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* A {@code Validator} using the JSR-303 (javax.validation) annotation-based | * A {@code Validator} using the JSR-303 (javax.validation) annotation-based | ||||
* annotation or equivalent. | * annotation or equivalent. | ||||
*/ | */ | ||||
@Override | @Override | ||||
public Result<Object> apply(final Object value) { | |||||
public Result<Object> apply(final Object value, ValueContext context) { | |||||
Set<? extends ConstraintViolation<?>> violations = getJavaxBeanValidator() | Set<? extends ConstraintViolation<?>> violations = getJavaxBeanValidator() | ||||
.validateValue(beanType, propertyName, value); | .validateValue(beanType, propertyName, value); | ||||
import com.vaadin.data.HasRequired; | import com.vaadin.data.HasRequired; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.Validator; | import com.vaadin.data.Validator; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* Simple validator to check against {@code null} value and empty {@link String} | * Simple validator to check against {@code null} value and empty {@link String} | ||||
} | } | ||||
@Override | @Override | ||||
public Result<T> apply(T value) { | |||||
public Result<T> apply(T value, ValueContext context) { | |||||
if (Objects.isNull(value) || Objects.equals(value, "")) { | if (Objects.isNull(value) || Objects.equals(value, "")) { | ||||
return Result.error(message); | return Result.error(message); | ||||
} else { | } else { |
import java.util.Objects; | import java.util.Objects; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* This validator is used for validating properties that do not allow null | * This validator is used for validating properties that do not allow null | ||||
} | } | ||||
@Override | @Override | ||||
public Result<String> apply(String value) { | |||||
public Result<String> apply(String value, ValueContext context) { | |||||
return Objects.isNull(value) ? Result.error(getMessage(value)) | return Objects.isNull(value) ? Result.error(getMessage(value)) | ||||
: Result.ok(value); | : Result.ok(value); | ||||
} | } |
import java.util.Objects; | import java.util.Objects; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* Verifies that a value is within the given range. | * Verifies that a value is within the given range. | ||||
* behavior depends on the used comparator. | * behavior depends on the used comparator. | ||||
*/ | */ | ||||
@Override | @Override | ||||
public Result<T> apply(T value) { | |||||
public Result<T> apply(T value, ValueContext context) { | |||||
return toResult(value, isValid(value)); | return toResult(value, isValid(value)); | ||||
} | } | ||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* A string validator comparing the string against a Java regular expression. | * A string validator comparing the string against a Java regular expression. | ||||
} | } | ||||
@Override | @Override | ||||
public Result<String> apply(String value) { | |||||
public Result<String> apply(String value, ValueContext context) { | |||||
return toResult(value, isValid(value)); | return toResult(value, isValid(value)); | ||||
} | } | ||||
package com.vaadin.data.validator; | package com.vaadin.data.validator; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* Verifies that the length of a string is within the given range. | * Verifies that the length of a string is within the given range. | ||||
} | } | ||||
@Override | @Override | ||||
public Result<String> apply(String value) { | |||||
public Result<String> apply(String value, ValueContext context) { | |||||
if (value == null) { | if (value == null) { | ||||
return toResult(value, true); | return toResult(value, true); | ||||
} | } | ||||
Result<?> lengthCheck = validator.apply(value.length()); | |||||
Result<?> lengthCheck = validator.apply(value.length(), context); | |||||
return toResult(value, !lengthCheck.isError()); | return toResult(value, !lengthCheck.isError()); | ||||
} | } | ||||
import org.jsoup.nodes.Element; | import org.jsoup.nodes.Element; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
import com.vaadin.data.validator.DateRangeValidator; | import com.vaadin.data.validator.DateRangeValidator; | ||||
import com.vaadin.event.FieldEvents.BlurEvent; | import com.vaadin.event.FieldEvents.BlurEvent; | ||||
import com.vaadin.event.FieldEvents.BlurListener; | import com.vaadin.event.FieldEvents.BlurListener; | ||||
getDateOutOfRangeMessage(), | getDateOutOfRangeMessage(), | ||||
getDate(getRangeStart(), getResolution()), | getDate(getRangeStart(), getResolution()), | ||||
getDate(getRangeEnd(), getResolution())); | getDate(getRangeEnd(), getResolution())); | ||||
Result<LocalDate> result = validator.apply(value); | |||||
Result<LocalDate> result = validator.apply(value, | |||||
new ValueContext(this)); | |||||
if (result.isError()) { | if (result.isError()) { | ||||
setComponentError(new UserError(getDateOutOfRangeMessage())); | setComponentError(new UserError(getDateOutOfRangeMessage())); | ||||
} | } |
binder.forField(yearOfBirth) | binder.forField(yearOfBirth) | ||||
.withConverter(new StringToIntegerConverter("err")) | .withConverter(new StringToIntegerConverter("err")) | ||||
.bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); | .bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); | ||||
binder.withValidator(bean -> bean.yearOfBirth < 2000 ? Result.ok(bean) | |||||
: Result.error(message)) | |||||
.withValidator(bean -> bean.yearOfBirth == 2000 | |||||
? Result.error(message2) : Result.ok(bean)); | |||||
binder.withValidator(bean -> bean.yearOfBirth < 2000, message) | |||||
.withValidator(bean -> bean.yearOfBirth != 2000, message2); | |||||
binder.setBean(p); | binder.setBean(p); | ||||
BookPerson p = new BookPerson(1500, 12); | BookPerson p = new BookPerson(1500, 12); | ||||
binder.forField(yearOfBirth) | binder.forField(yearOfBirth) | ||||
.withConverter(new StringToIntegerConverter("err")) | .withConverter(new StringToIntegerConverter("err")) | ||||
.withValidator(value -> value % 2 == 0 ? Result.ok(value) | |||||
: Result.error(bindingMessage)) | |||||
.withValidator(value -> value % 2 == 0, bindingMessage) | |||||
.bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); | .bind(BookPerson::getYearOfBirth, BookPerson::setYearOfBirth); | ||||
binder.withValidator(bean -> bean.yearOfBirth < 2000 ? Result.ok(bean) | |||||
: Result.error(message)) | |||||
.withValidator(bean -> bean.yearOfBirth == 2000 | |||||
? Result.error(message2) : Result.ok(bean)); | |||||
binder.withValidator(bean -> bean.yearOfBirth < 2000, message) | |||||
.withValidator(bean -> bean.yearOfBirth != 2000, message2); | |||||
binder.setBean(p); | binder.setBean(p); | ||||
import com.vaadin.data.Binder.Binding; | import com.vaadin.data.Binder.Binding; | ||||
import com.vaadin.data.util.converter.StringToIntegerConverter; | import com.vaadin.data.util.converter.StringToIntegerConverter; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
import com.vaadin.data.validator.NotEmptyValidator; | import com.vaadin.data.validator.NotEmptyValidator; | ||||
import com.vaadin.server.AbstractErrorMessage; | import com.vaadin.server.AbstractErrorMessage; | ||||
import com.vaadin.server.ErrorMessage; | import com.vaadin.server.ErrorMessage; | ||||
String msg2 = "bar"; | String msg2 = "bar"; | ||||
binding.withValidator(new Validator<String>() { | binding.withValidator(new Validator<String>() { | ||||
@Override | @Override | ||||
public Result<String> apply(String value) { | |||||
public Result<String> apply(String value, ValueContext context) { | |||||
return new SimpleResult<>(null, msg1); | return new SimpleResult<>(null, msg1); | ||||
} | } | ||||
}); | }); | ||||
// validator for Number can be used on a Double | // validator for Number can be used on a Double | ||||
TextField salaryField = new TextField(); | TextField salaryField = new TextField(); | ||||
Validator<Number> positiveNumberValidator = value -> { | |||||
Validator<Number> positiveNumberValidator = (value, context) -> { | |||||
if (value.doubleValue() >= 0) { | if (value.doubleValue() >= 0) { | ||||
return Result.ok(value); | return Result.ok(value); | ||||
} else { | } else { | ||||
Binding<Person, String, String> binding = binder.forField(nameField) | Binding<Person, String, String> binding = binder.forField(nameField) | ||||
.withValidator(notEmpty); | .withValidator(notEmpty); | ||||
binding.bind(Person::getFirstName, Person::setFirstName); | binding.bind(Person::getFirstName, Person::setFirstName); | ||||
binder.withValidator(bean -> bean.getFirstName().contains("error") | |||||
? Result.error("error") : Result.ok(bean)); | |||||
binder.withValidator(bean -> !bean.getFirstName().contains("error"), | |||||
"error"); | |||||
Person person = new Person(); | Person person = new Person(); | ||||
person.setFirstName(""); | person.setFirstName(""); | ||||
binder.setBean(person); | binder.setBean(person); |
/* | /* | ||||
* Copyright 2000-2016 Vaadin Ltd. | * Copyright 2000-2016 Vaadin Ltd. | ||||
* | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||
* use this file except in compliance with the License. You may obtain a copy of | * use this file except in compliance with the License. You may obtain a copy of | ||||
* the License at | * the License at | ||||
* | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | * http://www.apache.org/licenses/LICENSE-2.0 | ||||
* | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | * Unless required by applicable law or agreed to in writing, software | ||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
import com.vaadin.tests.data.bean.Person; | import com.vaadin.tests.data.bean.Person; | ||||
import com.vaadin.ui.Label; | import com.vaadin.ui.Label; | ||||
public class BinderValidationStatusTest extends | |||||
BinderTestBase<Binder<Person>, Person> { | |||||
public class BinderValidationStatusTest | |||||
extends BinderTestBase<Binder<Person>, Person> { | |||||
protected final static ValidationStatusHandler NOOP = event -> { | protected final static ValidationStatusHandler NOOP = event -> { | ||||
}; | }; | ||||
"Using a custom status change handler so no change should end up here"); | "Using a custom status change handler so no change should end up here"); | ||||
}).bind(Person::getAge, Person::setAge); | }).bind(Person::getAge, Person::setAge); | ||||
binder.withValidator( | binder.withValidator( | ||||
bean -> !bean.getFirstName().isEmpty() && bean.getAge() > 0 | |||||
? Result.ok(bean) | |||||
: Result.error("Need first name and age")); | |||||
bean -> !bean.getFirstName().isEmpty() && bean.getAge() > 0, | |||||
"Need first name and age"); | |||||
binder.setValidationStatusHandler(r -> { | binder.setValidationStatusHandler(r -> { | ||||
statusCapture.set(r); | statusCapture.set(r); |
import org.junit.Assert; | import org.junit.Assert; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* @author Vaadin Ltd | * @author Vaadin Ltd | ||||
* | * | ||||
@Test | @Test | ||||
public void alwaysPass() { | public void alwaysPass() { | ||||
Validator<String> alwaysPass = Validator.alwaysPass(); | Validator<String> alwaysPass = Validator.alwaysPass(); | ||||
Result<String> result = alwaysPass.apply("foo"); | |||||
Result<String> result = alwaysPass.apply("foo", new ValueContext()); | |||||
Assert.assertTrue(result instanceof SimpleResult); | Assert.assertTrue(result instanceof SimpleResult); | ||||
SimpleResult<String> implRes = (SimpleResult<String>) result; | SimpleResult<String> implRes = (SimpleResult<String>) result; | ||||
Assert.assertFalse(implRes.getMessage().isPresent()); | Assert.assertFalse(implRes.getMessage().isPresent()); | ||||
} | } | ||||
@Test | |||||
public void chain_alwaysPassAndError() { | |||||
Validator<String> alwaysPass = Validator.alwaysPass(); | |||||
Validator<String> chain = alwaysPass | |||||
.chain(value -> Result.error("foo")); | |||||
Result<String> result = chain.apply("bar"); | |||||
Assert.assertTrue(result.isError()); | |||||
Assert.assertEquals("foo", result.getMessage().get()); | |||||
} | |||||
@SuppressWarnings("serial") | |||||
@Test | |||||
public void chain_mixture() { | |||||
Validator<String> first = new Validator<String>() { | |||||
@Override | |||||
public Result<String> apply(String value) { | |||||
if (value == null) { | |||||
return Result.error("Cannot be null"); | |||||
} | |||||
return Result.ok(value); | |||||
} | |||||
}; | |||||
Validator<String> second = new Validator<String>() { | |||||
@Override | |||||
public Result<String> apply(String value) { | |||||
if (value != null && value.isEmpty()) { | |||||
return Result.error("Cannot be empty"); | |||||
} | |||||
return Result.ok(value); | |||||
} | |||||
}; | |||||
Validator<String> chain = first.chain(second); | |||||
Result<String> result = chain.apply("bar"); | |||||
Assert.assertFalse(result.isError()); | |||||
result = chain.apply(null); | |||||
Assert.assertTrue(result.isError()); | |||||
result = chain.apply(""); | |||||
Assert.assertTrue(result.isError()); | |||||
} | |||||
@Test | @Test | ||||
public void from() { | public void from() { | ||||
Validator<String> validator = Validator.from(Objects::nonNull, | Validator<String> validator = Validator.from(Objects::nonNull, | ||||
"Cannot be null"); | "Cannot be null"); | ||||
Result<String> result = validator.apply(null); | |||||
Result<String> result = validator.apply(null, new ValueContext()); | |||||
Assert.assertTrue(result.isError()); | Assert.assertTrue(result.isError()); | ||||
result = validator.apply(""); | |||||
result = validator.apply("", new ValueContext()); | |||||
Assert.assertFalse(result.isError()); | Assert.assertFalse(result.isError()); | ||||
} | } | ||||
} | } |
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
/** | /** | ||||
* @author Vaadin Ltd | * @author Vaadin Ltd | ||||
@Test | @Test | ||||
public void nullValueIsDisallowed() { | public void nullValueIsDisallowed() { | ||||
NotEmptyValidator<String> validator = new NotEmptyValidator<>("foo"); | NotEmptyValidator<String> validator = new NotEmptyValidator<>("foo"); | ||||
Result<String> result = validator.apply(null); | |||||
Result<String> result = validator.apply(null, new ValueContext()); | |||||
Assert.assertTrue(result.isError()); | Assert.assertTrue(result.isError()); | ||||
Assert.assertEquals("foo", result.getMessage().get()); | Assert.assertEquals("foo", result.getMessage().get()); | ||||
} | } | ||||
@Test | @Test | ||||
public void emptyValueIsDisallowed() { | public void emptyValueIsDisallowed() { | ||||
NotEmptyValidator<String> validator = new NotEmptyValidator<>("foo"); | NotEmptyValidator<String> validator = new NotEmptyValidator<>("foo"); | ||||
Result<String> result = validator.apply(""); | |||||
Result<String> result = validator.apply("", new ValueContext()); | |||||
Assert.assertTrue(result.isError()); | Assert.assertTrue(result.isError()); | ||||
Assert.assertEquals("foo", result.getMessage().get()); | Assert.assertEquals("foo", result.getMessage().get()); | ||||
} | } | ||||
public void nonNullValueIsAllowed() { | public void nonNullValueIsAllowed() { | ||||
NotEmptyValidator<Object> validator = new NotEmptyValidator<>("foo"); | NotEmptyValidator<Object> validator = new NotEmptyValidator<>("foo"); | ||||
Object value = new Object(); | Object value = new Object(); | ||||
Result<Object> result = validator.apply(value); | |||||
Result<Object> result = validator.apply(value, new ValueContext()); | |||||
Assert.assertFalse(result.isError()); | Assert.assertFalse(result.isError()); | ||||
result.ifOk(val -> Assert.assertEquals(value, val)); | result.ifOk(val -> Assert.assertEquals(value, val)); | ||||
result.ifError(msg -> Assert.fail()); | result.ifError(msg -> Assert.fail()); |
import org.junit.Test; | import org.junit.Test; | ||||
import com.vaadin.data.Result; | import com.vaadin.data.Result; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
public class NotNullValidatorTest { | public class NotNullValidatorTest { | ||||
@Test | @Test | ||||
public void nullValueIsDisallowed() { | public void nullValueIsDisallowed() { | ||||
NotNullValidator validator = new NotNullValidator("foo"); | NotNullValidator validator = new NotNullValidator("foo"); | ||||
Result<String> result = validator.apply(null); | |||||
Result<String> result = validator.apply(null, new ValueContext()); | |||||
Assert.assertTrue(result.isError()); | Assert.assertTrue(result.isError()); | ||||
Assert.assertEquals("foo", result.getMessage().get()); | Assert.assertEquals("foo", result.getMessage().get()); | ||||
} | } | ||||
@Test | @Test | ||||
public void nonNullValueIsAllowed() { | public void nonNullValueIsAllowed() { | ||||
NotNullValidator validator = new NotNullValidator("foo"); | NotNullValidator validator = new NotNullValidator("foo"); | ||||
Result<String> result = validator.apply("bar"); | |||||
Result<String> result = validator.apply("bar", new ValueContext()); | |||||
Assert.assertFalse(result.isError()); | Assert.assertFalse(result.isError()); | ||||
result.ifOk(value -> Assert.assertEquals("bar", value)); | result.ifOk(value -> Assert.assertEquals("bar", value)); | ||||
result.ifError(msg -> Assert.fail()); | result.ifError(msg -> Assert.fail()); |
import org.junit.Assert; | import org.junit.Assert; | ||||
import com.vaadin.data.Validator; | import com.vaadin.data.Validator; | ||||
import com.vaadin.data.util.converter.ValueContext; | |||||
public class ValidatorTestBase { | public class ValidatorTestBase { | ||||
protected <T> void assertPasses(T value, Validator<? super T> v) { | protected <T> void assertPasses(T value, Validator<? super T> v) { | ||||
v.apply(value).handle(val -> Assert.assertEquals(value, val), | |||||
err -> Assert | |||||
v.apply(value, new ValueContext()) | |||||
.handle(val -> Assert.assertEquals(value, val), err -> Assert | |||||
.fail(value + " should pass " + v + " but got " + err)); | .fail(value + " should pass " + v + " but got " + err)); | ||||
} | } | ||||
protected <T> void assertFails(T value, String errorMessage, | protected <T> void assertFails(T value, String errorMessage, | ||||
Validator<? super T> v) { | Validator<? super T> v) { | ||||
v.apply(value).handle(val -> Assert.fail(value + " should fail " + v), | |||||
v.apply(value, new ValueContext()).handle( | |||||
val -> Assert.fail(value + " should fail " + v), | |||||
err -> Assert.assertEquals(errorMessage, err)); | err -> Assert.assertEquals(errorMessage, err)); | ||||
} | } | ||||