最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - ArchUnit - rule to check there is less than N files (classes, interfaces, etc...) in a leaf package - Stack Overflow

programmeradmin3浏览0评论

What I would like to achieve is to write an ArchUnit rule to make sure our packages stay small enough.

For instance, suppose this:

natural
 ├─ goodpackage
 │  ├─ apple
 │  ├─ banana
 │  ├─ mango
 ├─ badpackage
 │  ├─ file1
 │  ├─ file2
 │  ├─ ...
 │  ├─ file10

For this example, let's say more than 9 files is too much, while up to 8 files is small enough.

This is also just for leaf packages, i.e. the most bottom level packages (if there are files in this package, but also sub packages, the test should aim to the sub packages)

I tried using the class com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes and was hoping to get a way to iterate inside a package. but no luck.

I also searched if we can directly get the packages from ArchUnit, something like:

    @Test
    void leafPackagesShouldNotHaveMoreThan9Files() {   }
        packages().that().areInSubPackages().shouldNot().have(moreThan9Files()).check(importedClasses);
    }

But also not possible.

How to check if there are less than N files in a leaf package with ArchUnit?

What I would like to achieve is to write an ArchUnit rule to make sure our packages stay small enough.

For instance, suppose this:

natural
 ├─ goodpackage
 │  ├─ apple
 │  ├─ banana
 │  ├─ mango
 ├─ badpackage
 │  ├─ file1
 │  ├─ file2
 │  ├─ ...
 │  ├─ file10

For this example, let's say more than 9 files is too much, while up to 8 files is small enough.

This is also just for leaf packages, i.e. the most bottom level packages (if there are files in this package, but also sub packages, the test should aim to the sub packages)

I tried using the class com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes and was hoping to get a way to iterate inside a package. but no luck.

I also searched if we can directly get the packages from ArchUnit, something like:

    @Test
    void leafPackagesShouldNotHaveMoreThan9Files() {   }
        packages().that().areInSubPackages().shouldNot().have(moreThan9Files()).check(importedClasses);
    }

But also not possible.

How to check if there are less than N files in a leaf package with ArchUnit?

Share Improve this question asked Feb 14 at 19:17 PatPandaPatPanda 5,04026 gold badges114 silver badges245 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You can probably use something like this:

import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaPackage;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.AbstractClassesTransformer;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.ClassesTransformer;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;

import static com.tngtech.archunit.base.DescribedPredicate.describe;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.all;
import static java.util.stream.Collectors.toSet;

...

@ArchTest
ArchRule leaf_packages_should_have_max_number_of_classes = all(packages())
        .that(are(describe("leaves", p -> p.getSubpackages().isEmpty())))
        .should(haveMaxNumberOfClasses(9));

static ClassesTransformer<JavaPackage> packages() {
    return new AbstractClassesTransformer<JavaPackage>("packages") {
        @Override
        public Iterable<JavaPackage> doTransform(JavaClasses javaClasses) {
            return javaClasses.stream().map(JavaClass::getPackage).collect(toSet());
        }
    };
}

static ArchCondition<JavaPackage> haveMaxNumberOfClasses(int maxNumberOfClasses) {
    return new ArchCondition<JavaPackage>("have at most " + maxNumberOfClasses + " classes") {
        @Override
        public void check(JavaPackage p, ConditionEvents events) {
            long numberOfClasses = p.getClasses().stream().count();
            boolean satisfied = numberOfClasses <= maxNumberOfClasses;
            String message = p.getDescription() + " contains " + numberOfClasses + " classes";
            events.add(new SimpleConditionEvent(p, satisfied, message));
        }
    };
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论