-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.kiwiproject.validation; | ||
|
||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE; | ||
import static java.lang.annotation.ElementType.CONSTRUCTOR; | ||
import static java.lang.annotation.ElementType.FIELD; | ||
import static java.lang.annotation.ElementType.METHOD; | ||
import static java.lang.annotation.ElementType.PARAMETER; | ||
import static java.lang.annotation.ElementType.TYPE_USE; | ||
|
||
import javax.validation.Constraint; | ||
import javax.validation.Payload; | ||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* The annotated element must have a value that can be converted to a Java int or {@link Integer}. | ||
*/ | ||
@Documented | ||
@Constraint(validatedBy = IntValidator.class) | ||
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Int { | ||
|
||
String message() default "{org.kiwiproject.validation.Int.message}"; | ||
|
||
Class<?>[] groups() default {}; | ||
|
||
Class<? extends Payload>[] payload() default {}; | ||
|
||
/** | ||
* Whether to consider null as valid. The default is false. | ||
* | ||
* @return true to consider null as valid | ||
*/ | ||
boolean allowNull() default false; | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/org/kiwiproject/validation/IntValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.kiwiproject.validation; | ||
|
||
import static java.util.Objects.isNull; | ||
|
||
import javax.validation.ConstraintValidator; | ||
import javax.validation.ConstraintValidatorContext; | ||
|
||
public class IntValidator implements ConstraintValidator<Int, CharSequence> { | ||
|
||
private Int anInt; | ||
|
||
@Override | ||
public void initialize(Int constraintAnnotation) { | ||
this.anInt = constraintAnnotation; | ||
} | ||
|
||
@Override | ||
public boolean isValid(CharSequence value, ConstraintValidatorContext context) { | ||
if (isNull(value)) { | ||
return anInt.allowNull(); | ||
} | ||
|
||
try { | ||
Integer.parseInt(value.toString()); | ||
return true; | ||
} catch (NumberFormatException e) { | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
src/test/java/org/kiwiproject/validation/IntValidatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package org.kiwiproject.validation; | ||
|
||
import static org.kiwiproject.validation.ValidationTestHelper.assertNoPropertyViolations; | ||
import static org.kiwiproject.validation.ValidationTestHelper.assertOnePropertyViolation; | ||
import static org.kiwiproject.validation.ValidationTestHelper.assertPropertyViolations; | ||
|
||
import lombok.Value; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
@DisplayName("IntValidator") | ||
class IntValidatorTest { | ||
|
||
private static final long ONE_BELOW_MAX_INTEGER = Integer.MIN_VALUE - 1L; | ||
private static final long ONE_ABOVE_MAX_INTEGER = Integer.MAX_VALUE + 1L; | ||
|
||
@Nested | ||
class ShouldBeValid { | ||
|
||
@Test | ||
void whenAllowingNull_AndValueIsNull() { | ||
var object = new SampleAllowNullObject(null); | ||
assertValueIsValid(object); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(ints = {Integer.MIN_VALUE, -84, 0, 42, Integer.MAX_VALUE}) | ||
void whenValueIsAnInt(int value) { | ||
var strValue = String.valueOf(value); | ||
var object = new SampleObject(strValue); | ||
assertValueIsValid(object); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {"042", "0042", "001", "+42", "-42", "+0042", "-0084"}) | ||
void whenValueContainingSignsAndLeadingZeroesIsAnInt(String value) { | ||
var object = new SampleObject(value); | ||
assertValueIsValid(object); | ||
} | ||
|
||
private void assertValueIsValid(Object object) { | ||
assertNoPropertyViolations(object, "value"); | ||
} | ||
} | ||
|
||
@Nested | ||
class ShouldNotBeValid { | ||
|
||
@Test | ||
void whenNotAllowingNull_AndValueIsNull() { | ||
var object = new SampleObject(null); | ||
assertValueIsNotValid(object); | ||
assertPropertyViolations(object, "value", "must be convertible to an integer"); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {"foo", "bar", "baz", "spam", "eggs", "ham", "0xCAFEBABE"}) | ||
void whenNotAnInt(String value) { | ||
var object = new SampleObject(value); | ||
assertValueIsNotValid(object); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(longs = {ONE_BELOW_MAX_INTEGER, ONE_ABOVE_MAX_INTEGER}) | ||
void whenOutsideIntRange(long value) { | ||
var strValue = String.valueOf(value); | ||
var object = new SampleObject(strValue); | ||
assertValueIsNotValid(object); | ||
} | ||
|
||
private void assertValueIsNotValid(SampleObject object) { | ||
assertOnePropertyViolation(object, "value"); | ||
} | ||
} | ||
|
||
@Value | ||
private static class SampleObject { | ||
@Int | ||
String value; | ||
} | ||
|
||
@Value | ||
private static class SampleAllowNullObject { | ||
@Int(allowNull = true) | ||
String value; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters