diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
index ca8f4d6839..cb2337d05a 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/Dependency.java
@@ -19,6 +19,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
@@ -51,6 +52,7 @@
*
a class (or method/constructor of this class) declares a type parameter referencing another class
* a class (or method/constructor of this class) is annotated with an annotation of a certain type or referencing another class as annotation parameter
* a method/constructor of a class references another class in a throws declaration
+ * a class references another class in a {@code catch} clause
* a class references another class object (e.g. {@code Example.class})
* a class references another class in an {@code instanceof} check
*
@@ -125,6 +127,12 @@ static Set tryCreateFromThrowsDeclaration(ThrowsDeclaration extend
return tryCreateDependency(declaration.getLocation(), "throws type", declaration.getRawType());
}
+ static Set tryCreateFromTryCatchBlock(TryCatchBlock tryCatchBlock) {
+ return tryCatchBlock.getCaughtThrowables().stream()
+ .flatMap(caughtThrowable -> tryCreateDependency(tryCatchBlock.getOwner(), "catches type", caughtThrowable, tryCatchBlock.getSourceCodeLocation()).stream())
+ .collect(Collectors.toSet());
+ }
+
static Set tryCreateFromInstanceofCheck(InstanceofCheck instanceofCheck) {
return tryCreateDependency(
instanceofCheck.getOwner(), "checks instanceof",
@@ -269,6 +277,10 @@ public String getDescription() {
return description;
}
+ /**
+ * @implNote For dependencies created by {@code catch} clauses, the line number reported currently refers to
+ * the first access in the {@code try} block, not to the {@code catch} clause.
+ */
@Override
@PublicAPI(usage = ACCESS)
public SourceCodeLocation getSourceCodeLocation() {
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
index e4480a4dae..02392e94f9 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java
@@ -646,6 +646,11 @@ public Set getInstanceofChecks() {
return members.getInstanceofChecks();
}
+ @PublicAPI(usage = ACCESS)
+ public Set getTryCatchBlocks() {
+ return members.getTryCatchBlocks();
+ }
+
@PublicAPI(usage = ACCESS)
public Set getReferencedClassObjects() {
return members.getReferencedClassObjects();
@@ -1310,6 +1315,14 @@ public Set> getMethodThrowsDeclarationsWithTypeOfS
return reverseDependencies.getMethodThrowsDeclarationsWithTypeOf(this);
}
+ /**
+ * @return {@link TryCatchBlock TryCatchBlocks} of all imported classes that declare to catch this class.
+ */
+ @PublicAPI(usage = ACCESS)
+ public Set getTryCatchBlocksThatCatchSelf() {
+ return reverseDependencies.getTryCatchBlocksThatCatch(this);
+ }
+
/**
* @return Constructors of all imported classes that have a parameter type of this class.
*/
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassDependencies.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassDependencies.java
index 35e29d4aa7..678383c36e 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassDependencies.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassDependencies.java
@@ -47,6 +47,7 @@ private Supplier> createDirectDependenciesFromClassSupplier() {
returnTypeDependenciesFromSelf(),
codeUnitParameterDependenciesFromSelf(),
throwsDeclarationDependenciesFromSelf(),
+ tryCatchBlockDependenciesFromSelf(),
annotationDependenciesFromSelf(),
instanceofCheckDependenciesFromSelf(),
referencedClassObjectDependenciesFromSelf(),
@@ -166,6 +167,11 @@ private Stream throwsDeclarationDependenciesFromSelf() {
.flatMap(throwsDeclaration -> Dependency.tryCreateFromThrowsDeclaration(throwsDeclaration).stream());
}
+ private Stream tryCatchBlockDependenciesFromSelf() {
+ return javaClass.getTryCatchBlocks().stream()
+ .flatMap(tryCatchBlock -> Dependency.tryCreateFromTryCatchBlock(tryCatchBlock).stream());
+ }
+
private Stream annotationDependenciesFromSelf() {
return Streams.concat(
annotationDependencies(javaClass),
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassMembers.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassMembers.java
index 1a5e1bcbbf..c797e60cb2 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassMembers.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClassMembers.java
@@ -191,6 +191,14 @@ Set getInstanceofChecks() {
return result.build();
}
+ Set getTryCatchBlocks() {
+ ImmutableSet.Builder result = ImmutableSet.builder();
+ for (JavaCodeUnit codeUnit : codeUnits) {
+ result.addAll(codeUnit.getTryCatchBlocks());
+ }
+ return result.build();
+ }
+
Set getReferencedClassObjects() {
ImmutableSet.Builder result = ImmutableSet.builder();
for (JavaCodeUnit codeUnit : codeUnits) {
diff --git a/archunit/src/main/java/com/tngtech/archunit/core/domain/ReverseDependencies.java b/archunit/src/main/java/com/tngtech/archunit/core/domain/ReverseDependencies.java
index e6a0fd7748..0e68259a7d 100644
--- a/archunit/src/main/java/com/tngtech/archunit/core/domain/ReverseDependencies.java
+++ b/archunit/src/main/java/com/tngtech/archunit/core/domain/ReverseDependencies.java
@@ -41,6 +41,7 @@ final class ReverseDependencies {
private final SetMultimap methodParameterTypeDependencies;
private final SetMultimap methodReturnTypeDependencies;
private final SetMultimap> methodsThrowsDeclarationDependencies;
+ private final SetMultimap tryCatchBlockDependencies;
private final SetMultimap constructorParameterTypeDependencies;
private final SetMultimap> constructorThrowsDeclarationDependencies;
private final SetMultimap> annotationTypeDependencies;
@@ -58,6 +59,7 @@ private ReverseDependencies(ReverseDependencies.Creation creation) {
this.methodParameterTypeDependencies = creation.methodParameterTypeDependencies.build();
this.methodReturnTypeDependencies = creation.methodReturnTypeDependencies.build();
this.methodsThrowsDeclarationDependencies = creation.methodsThrowsDeclarationDependencies.build();
+ this.tryCatchBlockDependencies = creation.tryCatchBlockDependencies.build();
this.constructorParameterTypeDependencies = creation.constructorParameterTypeDependencies.build();
this.constructorThrowsDeclarationDependencies = creation.constructorThrowsDeclarationDependencies.build();
this.annotationTypeDependencies = creation.annotationTypeDependencies.build();
@@ -114,6 +116,10 @@ Set> getMethodThrowsDeclarationsWithTypeOf(JavaCla
return methodsThrowsDeclarationDependencies.get(clazz);
}
+ Set getTryCatchBlocksThatCatch(JavaClass clazz) {
+ return tryCatchBlockDependencies.get(clazz);
+ }
+
Set getConstructorsWithParameterTypeOf(JavaClass clazz) {
return constructorParameterTypeDependencies.get(clazz);
}
@@ -150,6 +156,7 @@ static class Creation {
private final ImmutableSetMultimap.Builder methodParameterTypeDependencies = ImmutableSetMultimap.builder();
private final ImmutableSetMultimap.Builder methodReturnTypeDependencies = ImmutableSetMultimap.builder();
private final ImmutableSetMultimap.Builder> methodsThrowsDeclarationDependencies = ImmutableSetMultimap.builder();
+ private final ImmutableSetMultimap.Builder tryCatchBlockDependencies = ImmutableSetMultimap.builder();
private final ImmutableSetMultimap.Builder constructorParameterTypeDependencies = ImmutableSetMultimap.builder();
private final ImmutableSetMultimap.Builder> constructorThrowsDeclarationDependencies = ImmutableSetMultimap.builder();
private final ImmutableSetMultimap.Builder> annotationTypeDependencies = ImmutableSetMultimap.builder();
@@ -200,6 +207,11 @@ private void registerMethods(JavaClass clazz) {
for (ThrowsDeclaration throwsDeclaration : method.getThrowsClause()) {
methodsThrowsDeclarationDependencies.put(throwsDeclaration.getRawType(), throwsDeclaration);
}
+ for (TryCatchBlock tryCatchBlock : method.getTryCatchBlocks()) {
+ for (JavaClass caughtThrowable : tryCatchBlock.getCaughtThrowables()) {
+ tryCatchBlockDependencies.put(caughtThrowable.toErasure(), tryCatchBlock);
+ }
+ }
for (InstanceofCheck instanceofCheck : method.getInstanceofChecks()) {
instanceofCheckDependencies.put(instanceofCheck.getRawType(), instanceofCheck);
}
@@ -214,6 +226,11 @@ private void registerConstructors(JavaClass clazz) {
for (ThrowsDeclaration throwsDeclaration : constructor.getThrowsClause()) {
constructorThrowsDeclarationDependencies.put(throwsDeclaration.getRawType(), throwsDeclaration);
}
+ for (TryCatchBlock tryCatchBlock : constructor.getTryCatchBlocks()) {
+ for (JavaClass caughtThrowable : tryCatchBlock.getCaughtThrowables()) {
+ tryCatchBlockDependencies.put(caughtThrowable.toErasure(), tryCatchBlock);
+ }
+ }
for (InstanceofCheck instanceofCheck : constructor.getInstanceofChecks()) {
instanceofCheckDependencies.put(instanceofCheck.getRawType(), instanceofCheck);
}
@@ -252,11 +269,16 @@ private Set> findAnnotations(JavaClass clazz) {
}
private void registerStaticInitializer(JavaClass clazz) {
- if (clazz.getStaticInitializer().isPresent()) {
- for (InstanceofCheck instanceofCheck : clazz.getStaticInitializer().get().getInstanceofChecks()) {
+ clazz.getStaticInitializer().ifPresent(staticInitializer -> {
+ for (TryCatchBlock tryCatchBlock : staticInitializer.getTryCatchBlocks()) {
+ for (JavaClass caughtThrowable : tryCatchBlock.getCaughtThrowables()) {
+ tryCatchBlockDependencies.put(caughtThrowable.toErasure(), tryCatchBlock);
+ }
+ }
+ for (InstanceofCheck instanceofCheck : staticInitializer.getInstanceofChecks()) {
instanceofCheckDependencies.put(instanceofCheck.getRawType(), instanceofCheck);
}
- }
+ });
}
void finish(Iterable classes) {
diff --git a/archunit/src/test/java/com/tngtech/archunit/core/domain/DependencyTest.java b/archunit/src/test/java/com/tngtech/archunit/core/domain/DependencyTest.java
index f56e69dbd2..db06560861 100644
--- a/archunit/src/test/java/com/tngtech/archunit/core/domain/DependencyTest.java
+++ b/archunit/src/test/java/com/tngtech/archunit/core/domain/DependencyTest.java
@@ -13,6 +13,7 @@
import com.google.common.base.MoreObjects;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.testobjects.ClassWithArrayDependencies;
+import com.tngtech.archunit.core.domain.testobjects.ClassWithDependencyOnCaughtException;
import com.tngtech.archunit.core.domain.testobjects.ClassWithDependencyOnInstanceofCheck;
import com.tngtech.archunit.core.domain.testobjects.ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget;
import com.tngtech.archunit.core.domain.testobjects.DependenciesOnClassObjects;
@@ -200,6 +201,67 @@ public void Dependency_from_throws_declaration() {
.contains("Method <" + origin.getFullName() + "> throws type <" + IOException.class.getName() + ">");
}
+ @DataProvider
+ public static Object[][] with_try_catch_block_members() {
+ JavaClass javaClass = importClassesWithContext(ClassWithDependencyOnCaughtException.class, IOException.class)
+ .get(ClassWithDependencyOnCaughtException.class);
+
+ return $$(
+ $(javaClass.getStaticInitializer().get(), 9),
+ $(javaClass.getConstructor(), 16),
+ $(javaClass.getMethod("simpleCatchClauseMethod"), 23)
+ );
+ }
+
+ @Test
+ @UseDataProvider("with_try_catch_block_members")
+ public void Dependency_from_simple_catch_clause(JavaCodeUnit memberWithTryCatchBlock, int expectedLineNumber) {
+ TryCatchBlock tryCatchBlock = getOnlyElement(memberWithTryCatchBlock.getTryCatchBlocks());
+
+ Dependency dependency = getOnlyElement(Dependency.tryCreateFromTryCatchBlock(tryCatchBlock));
+
+ Assertions.assertThatDependency(dependency)
+ .satisfies(catchesType(IOException.class, memberWithTryCatchBlock, expectedLineNumber, ClassWithDependencyOnCaughtException.class));
+ }
+
+ private static Consumer catchesType(Class extends Throwable> targetClass, JavaCodeUnit javaCodeUnit, int expectedLineNumber, Class> originClass) {
+ return dependency -> Assertions.assertThatDependency(dependency)
+ .matches(originClass, targetClass)
+ .hasDescription(javaCodeUnit.getFullName(), "catches type", targetClass.getName())
+ .inLocation(originClass, expectedLineNumber);
+ }
+
+ @Test
+ public void Dependency_from_union_catch_clause() {
+ JavaMethod method = importClassesWithContext(ClassWithDependencyOnCaughtException.class, IllegalStateException.class, IOException.class)
+ .get(ClassWithDependencyOnCaughtException.class)
+ .getMethod("unionCatchClauseMethod");
+ TryCatchBlock tryCatchBlock = getOnlyElement(method.getTryCatchBlocks());
+
+ Set dependencies = Dependency.tryCreateFromTryCatchBlock(tryCatchBlock);
+
+ Assertions.assertThatDependencies(dependencies).satisfiesExactlyInAnyOrder(
+ catchesType(IllegalStateException.class, method, 30, ClassWithDependencyOnCaughtException.class),
+ catchesType(IOException.class, method, 30, ClassWithDependencyOnCaughtException.class)
+ );
+ }
+
+ @Test
+ public void Dependency_from_multiple_catch_clauses() {
+ JavaMethod method = importClassesWithContext(ClassWithDependencyOnCaughtException.class, IllegalStateException.class, IOException.class)
+ .get(ClassWithDependencyOnCaughtException.class)
+ .getMethod("multipleCatchClausesMethod");
+ TryCatchBlock tryCatchBlock = getOnlyElement(method.getTryCatchBlocks());
+
+ Set dependencies = Dependency.tryCreateFromTryCatchBlock(tryCatchBlock);
+
+ Assertions.assertThatDependencies(dependencies).satisfiesExactlyInAnyOrder(
+ catchesType(IllegalStateException.class, method, 37, ClassWithDependencyOnCaughtException.class),
+ catchesType(RuntimeException.class, method, 37, ClassWithDependencyOnCaughtException.class),
+ catchesType(IOException.class, method, 37, ClassWithDependencyOnCaughtException.class)
+ );
+ }
+
@DataProvider
public static Object[][] with_instanceof_check_members() {
JavaClass javaClass = importClassesWithContext(ClassWithDependencyOnInstanceofCheck.class, InstanceOfCheckTarget.class)
diff --git a/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaClassTest.java b/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaClassTest.java
index c08fc3ac32..2b0ecdcfea 100644
--- a/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaClassTest.java
+++ b/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaClassTest.java
@@ -26,13 +26,19 @@
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.base.HasDescription;
import com.tngtech.archunit.core.domain.testobjects.AAccessingB;
+import com.tngtech.archunit.core.domain.testobjects.ACatchingBException;
import com.tngtech.archunit.core.domain.testobjects.AExtendingSuperAImplementingInterfaceForA;
import com.tngtech.archunit.core.domain.testobjects.AReferencingB;
+import com.tngtech.archunit.core.domain.testobjects.AThrowingBException;
import com.tngtech.archunit.core.domain.testobjects.AhavingMembersOfTypeB;
import com.tngtech.archunit.core.domain.testobjects.AllPrimitiveDependencies;
import com.tngtech.archunit.core.domain.testobjects.ArrayComponentTypeDependencies;
import com.tngtech.archunit.core.domain.testobjects.B;
+import com.tngtech.archunit.core.domain.testobjects.BException1;
+import com.tngtech.archunit.core.domain.testobjects.BException2;
+import com.tngtech.archunit.core.domain.testobjects.BException3;
import com.tngtech.archunit.core.domain.testobjects.BReferencedByA;
+import com.tngtech.archunit.core.domain.testobjects.ClassWithDependencyOnInstanceofCheck;
import com.tngtech.archunit.core.domain.testobjects.ComponentTypeDependency;
import com.tngtech.archunit.core.domain.testobjects.DependenciesOnClassObjects;
import com.tngtech.archunit.core.domain.testobjects.InterfaceForA;
@@ -808,26 +814,159 @@ public void direct_dependencies_from_self_by_member_declarations() {
JavaClass javaClass = importClasses(AhavingMembersOfTypeB.class, B.class).get(AhavingMembersOfTypeB.class);
assertThat(javaClass.getDirectDependenciesFromSelf())
- .areAtLeastOne(methodReturnTypeDependency()
+ .areAtLeastOne(fieldTypeDependency()
.from(AhavingMembersOfTypeB.class)
.to(B.class)
.inLineNumber(0))
- .areAtLeastOne(methodThrowsDeclarationDependency()
+ .areAtLeastOne(methodReturnTypeDependency()
.from(AhavingMembersOfTypeB.class)
- .to(B.BException.class)
+ .to(B.class)
.inLineNumber(0))
.areAtLeast(2, parameterTypeDependency()
+ .from(AhavingMembersOfTypeB.class)
+ .to(B.class)
+ .inLineNumber(0));
+ }
+
+ @Test
+ public void direct_dependencies_to_self_by_member_declarations() {
+ JavaClass javaClass = importClassesWithContext(AhavingMembersOfTypeB.class, B.class).get(B.class);
+
+ assertThat(javaClass.getDirectDependenciesToSelf())
+ .areAtLeastOne(fieldTypeDependency()
.from(AhavingMembersOfTypeB.class)
.to(B.class)
.inLineNumber(0))
- .areAtLeastOne(methodChecksInstanceOfDependency()
+ .areAtLeastOne(methodReturnTypeDependency()
.from(AhavingMembersOfTypeB.class)
.to(B.class)
- .inLineNumber(7))
- .areAtLeastOne(methodChecksInstanceOfDependency()
+ .inLineNumber(0))
+ .areAtLeast(2, parameterTypeDependency()
.from(AhavingMembersOfTypeB.class)
.to(B.class)
- .inLineNumber(25));
+ .inLineNumber(0));
+ }
+
+ @Test
+ public void direct_dependencies_from_self_by_instanceof_checks() {
+ JavaClass javaClass = importClasses(ClassWithDependencyOnInstanceofCheck.class, ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .get(ClassWithDependencyOnInstanceofCheck.class);
+
+ assertThat(javaClass.getDirectDependenciesFromSelf())
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(6))
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(9))
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(13));
+ }
+
+ @Test
+ public void direct_dependencies_to_self_by_instanceof_checks() {
+ JavaClass javaClass = importClasses(ClassWithDependencyOnInstanceofCheck.class, ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .get(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class);
+
+ assertThat(javaClass.getDirectDependenciesToSelf())
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(6))
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(9))
+ .areAtLeastOne(methodChecksInstanceOfDependency()
+ .from(ClassWithDependencyOnInstanceofCheck.class)
+ .to(ClassWithDependencyOnInstanceofCheck.InstanceOfCheckTarget.class)
+ .inLineNumber(13));
+ }
+
+ @Test
+ public void direct_dependencies_from_self_by_catch_clauses() {
+ JavaClass javaClass = importClasses(ACatchingBException.class, BException1.class)
+ .get(ACatchingBException.class);
+
+ assertThat(javaClass.getDirectDependenciesFromSelf())
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(7))
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(14))
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(21));
+ }
+
+ @Test
+ public void direct_dependencies_to_self_by_catch_clause() {
+ JavaClass javaClass = importClasses(ACatchingBException.class, BException1.class)
+ .get(BException1.class);
+
+ assertThat(javaClass.getDirectDependenciesToSelf())
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(7))
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(14))
+ .areAtLeastOne(codeUnitTryCatchDependency()
+ .from(ACatchingBException.class)
+ .to(BException1.class)
+ .inLineNumber(21));
+ }
+
+ @Test
+ public void direct_dependencies_from_self_by_throws_clause() {
+ JavaClass javaClass = importClasses(AThrowingBException.class, BException1.class, BException2.class, BException3.class)
+ .get(AThrowingBException.class);
+
+ assertThat(javaClass.getDirectDependenciesFromSelf())
+ .areAtLeastOne(methodThrowsDeclarationDependency()
+ .from(AThrowingBException.class)
+ .to(BException1.class)
+ .inLineNumber(0))
+ .areAtLeastOne(methodThrowsDeclarationDependency()
+ .from(AThrowingBException.class)
+ .to(BException2.class)
+ .inLineNumber(0))
+ .areAtLeastOne(methodThrowsDeclarationDependency()
+ .from(AThrowingBException.class)
+ .to(BException3.class)
+ .inLineNumber(0));
+ }
+
+ @DataProvider
+ public static Object[][] with_throws_dependencies() {
+ return $$(
+ $(BException1.class, AThrowingBException.class, 0),
+ $(BException2.class, AThrowingBException.class, 0),
+ $(BException3.class, AThrowingBException.class, 0)
+ );
+ }
+
+ @Test
+ @UseDataProvider("with_throws_dependencies")
+ public void direct_dependencies_to_self_by_throws_clause(Class extends Throwable> selfClass, Class> throwingClass, int expectedLineNumber) {
+ JavaClass javaClass = importClasses(selfClass, throwingClass)
+ .get(selfClass);
+
+ assertThat(javaClass.getDirectDependenciesToSelf())
+ .areAtLeastOne(methodThrowsDeclarationDependency()
+ .from(throwingClass)
+ .to(selfClass)
+ .inLineNumber(expectedLineNumber));
}
@Test
@@ -1282,42 +1421,6 @@ void method(List irrelevant, SecondGenericType