package com.tngtech.archunit.exampletest;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaCall;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.example.ClassViolatingThirdPartyRules;
import com.tngtech.archunit.example.thirdparty.ThirdPartyClassWithProblem;
import com.tngtech.archunit.example.thirdparty.ThirdPartyClassWorkaroundFactory;
import com.tngtech.archunit.lang.ArchCondition;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static com.tngtech.archunit.base.DescribedPredicate.not;
import static com.tngtech.archunit.core.domain.AccessTarget.Predicates.constructor;
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.originOwner;
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.targetOwner;
import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.equivalentTo;
import static com.tngtech.archunit.lang.conditions.ArchConditions.callCodeUnitWhere;
import static com.tngtech.archunit.lang.conditions.ArchConditions.never;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.is;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
public class ThirdPartyRulesTest {
protected static final String THIRD_PARTY_CLASS_RULE_TEXT =
"not instantiate " +
ThirdPartyClassWithProblem.class.getSimpleName() +
" and its subclasses, but instead use " +
ThirdPartyClassWorkaroundFactory.class.getSimpleName();
private JavaClasses classes;
@Before
public void setUp() throws Exception {
classes = new ClassFileImportHelper().importTreesOf(ClassViolatingThirdPartyRules.class);
}
@Ignore
@Test
public void third_party_class_should_only_be_instantiated_via_workaround() {
classes().should(notCreateProblematicClassesOutsideOfWorkaroundFactory()
.as(THIRD_PARTY_CLASS_RULE_TEXT))
.check(classes);
}
private ArchCondition<JavaClass> notCreateProblematicClassesOutsideOfWorkaroundFactory() {
DescribedPredicate<JavaCall<?>> constructorCallOfThirdPartyClass =
target(is(constructor())).and(targetOwner(is(assignableTo(ThirdPartyClassWithProblem.class))));
DescribedPredicate<JavaCall<?>> notFromWithinThirdPartyClass =
originOwner(is(not(assignableTo(ThirdPartyClassWithProblem.class)))).forSubType();
DescribedPredicate<JavaCall<?>> notFromWorkaroundFactory =
originOwner(is(not(equivalentTo(ThirdPartyClassWorkaroundFactory.class)))).forSubType();
DescribedPredicate<JavaCall<?>> targetIsIllegalConstructorOfThirdPartyClass =
constructorCallOfThirdPartyClass.
and(notFromWithinThirdPartyClass).
and(notFromWorkaroundFactory);
return never(callCodeUnitWhere(targetIsIllegalConstructorOfThirdPartyClass));
}
}