com.tngtech.archunit.junit.ArchRuleDeclaration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of archunit-junit4 Show documentation
Show all versions of archunit-junit4 Show documentation
A Java architecture test library, to specify and assert architecture rules in plain Java - Module 'archunit-junit4'
/*
* Copyright 2014-2021 TNG Technology Consulting GmbH
*
* 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.tngtech.archunit.junit;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.tngtech.archunit.junit.ArchTestExecution.getValue;
import static com.tngtech.archunit.junit.ReflectionUtils.getAllFields;
import static com.tngtech.archunit.junit.ReflectionUtils.getAllMethods;
import static com.tngtech.archunit.junit.ReflectionUtils.withAnnotation;
abstract class ArchRuleDeclaration {
private final Class> testClass;
final T declaration;
final Class> owner;
private final boolean forceIgnore;
ArchRuleDeclaration(Class> testClass, T declaration, Class> owner, boolean forceIgnore) {
this.testClass = testClass;
this.declaration = declaration;
this.owner = owner;
this.forceIgnore = forceIgnore;
}
abstract void handleWith(Handler handler);
private static ArchRuleDeclaration from(Class> testClass, Method method, Class> methodOwner, boolean forceIgnore) {
return new AsMethod(testClass, method, methodOwner, forceIgnore);
}
private static ArchRuleDeclaration from(Class> testClass, Field field, Class> fieldOwner, boolean forceIgnore) {
return new AsField(testClass, field, fieldOwner, forceIgnore);
}
static boolean elementShouldBeIgnored(T member) {
return elementShouldBeIgnored(member.getDeclaringClass(), member);
}
static boolean elementShouldBeIgnored(Class> testClass, AnnotatedElement ruleDeclaration) {
return testClass.getAnnotation(ArchIgnore.class) != null ||
ruleDeclaration.getAnnotation(ArchIgnore.class) != null;
}
boolean shouldBeIgnored() {
return forceIgnore || elementShouldBeIgnored(testClass, declaration);
}
static Set> toDeclarations(
ArchTests archTests, Class> testClass, Class extends Annotation> archTestAnnotationType, boolean forceIgnore) {
ImmutableSet.Builder> result = ImmutableSet.builder();
Class> definitionLocation = archTests.getDefinitionLocation();
for (Field field : getAllFields(definitionLocation, withAnnotation(archTestAnnotationType))) {
result.addAll(archRuleDeclarationsFrom(testClass, field, definitionLocation, archTestAnnotationType, forceIgnore));
}
for (Method method : getAllMethods(definitionLocation, withAnnotation(archTestAnnotationType))) {
result.add(ArchRuleDeclaration.from(testClass, method, definitionLocation, forceIgnore));
}
return result.build();
}
private static Set> archRuleDeclarationsFrom(Class> testClass, Field field, Class> fieldOwner,
Class extends Annotation> archTestAnnotationType, boolean forceIgnore) {
return ArchTests.class.isAssignableFrom(field.getType()) || ArchRules.class.isAssignableFrom(field.getType()) ?
toDeclarations(getArchRulesIn(field, fieldOwner), testClass, archTestAnnotationType, forceIgnore || elementShouldBeIgnored(field)) :
Collections.>singleton(ArchRuleDeclaration.from(testClass, field, fieldOwner, forceIgnore));
}
private static ArchTests getArchRulesIn(Field field, Class> fieldOwner) {
ArchTests value = ArchTests.from(getValue(field, fieldOwner));
return checkNotNull(value, "Field %s.%s is not initialized", fieldOwner.getName(), field.getName());
}
private static class AsMethod extends ArchRuleDeclaration {
AsMethod(Class> testClass, Method method, Class> methodOwner, boolean forceIgnore) {
super(testClass, method, methodOwner, forceIgnore);
}
@Override
void handleWith(Handler handler) {
handler.handleMethodDeclaration(declaration, owner, shouldBeIgnored());
}
}
private static class AsField extends ArchRuleDeclaration {
AsField(Class> testClass, Field field, Class> fieldOwner, boolean forceIgnore) {
super(testClass, field, fieldOwner, forceIgnore);
}
@Override
void handleWith(Handler handler) {
handler.handleFieldDeclaration(declaration, owner, shouldBeIgnored());
}
}
interface Handler {
void handleFieldDeclaration(Field field, Class> fieldOwner, boolean ignore);
void handleMethodDeclaration(Method method, Class> methodOwner, boolean ignore);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy