aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/validator
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2016-12-14 11:49:43 +0000
committerPaul Duffin <paulduffin@google.com>2016-12-20 15:52:52 +0000
commitaeb93fc33cae3aadbb9b46083350ad2dc9aea645 (patch)
treeb316db7dee11d1aeee3510562e036fd41705b8b5 /src/main/java/org/junit/validator
parent26401927b83770db45f00706ccc589955644c6c2 (diff)
downloadjunit-aeb93fc33cae3aadbb9b46083350ad2dc9aea645.tar.gz
Upgrade to JUnit 4.12
The license has changed from Common Public License v1.0 to Eclipse Public License v1.0. This will not compile as it is because it is intended to be built against Hamcrest 1.3 or later but it is being built against Hamcrest 1.1. A follow on patch will fix the compilation errors so that it builds against Hamcrest 1.1. That allows Hamcrest to be upgraded separately. The patch can be reverted once Hamcrest has been upgraded. There are also some Android specific issues that will also be fixed in follow on patches. Bug: 33613916 Test: make checkbuild Change-Id: Ic2c983a030399e3ace1a14927cb143fbd8307b4f
Diffstat (limited to 'src/main/java/org/junit/validator')
-rw-r--r--src/main/java/org/junit/validator/AnnotationValidator.java60
-rw-r--r--src/main/java/org/junit/validator/AnnotationValidatorFactory.java42
-rw-r--r--src/main/java/org/junit/validator/AnnotationsValidator.java120
-rw-r--r--src/main/java/org/junit/validator/PublicClassValidator.java33
-rw-r--r--src/main/java/org/junit/validator/TestClassValidator.java21
-rw-r--r--src/main/java/org/junit/validator/ValidateWith.java19
6 files changed, 295 insertions, 0 deletions
diff --git a/src/main/java/org/junit/validator/AnnotationValidator.java b/src/main/java/org/junit/validator/AnnotationValidator.java
new file mode 100644
index 0000000..8a53adf
--- /dev/null
+++ b/src/main/java/org/junit/validator/AnnotationValidator.java
@@ -0,0 +1,60 @@
+package org.junit.validator;
+
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+import static java.util.Collections.emptyList;
+
+import java.util.List;
+
+/**
+ * Validates annotations on classes and methods. To be validated,
+ * an annotation should be annotated with {@link ValidateWith}
+ *
+ * Instances of this class are shared by multiple test runners, so they should
+ * be immutable and thread-safe.
+ *
+ * @since 4.12
+ */
+public abstract class AnnotationValidator {
+
+ private static final List<Exception> NO_VALIDATION_ERRORS = emptyList();
+
+ /**
+ * Validates annotation on the given class.
+ *
+ * @param testClass that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedClass(TestClass testClass) {
+ return NO_VALIDATION_ERRORS;
+ }
+
+ /**
+ * Validates annotation on the given field.
+ *
+ * @param field that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedField(FrameworkField field) {
+ return NO_VALIDATION_ERRORS;
+
+ }
+
+ /**
+ * Validates annotation on the given method.
+ *
+ * @param method that is being validated
+ * @return A list of exceptions. Default behavior is to return an empty list.
+ *
+ * @since 4.12
+ */
+ public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
+ return NO_VALIDATION_ERRORS;
+ }
+}
diff --git a/src/main/java/org/junit/validator/AnnotationValidatorFactory.java b/src/main/java/org/junit/validator/AnnotationValidatorFactory.java
new file mode 100644
index 0000000..7309fdd
--- /dev/null
+++ b/src/main/java/org/junit/validator/AnnotationValidatorFactory.java
@@ -0,0 +1,42 @@
+package org.junit.validator;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Creates instances of Annotation Validators.
+ *
+ * @since 4.12
+ */
+public class AnnotationValidatorFactory {
+ private static final ConcurrentHashMap<ValidateWith, AnnotationValidator> VALIDATORS_FOR_ANNOTATION_TYPES =
+ new ConcurrentHashMap<ValidateWith, AnnotationValidator>();
+
+ /**
+ * Creates the AnnotationValidator specified by the value in
+ * {@link org.junit.validator.ValidateWith}. Instances are
+ * cached.
+ *
+ * @return An instance of the AnnotationValidator.
+ *
+ * @since 4.12
+ */
+ public AnnotationValidator createAnnotationValidator(ValidateWith validateWithAnnotation) {
+ AnnotationValidator validator = VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
+ if (validator != null) {
+ return validator;
+ }
+
+ Class<? extends AnnotationValidator> clazz = validateWithAnnotation.value();
+ if (clazz == null) {
+ throw new IllegalArgumentException("Can't create validator, value is null in annotation " + validateWithAnnotation.getClass().getName());
+ }
+ try {
+ AnnotationValidator annotationValidator = clazz.newInstance();
+ VALIDATORS_FOR_ANNOTATION_TYPES.putIfAbsent(validateWithAnnotation, annotationValidator);
+ return VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
+ } catch (Exception e) {
+ throw new RuntimeException("Exception received when creating AnnotationValidator class " + clazz.getName(), e);
+ }
+ }
+
+}
diff --git a/src/main/java/org/junit/validator/AnnotationsValidator.java b/src/main/java/org/junit/validator/AnnotationsValidator.java
new file mode 100644
index 0000000..30f54a6
--- /dev/null
+++ b/src/main/java/org/junit/validator/AnnotationsValidator.java
@@ -0,0 +1,120 @@
+package org.junit.validator;
+
+import static java.util.Collections.singletonList;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.runners.model.Annotatable;
+import org.junit.runners.model.FrameworkField;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+/**
+ * An {@code AnnotationsValidator} validates all annotations of a test class,
+ * including its annotated fields and methods.
+ *
+ * @since 4.12
+ */
+public final class AnnotationsValidator implements TestClassValidator {
+ private static final List<AnnotatableValidator<?>> VALIDATORS = Arrays.<AnnotatableValidator<?>>asList(
+ new ClassValidator(), new MethodValidator(), new FieldValidator());
+
+ /**
+ * Validate all annotations of the specified test class that are be
+ * annotated with {@link ValidateWith}.
+ *
+ * @param testClass
+ * the {@link TestClass} that is validated.
+ * @return the errors found by the validator.
+ */
+ public List<Exception> validateTestClass(TestClass testClass) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (AnnotatableValidator<?> validator : VALIDATORS) {
+ List<Exception> additionalErrors= validator
+ .validateTestClass(testClass);
+ validationErrors.addAll(additionalErrors);
+ }
+ return validationErrors;
+ }
+
+ private static abstract class AnnotatableValidator<T extends Annotatable> {
+ private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory();
+
+ abstract Iterable<T> getAnnotatablesForTestClass(TestClass testClass);
+
+ abstract List<Exception> validateAnnotatable(
+ AnnotationValidator validator, T annotatable);
+
+ public List<Exception> validateTestClass(TestClass testClass) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (T annotatable : getAnnotatablesForTestClass(testClass)) {
+ List<Exception> additionalErrors= validateAnnotatable(annotatable);
+ validationErrors.addAll(additionalErrors);
+ }
+ return validationErrors;
+ }
+
+ private List<Exception> validateAnnotatable(T annotatable) {
+ List<Exception> validationErrors= new ArrayList<Exception>();
+ for (Annotation annotation : annotatable.getAnnotations()) {
+ Class<? extends Annotation> annotationType = annotation
+ .annotationType();
+ ValidateWith validateWith = annotationType
+ .getAnnotation(ValidateWith.class);
+ if (validateWith != null) {
+ AnnotationValidator annotationValidator = ANNOTATION_VALIDATOR_FACTORY
+ .createAnnotationValidator(validateWith);
+ List<Exception> errors= validateAnnotatable(
+ annotationValidator, annotatable);
+ validationErrors.addAll(errors);
+ }
+ }
+ return validationErrors;
+ }
+ }
+
+ private static class ClassValidator extends AnnotatableValidator<TestClass> {
+ @Override
+ Iterable<TestClass> getAnnotatablesForTestClass(TestClass testClass) {
+ return singletonList(testClass);
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, TestClass testClass) {
+ return validator.validateAnnotatedClass(testClass);
+ }
+ }
+
+ private static class MethodValidator extends
+ AnnotatableValidator<FrameworkMethod> {
+ @Override
+ Iterable<FrameworkMethod> getAnnotatablesForTestClass(
+ TestClass testClass) {
+ return testClass.getAnnotatedMethods();
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, FrameworkMethod method) {
+ return validator.validateAnnotatedMethod(method);
+ }
+ }
+
+ private static class FieldValidator extends
+ AnnotatableValidator<FrameworkField> {
+ @Override
+ Iterable<FrameworkField> getAnnotatablesForTestClass(TestClass testClass) {
+ return testClass.getAnnotatedFields();
+ }
+
+ @Override
+ List<Exception> validateAnnotatable(
+ AnnotationValidator validator, FrameworkField field) {
+ return validator.validateAnnotatedField(field);
+ }
+ };
+}
diff --git a/src/main/java/org/junit/validator/PublicClassValidator.java b/src/main/java/org/junit/validator/PublicClassValidator.java
new file mode 100644
index 0000000..fe3f185
--- /dev/null
+++ b/src/main/java/org/junit/validator/PublicClassValidator.java
@@ -0,0 +1,33 @@
+package org.junit.validator;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
+import java.util.List;
+
+import org.junit.runners.model.TestClass;
+
+/**
+ * Validates that a {@link TestClass} is public.
+ *
+ * @since 4.12
+ */
+public class PublicClassValidator implements TestClassValidator {
+ private static final List<Exception> NO_VALIDATION_ERRORS = emptyList();
+
+ /**
+ * Validate that the specified {@link TestClass} is public.
+ *
+ * @param testClass the {@link TestClass} that is validated.
+ * @return an empty list if the class is public or a list with a single
+ * exception otherwise.
+ */
+ public List<Exception> validateTestClass(TestClass testClass) {
+ if (testClass.isPublic()) {
+ return NO_VALIDATION_ERRORS;
+ } else {
+ return singletonList(new Exception("The class "
+ + testClass.getName() + " is not public."));
+ }
+ }
+}
diff --git a/src/main/java/org/junit/validator/TestClassValidator.java b/src/main/java/org/junit/validator/TestClassValidator.java
new file mode 100644
index 0000000..43cb787
--- /dev/null
+++ b/src/main/java/org/junit/validator/TestClassValidator.java
@@ -0,0 +1,21 @@
+package org.junit.validator;
+
+import java.util.List;
+
+import org.junit.runners.model.TestClass;
+
+/**
+ * Validates a single facet of a test class.
+ *
+ * @since 4.12
+ */
+public interface TestClassValidator {
+ /**
+ * Validate a single facet of a test class.
+ *
+ * @param testClass
+ * the {@link TestClass} that is validated.
+ * @return the validation errors found by the validator.
+ */
+ public List<Exception> validateTestClass(TestClass testClass);
+}
diff --git a/src/main/java/org/junit/validator/ValidateWith.java b/src/main/java/org/junit/validator/ValidateWith.java
new file mode 100644
index 0000000..03d7906
--- /dev/null
+++ b/src/main/java/org/junit/validator/ValidateWith.java
@@ -0,0 +1,19 @@
+package org.junit.validator;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Allows for an {@link AnnotationValidator} to be attached to an annotation.
+ *
+ * <p>When attached to an annotation, the validator will be instantiated and invoked
+ * by the {@link org.junit.runners.ParentRunner}.</p>
+ *
+ * @since 4.12
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ValidateWith {
+ Class<? extends AnnotationValidator> value();
+}