dropwizard/dropwizard

View on GitHub
dropwizard-validation/src/test/java/io/dropwizard/validation/selfvalidating/SelfValidatingValidatorTest.java

Summary

Maintainability
A
0 mins
Test Coverage
package io.dropwizard.validation.selfvalidating;

import com.fasterxml.classmate.AnnotationConfiguration;
import com.fasterxml.classmate.AnnotationInclusion;
import com.fasterxml.classmate.MemberResolver;
import com.fasterxml.classmate.ResolvedTypeWithMembers;
import com.fasterxml.classmate.TypeResolver;
import com.fasterxml.classmate.members.ResolvedMethod;
import io.dropwizard.validation.BaseValidator;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Arrays;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

class SelfValidatingValidatorTest {
    private final Logger log = mock(Logger.class);
    private final SelfValidatingValidator selfValidatingValidator = new SelfValidatingValidator(log);

    @Test
    void validObjectHasNoViolations() {
        final Validator validator = BaseValidator.newValidator();
        final Set<ConstraintViolation<ValidExample>> violations = validator.validate(new ValidExample(1));
        assertThat(violations).isEmpty();
    }

    @Test
    void invalidObjectHasViolations() {
        final Validator validator = BaseValidator.newValidator();
        final Set<ConstraintViolation<ValidExample>> violations = validator.validate(new ValidExample(-1));
        assertThat(violations)
                .singleElement()
                .extracting(ConstraintViolation::getMessage)
                .isEqualTo("n must be positive!");
    }

    @Test
    void correctMethod() {
        assertThat(selfValidatingValidator.isMethodCorrect(
                getMethod("validateCorrect", ViolationCollector.class)))
                .isTrue();
    }

    @Test
    void voidIsNotAccepted() {
        assertThat(selfValidatingValidator.isMethodCorrect(
                getMethod("validateFailReturn", ViolationCollector.class)))
                .isFalse();
    }

    @Test
    @SuppressWarnings("Slf4jFormatShouldBeConst")
    void privateIsNotAccepted() throws NoSuchMethodException {
        assertThat(selfValidatingValidator.isMethodCorrect(
                getMethod("validateFailPrivate", ViolationCollector.class)))
                .isFalse();

        verify(log).error("The method {} is annotated with @SelfValidation but is not public",
            InvalidExample.class.getDeclaredMethod("validateFailPrivate", ViolationCollector.class));
    }

    @Test
    @SuppressWarnings("Slf4jFormatShouldBeConst")
    void additionalParametersAreNotAccepted() throws NoSuchMethodException {
        assertThat(selfValidatingValidator.isMethodCorrect(
                getMethod("validateFailAdditionalParameters", ViolationCollector.class, int.class)))
                .isFalse();

        verify(log).error("The method {} is annotated with @SelfValidation but does not have a single parameter of type {}",
            InvalidExample.class.getMethod("validateFailAdditionalParameters", ViolationCollector.class, int.class),
            ViolationCollector.class);
    }

    private ResolvedMethod getMethod(String name, Class<?>... params) {
        AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED);
        TypeResolver typeResolver = new TypeResolver();
        MemberResolver memberResolver = new MemberResolver(typeResolver);
        ResolvedTypeWithMembers annotatedType = memberResolver.resolve(typeResolver.resolve(InvalidExample.class), annotationConfiguration, null);
        for (ResolvedMethod m : annotatedType.getMemberMethods()) {
            if (hasSignature(m, name, params)) {
                return m;
            }
        }
        throw new IllegalStateException("Could not resolve method " + name + Arrays.toString(params) + " in " + InvalidExample.class);
    }

    private boolean hasSignature(ResolvedMethod m, String name, Class<?>[] params) {
        if (!m.getName().equals(name) || m.getArgumentCount() != params.length) {
            return false;
        }
        for (int i = 0; i < params.length; i++) {
            if (!m.getArgumentType(i).getErasedType().equals(params[i]))
                return false;
        }
        return true;
    }


    @SelfValidating
    static class InvalidExample {
        @SelfValidation
        public void validateCorrect(ViolationCollector col) {
        }

        @SelfValidation
        public void validateFailAdditionalParameters(ViolationCollector col, int a) {
        }

        @SelfValidation
        public boolean validateFailReturn(ViolationCollector col) {
            return true;
        }

        @SelfValidation
        private void validateFailPrivate(ViolationCollector col) {
        }
    }

    @SelfValidating
    static class ValidExample {
        final int n;

        ValidExample(int n) {
            this.n = n;
        }

        @SelfValidation
        public void validate(ViolationCollector col) {
            if (n < 0) {
                col.addViolation("n must be positive!");
            }
        }
    }
}