• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.junit.validator;
2 
3 import static java.util.Collections.singletonList;
4 
5 import java.lang.annotation.Annotation;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.List;
9 
10 import org.junit.runners.model.Annotatable;
11 import org.junit.runners.model.FrameworkField;
12 import org.junit.runners.model.FrameworkMethod;
13 import org.junit.runners.model.TestClass;
14 
15 /**
16  * An {@code AnnotationsValidator} validates all annotations of a test class,
17  * including its annotated fields and methods.
18  *
19  * @since 4.12
20  */
21 public final class AnnotationsValidator implements TestClassValidator {
22     private static final List<AnnotatableValidator<?>> VALIDATORS = Arrays.<AnnotatableValidator<?>>asList(
23             new ClassValidator(), new MethodValidator(), new FieldValidator());
24 
25     /**
26      * Validate all annotations of the specified test class that are be
27      * annotated with {@link ValidateWith}.
28      *
29      * @param testClass
30      *            the {@link TestClass} that is validated.
31      * @return the errors found by the validator.
32      */
validateTestClass(TestClass testClass)33     public List<Exception> validateTestClass(TestClass testClass) {
34         List<Exception> validationErrors= new ArrayList<Exception>();
35         for (AnnotatableValidator<?> validator : VALIDATORS) {
36             List<Exception> additionalErrors= validator
37                     .validateTestClass(testClass);
38             validationErrors.addAll(additionalErrors);
39         }
40         return validationErrors;
41     }
42 
43     private static abstract class AnnotatableValidator<T extends Annotatable> {
44         private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory();
45 
getAnnotatablesForTestClass(TestClass testClass)46         abstract Iterable<T> getAnnotatablesForTestClass(TestClass testClass);
47 
validateAnnotatable( AnnotationValidator validator, T annotatable)48         abstract List<Exception> validateAnnotatable(
49                 AnnotationValidator validator, T annotatable);
50 
validateTestClass(TestClass testClass)51         public List<Exception> validateTestClass(TestClass testClass) {
52             List<Exception> validationErrors= new ArrayList<Exception>();
53             for (T annotatable : getAnnotatablesForTestClass(testClass)) {
54                 List<Exception> additionalErrors= validateAnnotatable(annotatable);
55                 validationErrors.addAll(additionalErrors);
56             }
57             return validationErrors;
58         }
59 
validateAnnotatable(T annotatable)60         private List<Exception> validateAnnotatable(T annotatable) {
61             List<Exception> validationErrors= new ArrayList<Exception>();
62             for (Annotation annotation : annotatable.getAnnotations()) {
63                 Class<? extends Annotation> annotationType = annotation
64                         .annotationType();
65                 ValidateWith validateWith = annotationType
66                         .getAnnotation(ValidateWith.class);
67                 if (validateWith != null) {
68                     AnnotationValidator annotationValidator = ANNOTATION_VALIDATOR_FACTORY
69                             .createAnnotationValidator(validateWith);
70                     List<Exception> errors= validateAnnotatable(
71                             annotationValidator, annotatable);
72                     validationErrors.addAll(errors);
73                 }
74             }
75             return validationErrors;
76         }
77     }
78 
79     private static class ClassValidator extends AnnotatableValidator<TestClass> {
80         @Override
getAnnotatablesForTestClass(TestClass testClass)81         Iterable<TestClass> getAnnotatablesForTestClass(TestClass testClass) {
82             return singletonList(testClass);
83         }
84 
85         @Override
validateAnnotatable( AnnotationValidator validator, TestClass testClass)86         List<Exception> validateAnnotatable(
87                 AnnotationValidator validator, TestClass testClass) {
88             return validator.validateAnnotatedClass(testClass);
89         }
90     }
91 
92     private static class MethodValidator extends
93             AnnotatableValidator<FrameworkMethod> {
94         @Override
getAnnotatablesForTestClass( TestClass testClass)95         Iterable<FrameworkMethod> getAnnotatablesForTestClass(
96                 TestClass testClass) {
97             return testClass.getAnnotatedMethods();
98         }
99 
100         @Override
validateAnnotatable( AnnotationValidator validator, FrameworkMethod method)101         List<Exception> validateAnnotatable(
102                 AnnotationValidator validator, FrameworkMethod method) {
103             return validator.validateAnnotatedMethod(method);
104         }
105     }
106 
107     private static class FieldValidator extends
108             AnnotatableValidator<FrameworkField> {
109         @Override
getAnnotatablesForTestClass(TestClass testClass)110         Iterable<FrameworkField> getAnnotatablesForTestClass(TestClass testClass) {
111             return testClass.getAnnotatedFields();
112         }
113 
114         @Override
validateAnnotatable( AnnotationValidator validator, FrameworkField field)115         List<Exception> validateAnnotatable(
116                 AnnotationValidator validator, FrameworkField field) {
117             return validator.validateAnnotatedField(field);
118         }
119     };
120 }
121