Skip to content

Commit 507f675

Browse files
authored
add anyParameterThat and allParameters predicates (#1498)
In another project I'm writing rules about method parameter annotations, and it seems like support for that in the DSL would make sense. This change is the first step towards that, it extracts a HasParameters interface from JavaCodeUnit and provides DescribedPredicates for - checking that any parameter matches - checking that all parameters match
2 parents 49e32aa + b0922cc commit 507f675

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

archunit/src/main/java/com/tngtech/archunit/core/domain/JavaCodeUnit.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public List<JavaType> getParameterTypes() {
131131
}
132132

133133
/**
134-
* @return the {@link JavaParameter parameters} of this {@link JavaCodeUnit}. On the contrary to the Reflection API this will only contain
134+
* @return the {@link JavaParameter parameters} of this {@link JavaCodeUnit}. In contrast to the Reflection API this will only contain
135135
* the parameters from the signature and not synthetic parameters, if the signature is generic. In these cases
136136
* {@link #getParameters()}{@code .size()} will always be equal to {@link #getParameterTypes()}{@code .size()},
137137
* but not necessarily to {@link #getRawParameterTypes()}{@code .size()} in case the compiler adds synthetic parameters.<br>
@@ -411,6 +411,26 @@ public boolean test(JavaCodeUnit input) {
411411
}
412412
};
413413
}
414+
415+
/**
416+
* @param predicate A {@link DescribedPredicate} for the {@link JavaParameter}s of the {@link JavaCodeUnit}
417+
* @return A {@link DescribedPredicate predicate} for a {@link JavaCodeUnit} that returns {@code true}
418+
* if and only if at least one {@link JavaParameter} of the {@link JavaCodeUnit} matches the given predicate.
419+
*/
420+
@PublicAPI(usage = ACCESS)
421+
public static DescribedPredicate<JavaCodeUnit> anyParameterThat(DescribedPredicate<? super JavaParameter> predicate) {
422+
return DescribedPredicate.anyElementThat(predicate).onResultOf(JavaCodeUnit::getParameters).as("any parameter that %s", predicate.getDescription());
423+
}
424+
425+
/**
426+
* @param predicate A {@link DescribedPredicate} for the {@link JavaParameter}s of the {@link JavaCodeUnit}
427+
* @return A {@link DescribedPredicate predicate} for a {@link JavaCodeUnit} that returns {@code true}
428+
* if and only if all {@link JavaParameter}s of the {@link JavaCodeUnit} match the given predicate.
429+
*/
430+
@PublicAPI(usage = ACCESS)
431+
public static DescribedPredicate<JavaCodeUnit> allParameters(DescribedPredicate<? super JavaParameter> predicate) {
432+
return DescribedPredicate.<JavaParameter>allElements(predicate).onResultOf(JavaCodeUnit::getParameters).as("all parameters %s", predicate.getDescription());
433+
}
414434
}
415435

416436
/**

archunit/src/test/java/com/tngtech/archunit/core/domain/JavaCodeUnitTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Set;
99

1010
import com.google.common.collect.ImmutableList;
11+
import com.tngtech.archunit.base.DescribedPredicate;
1112
import com.tngtech.archunit.core.importer.ClassFileImporter;
1213
import com.tngtech.java.junit.dataprovider.DataProvider;
1314
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
@@ -18,9 +19,13 @@
1819
import static com.google.common.collect.Lists.newArrayList;
1920
import static com.google.common.collect.Sets.union;
2021
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.equivalentTo;
22+
import static com.tngtech.archunit.core.domain.JavaCodeUnit.Predicates.allParameters;
23+
import static com.tngtech.archunit.core.domain.JavaCodeUnit.Predicates.anyParameterThat;
2124
import static com.tngtech.archunit.core.domain.JavaParameter.startWithLowercase;
2225
import static com.tngtech.archunit.core.domain.TestUtils.importClassWithContext;
2326
import static com.tngtech.archunit.core.domain.properties.HasType.Functions.GET_RAW_TYPE;
27+
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
28+
import static com.tngtech.archunit.lang.conditions.ArchPredicates.is;
2429
import static com.tngtech.archunit.testutil.Assertions.assertThat;
2530
import static com.tngtech.archunit.testutil.Assertions.assertThatAnnotation;
2631
import static com.tngtech.archunit.testutil.Assertions.assertThatTypes;
@@ -326,6 +331,32 @@ void method(@SomeParameterAnnotation("test") String param) {
326331
assertThat(parameter.tryGetAnnotationOfType(Deprecated.class.getName())).isEmpty();
327332
}
328333

334+
@Test
335+
public void predicate_on_any_parameter() {
336+
JavaClass someClass = importClassWithContext(SomeClass.class);
337+
DescribedPredicate<JavaParameter> stringTyped = equivalentTo(String.class).onResultOf(JavaParameter::getRawType);
338+
339+
DescribedPredicate<JavaCodeUnit> predicate = anyParameterThat(is(stringTyped));
340+
341+
assertThat(predicate).hasDescription("any parameter that is equivalent to java.lang.String")
342+
.accepts(someClass.getMethod("method", String.class, String.class))
343+
.accepts(someClass.getMethod("method", String.class, Integer.class))
344+
.rejects(someClass.getMethod("method", Integer.class, Integer.class));
345+
}
346+
347+
@Test
348+
public void predicate_on_all_parameters() {
349+
JavaClass someClass = importClassWithContext(SomeClass.class);
350+
DescribedPredicate<JavaParameter> stringTyped = equivalentTo(String.class).onResultOf(JavaParameter::getRawType);
351+
352+
DescribedPredicate<JavaCodeUnit> predicate = allParameters(are(stringTyped));
353+
354+
assertThat(predicate).hasDescription("all parameters are equivalent to java.lang.String")
355+
.accepts(someClass.getMethod("method", String.class, String.class))
356+
.rejects(someClass.getMethod("method", String.class, Integer.class))
357+
.rejects(someClass.getMethod("method", Integer.class, Integer.class));
358+
}
359+
329360
@SuppressWarnings("unused")
330361
private static class ClassWithVariousCodeUnitParameters {
331362
ClassWithVariousCodeUnitParameters(Object simple, String noParameterizedTypes) {
@@ -379,6 +410,18 @@ enum NonTrivialEnum {
379410
}
380411
}
381412

413+
@SuppressWarnings("unused")
414+
private static class SomeClass {
415+
void method(Integer a, Integer b) {
416+
}
417+
418+
void method(String l, String r) {
419+
}
420+
421+
void method(String s, Integer i) {
422+
}
423+
}
424+
382425
@interface SomeMetaAnnotation {
383426
}
384427

0 commit comments

Comments
 (0)