| /* |
| * Copyright 2010 Google Inc. |
| * |
| * 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 |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.validation.testing.constraints; |
| |
| import junit.framework.TestCase; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Field; |
| |
| import javax.validation.ConstraintValidator; |
| import javax.validation.ConstraintValidatorContext; |
| |
| /** |
| * TestCase for {@link javax.validation.ConstraintValidator}s. |
| * <p> |
| * Subclasses must : |
| * <ul> |
| * <li>implement {@link #getAnnotationClass()}</li> |
| * <li>implement {@link #createValidator()}.</li> |
| * <li>define a field called <code>defaultField</code> and annotate it with the |
| * constraint Annotation under test</li> |
| * </ul> |
| * |
| * <p> |
| * If additional instances of the annotation need to be tested you can get there |
| * value with {@link #getAnnotation(Class, Class, String)} |
| * |
| * @param <A> The constraint Annotation of the ConstraintValidator under test |
| * @param <T> The bean type of the ConstraintValidator under test |
| */ |
| public abstract class ConstraintValidatorTestCase<A extends Annotation, T> |
| extends TestCase { |
| |
| public final static String DEFAULT_ANNOTATED_FIELD_NAME = "defaultField"; |
| |
| // Validators are reusable but not thread safe |
| protected final ConstraintValidator<A, T> validator = createValidator(); |
| |
| // private ConstraintValidatorContext context; |
| |
| public ConstraintValidatorTestCase() { |
| super(); |
| } |
| |
| /** |
| * All constraints except {@link NotNull} should return true for a null value. |
| */ |
| public final void testIsValid_null() { |
| ConstraintValidatorTestCase.assertConstraintValidator(validator, |
| getDefaultAnnotation(), null, null, isNullValid()); |
| } |
| |
| /** |
| * Override this if a null value should not be valid. This is called by |
| * {@link #testIsValid_null()} |
| */ |
| protected boolean isNullValid() { |
| return true; |
| } |
| |
| /** |
| * Get the annotation of type {@link #getAnnotationClass()} on the field named |
| * <code>defaultField</code>. |
| */ |
| protected final A getDefaultAnnotation() { |
| return getAnnotation(getAnnotationClass(), this.getClass(), |
| DEFAULT_ANNOTATED_FIELD_NAME); |
| } |
| |
| protected abstract Class<A> getAnnotationClass(); |
| |
| protected A getAnnotation(Class<A> annotationClass, Class<?> objectClass, |
| String fieldName) { |
| |
| for (Field field : objectClass.getDeclaredFields()) { |
| if (field.getName().equals(fieldName)) { |
| A annotation = field.getAnnotation(annotationClass); |
| if (annotation == null) { |
| throw new IllegalArgumentException(objectClass + "." + fieldName |
| + " is not annotated with " + annotationClass); |
| } |
| return annotation; |
| } |
| } |
| throw new IllegalArgumentException(objectClass |
| + " does not have a field called " + fieldName); |
| } |
| |
| protected abstract ConstraintValidator<A, T> createValidator(); |
| |
| /** |
| * Assert result of validating <code>value</code> with <code>validator</code> |
| * initialized with the annotation of the <code>defaultField</code>. |
| * |
| * @param value the Value to validate |
| * @param expected the expected result of a calling <code>isValid</code> |
| */ |
| protected void assertConstraintValidator(T value, boolean expected) { |
| assertConstraintValidator(validator, getDefaultAnnotation(), null, value, |
| expected); |
| } |
| |
| /** |
| * Asserts the validity of a value using the given validator, annotation, and |
| * context. |
| * |
| * @param <T> object type |
| * @param <A> the constraint annotation type |
| * @param validator the {@link ConstraintValidator} to test |
| * @param annotation the constraint annotation to initialize the validator. |
| * @param context The context for the validator |
| * @param value the value to validate. |
| * @param expected the expected result |
| */ |
| public static <T, A extends Annotation> void assertConstraintValidator( |
| ConstraintValidator<A, T> validator, A annotation, |
| ConstraintValidatorContext context, T value, boolean expected) { |
| validator.initialize(annotation); |
| String message = validator.getClass().getName() + "(" + annotation |
| + ").isValid(" + value + ", " + context + ")"; |
| assertEquals(message, expected, validator.isValid(value, context)); |
| } |
| |
| } |