Search code examples
archunit

In Archunit, is it possible to convert a definition into a predicate?


Is it possible at all to convert a definition into a predicate?

I want to do a test to forbid any class in my system to call a static method defined elsewhere (in my case it is "com.vaadin.flow.internal.StringUtil"). I've achieved that by doing:

        ArchRuleDefinition.noClasses().should().callMethodWhere(
                JavaAccess.Predicates.targetOwner(JavaClass.Predicates
                        .assignableTo("com.vaadin.flow.internal.StringUtil")))
                .check(new ClassFileImporter()
                        .importPackages("com.example.application"));

However, ArchUnit already provides this nice definition:

ArchRuleDefinition.methods().that()
                        .areDeclaredIn("com.vaadin.flow.internal.StringUtil")

So, I could make my test easier to understand if I could do something like:

        ArchRuleDefinition.noClasses().should()
                .callMethodWhere(transformInPredicate(ArchRuleDefinition.methods().that()
                        .areDeclaredIn("com.vaadin.flow.internal.StringUtil")))
                .check(new ClassFileImporter()
                        .importPackages("com.example.application"));

is it possible at all?


Solution

  • ArchUnit does not provide a way to convert an ArchRule into a DescribedPredicate.

    However, every predicate that is available in the fluent rule API is also available as static method. With these methods you could compose your own predicates and reuse them in multiple places. Using static imports makes the code even more readable.

    You could rewrite your rule like this:

    import static com.tngtech.archunit.core.domain.AccessTarget.Predicates.declaredIn;
    import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.target;
    import static com.tngtech.archunit.lang.conditions.ArchPredicates.is;
    import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
    
    ArchRule rule = noClasses().should().callMethodWhere(target(is(declaredIn("com.vaadin.flow.internal.StringUtil"))));
    rule.check(..);