From eea7bd05b8761fccf13f5307f8b9d512a0e0011e Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 21 Mar 2023 13:15:16 -0600 Subject: [PATCH] Add more tests and fix nullability (#79) --- .../DefaultConstraintDescriptor.java | 26 ++--- .../validator/MyBeanWithPrimitives.java | 19 ++++ .../validation/validator/ValidatorSpec.groovy | 98 ++++++++++++++++++- 3 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 validation/src/test/groovy/io/micronaut/validation/validator/MyBeanWithPrimitives.java diff --git a/validation/src/main/java/io/micronaut/validation/validator/DefaultConstraintDescriptor.java b/validation/src/main/java/io/micronaut/validation/validator/DefaultConstraintDescriptor.java index d48176a6..950c02da 100644 --- a/validation/src/main/java/io/micronaut/validation/validator/DefaultConstraintDescriptor.java +++ b/validation/src/main/java/io/micronaut/validation/validator/DefaultConstraintDescriptor.java @@ -60,12 +60,12 @@ class DefaultConstraintDescriptor implements ConstraintDes private final AnnotationValue annotationValue; private final AnnotationMetadata annotationMetadata; - DefaultConstraintDescriptor(Class constraintType, - AnnotationValue annotationValue, - AnnotationMetadata annotationMetadata) { + DefaultConstraintDescriptor(@NonNull Class constraintType, + @NonNull AnnotationValue annotationValue, + @NonNull AnnotationMetadata annotationMetadata) { this(constraintType, annotationValue.stringValue("message").orElse(null), - (String) annotationValue.getDefaultValues().get("message"), + annotationValue.getDefaultValues() == null ? null : (String) annotationValue.getDefaultValues().get("message"), Set.of(annotationValue.classValues("groups")), (Set) Set.of(annotationValue.classValues("payload")), (List) List.of(annotationValue.classValues(ValidationAnnotationUtil.CONSTRAINT_VALIDATED_BY)), @@ -74,15 +74,15 @@ class DefaultConstraintDescriptor implements ConstraintDes annotationMetadata); } - DefaultConstraintDescriptor(Class type, - String message, - String defaultMessage, - Set> groups, - Set> payload, - List>> validatedBy, - ConstraintTarget validationAppliesTo, - AnnotationValue annotationValue, - AnnotationMetadata annotationMetadata) { + DefaultConstraintDescriptor(@NonNull Class type, + @Nullable String message, + @Nullable String defaultMessage, + @NonNull Set> groups, + @NonNull Set> payload, + @NonNull List>> validatedBy, + @NonNull ConstraintTarget validationAppliesTo, + @NonNull AnnotationValue annotationValue, + @NonNull AnnotationMetadata annotationMetadata) { this.type = type; this.message = message; this.defaultMessage = defaultMessage; diff --git a/validation/src/test/groovy/io/micronaut/validation/validator/MyBeanWithPrimitives.java b/validation/src/test/groovy/io/micronaut/validation/validator/MyBeanWithPrimitives.java new file mode 100644 index 00000000..7ad8f81d --- /dev/null +++ b/validation/src/test/groovy/io/micronaut/validation/validator/MyBeanWithPrimitives.java @@ -0,0 +1,19 @@ +package io.micronaut.validation.validator; + +import io.micronaut.core.annotation.Introspected; +import jakarta.validation.constraints.Max; + +@Introspected +public class MyBeanWithPrimitives { + + @Max(20) + private int number; + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } +} diff --git a/validation/src/test/groovy/io/micronaut/validation/validator/ValidatorSpec.groovy b/validation/src/test/groovy/io/micronaut/validation/validator/ValidatorSpec.groovy index 0b8c0351..11a6d322 100644 --- a/validation/src/test/groovy/io/micronaut/validation/validator/ValidatorSpec.groovy +++ b/validation/src/test/groovy/io/micronaut/validation/validator/ValidatorSpec.groovy @@ -19,7 +19,6 @@ import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Size import jakarta.validation.metadata.BeanDescriptor -import org.apache.groovy.util.Maps import spock.lang.AutoCleanup import spock.lang.Shared import spock.lang.Specification @@ -860,15 +859,79 @@ class ValidatorSpec extends Specification { then: noExceptionThrown() } + + void "test shouldn't iterate"() { + when: + def service = applicationContext.getBean(MyService) + service.myMethod1() + service.myMethod2() + service.myMethod3() + service.myMethod4(new BeanMap()) + service.myMethod5(new BeanList>()) + + then: + noExceptionThrown() + } + + void "test validate primitives parameter"() { + when: + def service = applicationContext.getBean(MyService2) + service.myMethod1(10) + then: + Exception e = thrown() + e.message.contains('''myMethod1.a: must be less than or equal to 5''') + } + + void "test validate primitives return"() { + when: + def service = applicationContext.getBean(MyService2) + service.myMethod1(1) + then: + Exception e = thrown() + e.message.contains('''myMethod1.: must be greater than or equal to 10''') + } + + void "test validate bean with primitives"() { + when: + def service = applicationContext.getBean(MyService2) + def bean = new MyBeanWithPrimitives() + bean.number = 100 + service.myMethod2(bean) + then: + Exception e = thrown() + e.message.contains('''myMethod2.bean.number: must be less than or equal to 20''') + } } class Bean extends AbstractMap { @Override Set> entrySet() { - return Maps.of("A", 1, "B", 2, "C", 3).entrySet() + throw new IllegalStateException("Should be iterated") + } + +} + +class BeanMap extends AbstractMap { + + @Override + Set> entrySet() { + throw new IllegalStateException("Should be iterated") + } + +} + +class BeanList extends AbstractList { + + @Override + V get(int index) { + throw new IllegalStateException("Should be iterated") } + @Override + int size() { + throw new IllegalStateException("Should be iterated") + } } @Validated @@ -879,6 +942,37 @@ class MyService { return [new Bean(), new Bean()] as List } + List myMethod1() { + return [new Bean(), new Bean()] as List + } + + List> myMethod2() { + return [new BeanMap(), new BeanMap()] as List + } + + BeanMap myMethod3() { + return new BeanMap() + } + + void myMethod4(BeanMap val) { + } + + void myMethod5(List> val) { + } + +} + +@Validated +@Singleton +class MyService2 { + + @Min(10) int myMethod1(@Max(5) int a) { + return a + } + + void myMethod2(@Valid MyBeanWithPrimitives bean) { + } + } @Singleton