GH-578 - Support for nested application modules.
The ApplicationModules bootstrap now triggers the module base package detection, followed by a new, additional pass of detecting nested application module packages. Those packages are now added to the ones we create ApplicationModule instances for and also handed into the module instance creation step as exclusions to make sure that parent modules do not include code residing in sub-modules. The bootstrap of ApplicationModules now uses a dedicated ApplicationModuleSource to allow calculating a default module name relative to the application base package. Each module now operates on the Classes instance obtained from the JavaPackage instance that constitutes the module's base package but filtered by the given exclusions.
This commit is contained in:
committed by
Oliver Drotbohm
parent
b927bf1211
commit
7838204c25
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.empty;
|
||||
package empty;
|
||||
|
||||
import org.springframework.modulith.Modulithic;
|
||||
|
||||
@@ -21,6 +21,4 @@ import org.springframework.modulith.Modulithic;
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Modulithic
|
||||
public class EmptyApplication {
|
||||
|
||||
}
|
||||
public class EmptyApplication {}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.invalid;
|
||||
|
||||
import example.ni.nested.InNested;
|
||||
import example.ni.nested.b.first.InNestedBFirst;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class Invalid {
|
||||
InNested invalid;
|
||||
InNestedBFirst invalidToo;
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
@org.jmolecules.ddd.annotation.Module
|
||||
package jmolecules;
|
||||
package example.jmolecules;
|
||||
@@ -15,7 +15,17 @@
|
||||
*/
|
||||
package example.ni;
|
||||
|
||||
import example.ni.nested.b.first.InNestedBFirst;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public interface RootType {}
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RootType {
|
||||
|
||||
final InNestedBFirst inNestedBFirst;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.ni.nested;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class InNested {}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.ni.nested.a;
|
||||
|
||||
import example.ni.internal.Internal;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class InNestedA {
|
||||
Internal internal;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.ni.nested.b;
|
||||
|
||||
import example.ni.RootType;
|
||||
import example.ni.nested.b.first.InNestedBFirst;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class InNestedB {
|
||||
|
||||
final InNestedBFirst downward;
|
||||
final RootType upward;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.ni.nested.b.first;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
@Component
|
||||
public class InNestedBFirst {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@org.springframework.modulith.ApplicationModule
|
||||
package example.ni.nested.b.first;
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package example.ni.nested.b.second;
|
||||
|
||||
import example.ni.nested.InNested;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
public class InNestedBSecond {
|
||||
InNested inNested;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@org.springframework.modulith.ApplicationModule
|
||||
package example.ni.nested.b.second;
|
||||
@@ -0,0 +1,2 @@
|
||||
@org.springframework.modulith.ApplicationModule
|
||||
package example.ni.nested;
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.modulith.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ApplicationModules}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class ApplicationModulesUnitTests {
|
||||
|
||||
ApplicationModules modules = TestUtils.of("example", "example.ninvalid");
|
||||
|
||||
@Test // GH 578
|
||||
void discoversComplexModuleArrangement() {
|
||||
|
||||
assertThat(modules)
|
||||
.extracting(ApplicationModule::getName)
|
||||
.containsExactlyInAnyOrder(
|
||||
"invalid",
|
||||
"jmolecules",
|
||||
"ni",
|
||||
"ni.nested",
|
||||
"ni.nested.b.first",
|
||||
"ni.nested.b.second",
|
||||
"springbean");
|
||||
}
|
||||
|
||||
@Test // GH 578
|
||||
void detectsModuleNesting() {
|
||||
|
||||
var ni = modules.getModuleByName("ni").orElseThrow();
|
||||
var nested = modules.getModuleByName("ni.nested").orElseThrow();
|
||||
var inner = modules.getModuleByName("ni.nested.b.first").orElseThrow();
|
||||
|
||||
assertThat(inner.getParentModule(modules)).hasValue(nested);
|
||||
assertThat(nested.getParentModule(modules)).hasValue(ni);
|
||||
assertThat(ni.getParentModule(modules)).isEmpty();
|
||||
|
||||
assertThat(ni.getDirectlyNestedModules(modules))
|
||||
.extracting(ApplicationModule::getName)
|
||||
.containsExactlyInAnyOrder("ni.nested");
|
||||
|
||||
assertThat(ni.getNestedModules(modules))
|
||||
.extracting(ApplicationModule::getName)
|
||||
.containsExactlyInAnyOrder("ni.nested", "ni.nested.b.first", "ni.nested.b.second");
|
||||
}
|
||||
|
||||
@Test // GH 578
|
||||
void detectsInvalidReferenceToNestedModule() {
|
||||
|
||||
var violations = modules.detectViolations();
|
||||
var messages = violations.getMessages();
|
||||
|
||||
assertThat(messages)
|
||||
.hasSize(3)
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
it -> assertThat(it).contains("Invalid", "'invalid'", "'ni.nested'"),
|
||||
it -> assertThat(it).contains("Invalid", "'invalid'", "'ni.nested.b.first'"),
|
||||
it -> assertThat(it).contains("Invalid", "'ni'", "'ni.nested.b.first'"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.modulith.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import example.ni.nested.a.InNestedA;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.tngtech.archunit.core.domain.JavaClass;
|
||||
import com.tngtech.archunit.core.domain.JavaClasses;
|
||||
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||
import com.tngtech.archunit.core.importer.ImportOption;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JavaPackage}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class JavaPackageUnitTests {
|
||||
|
||||
static final JavaClasses ALL_CLASSES = new ClassFileImporter() //
|
||||
.withImportOption(ImportOption.Predefined.ONLY_INCLUDE_TESTS)
|
||||
.importPackages("example");
|
||||
|
||||
Classes classes = Classes.of(ALL_CLASSES);
|
||||
JavaPackage pkg = JavaPackage.of(classes, "example.ni");
|
||||
|
||||
@Test // GH-578
|
||||
void detectsDirectSubPackages() throws Exception {
|
||||
|
||||
assertThat(pkg.getLocalName()).isEqualTo("ni");
|
||||
assertThat(pkg.getDirectSubPackages()) //
|
||||
.extracting(JavaPackage::getLocalName) //
|
||||
.containsExactlyInAnyOrder("api", "internal", "nested", "ontype", "spi");
|
||||
}
|
||||
|
||||
@Test // GH-578
|
||||
void detectsAllSubPackages() {
|
||||
|
||||
var subPackages = pkg.getSubPackages();
|
||||
|
||||
assertThat(subPackages.stream()
|
||||
.map(JavaPackage::getPackageName)
|
||||
.map(it -> it.getLocalName("example.ni")))
|
||||
.containsExactly(
|
||||
"api",
|
||||
"internal",
|
||||
"nested",
|
||||
"nested.a",
|
||||
"nested.b",
|
||||
"nested.b.first",
|
||||
"nested.b.second",
|
||||
"ontype",
|
||||
"spi");
|
||||
}
|
||||
|
||||
@Test // GH-578
|
||||
void detectsFlattenedSubPackages() {
|
||||
|
||||
var subPackages = pkg.getSubPackages();
|
||||
|
||||
assertThat(subPackages.flatten().stream()
|
||||
.map(JavaPackage::getPackageName)
|
||||
.map(it -> it.getLocalName("example.ni")))
|
||||
.containsExactlyInAnyOrder("api", "internal", "nested", "ontype", "spi");
|
||||
}
|
||||
|
||||
@Test // GH-578
|
||||
void considersExclusionsForClassesLookup() {
|
||||
|
||||
assertThat(pkg.contains(InNestedA.class.getName()));
|
||||
|
||||
var nestedA = JavaPackage.of(classes, "example.ni.nested.a");
|
||||
assertThat(nestedA.contains(InNestedA.class.getName()));
|
||||
|
||||
assertThat(pkg.getClasses(List.of(nestedA)).stream().map(JavaClass::getName))
|
||||
.doesNotContain(InNestedA.class.getName());
|
||||
}
|
||||
|
||||
@Test // GH-578
|
||||
void detectsSubPackage() {
|
||||
|
||||
var classes = Classes.of(ALL_CLASSES);
|
||||
var root = JavaPackage.of(classes, "example.ni");
|
||||
var direct = JavaPackage.of(classes, "example.ni.internal");
|
||||
var nested = JavaPackage.of(classes, "example.ni.internal.nested");
|
||||
|
||||
assertThat(direct.isSubPackageOf(root)).isTrue();
|
||||
assertThat(nested.isSubPackageOf(root)).isTrue();
|
||||
assertThat(nested.isSubPackageOf(direct)).isTrue();
|
||||
}
|
||||
|
||||
@Test // GH-578
|
||||
void samePackagesConsideredEqual() {
|
||||
|
||||
var first = JavaPackage.of(classes, "example.ni");
|
||||
var second = JavaPackage.of(classes, "example.ni");
|
||||
|
||||
assertThat(first.equals(second)).isTrue();
|
||||
assertThat(second.equals(first)).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -34,11 +34,12 @@ class ModuleDetectionStrategyUnitTest {
|
||||
|
||||
var classes = new ClassFileImporter() //
|
||||
.withImportOption(new ImportOption.OnlyIncludeTests()) //
|
||||
.importPackages("jmolecules");
|
||||
.importPackages("example.jmolecules");
|
||||
|
||||
var javaPackage = JavaPackage.of(Classes.of(classes), "jmolecules");
|
||||
var javaPackage = JavaPackage.of(Classes.of(classes), "example");
|
||||
var expected = javaPackage.getSubPackage("jmolecules").orElseThrow();
|
||||
|
||||
assertThat(ApplicationModuleDetectionStrategy.explicitlyAnnotated().getModuleBasePackages(javaPackage))
|
||||
.containsExactly(javaPackage);
|
||||
.containsExactly(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ import com.acme.withatbean.SampleAggregate;
|
||||
import com.acme.withatbean.TestEvents.JMoleculesAnnotated;
|
||||
import com.acme.withatbean.TestEvents.JMoleculesImplementing;
|
||||
import com.tngtech.archunit.core.domain.JavaClass;
|
||||
import com.tngtech.archunit.core.domain.JavaClasses;
|
||||
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ApplicationModule}.
|
||||
@@ -45,10 +43,7 @@ import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||
class ModuleUnitTest {
|
||||
|
||||
String packageName = "com.acme.withatbean";
|
||||
JavaClasses classes = new ClassFileImporter().importPackages(packageName);
|
||||
JavaPackage javaPackage = JavaPackage.of(Classes.of(classes), packageName);
|
||||
|
||||
ApplicationModule module = new ApplicationModule(javaPackage, false);
|
||||
ApplicationModule module = TestUtils.getApplicationModule(packageName);
|
||||
|
||||
@Test
|
||||
public void considersExternalSpringBeans() {
|
||||
@@ -61,8 +56,10 @@ class ModuleUnitTest {
|
||||
@Test
|
||||
void discoversPublishedEvents() {
|
||||
|
||||
JavaClass jMoleculesAnnotated = classes.get(JMoleculesAnnotated.class);
|
||||
JavaClass jMoleculesImplementing = classes.get(JMoleculesImplementing.class);
|
||||
var classes = module.getClasses();
|
||||
|
||||
JavaClass jMoleculesAnnotated = classes.getRequiredClass(JMoleculesAnnotated.class);
|
||||
JavaClass jMoleculesImplementing = classes.getRequiredClass(JMoleculesImplementing.class);
|
||||
|
||||
List<EventType> events = module.getPublishedEvents();
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ import example.ni.api.ApiType;
|
||||
import example.ni.internal.AdditionalSpiType;
|
||||
import example.ni.internal.DefaultedNamedInterfaceType;
|
||||
import example.ni.internal.Internal;
|
||||
import example.ni.nested.InNested;
|
||||
import example.ni.nested.a.InNestedA;
|
||||
import example.ni.nested.b.InNestedB;
|
||||
import example.ni.nested.b.first.InNestedBFirst;
|
||||
import example.ni.nested.b.second.InNestedBSecond;
|
||||
import example.ni.ontype.Exposed;
|
||||
import example.ni.spi.SpiType;
|
||||
import example.ninvalid.InvalidDefaultNamedInterface;
|
||||
@@ -62,7 +67,8 @@ class NamedInterfacesUnitTests {
|
||||
|
||||
var javaPackage = TestUtils.getPackage(InvalidDefaultNamedInterface.class);
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() -> NamedInterfaces.discoverNamedInterfaces(javaPackage))
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> NamedInterfaces.discoverNamedInterfaces(javaPackage))
|
||||
.withMessageContaining("named interface defaulting")
|
||||
.withMessageContaining(InvalidDefaultNamedInterface.class.getSimpleName());
|
||||
}
|
||||
@@ -76,7 +82,9 @@ class NamedInterfacesUnitTests {
|
||||
assertThat(interfaces).map(NamedInterface::getName)
|
||||
.containsExactlyInAnyOrder(NamedInterface.UNNAMED_NAME, "api", "spi", "kpi", "internal", "ontype");
|
||||
|
||||
assertInterfaceContains(interfaces, NamedInterface.UNNAMED_NAME, RootType.class, Internal.class);
|
||||
assertInterfaceContains(interfaces, NamedInterface.UNNAMED_NAME,
|
||||
RootType.class, Internal.class, InNested.class, InNestedA.class, InNestedB.class, InNestedBFirst.class,
|
||||
InNestedBSecond.class);
|
||||
}
|
||||
|
||||
@Test // GH-595
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.modulith.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PackageName}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
*/
|
||||
class PackageNameUnitTests {
|
||||
|
||||
@Test // GH-578
|
||||
void sortsPackagesByNameAndDepth() {
|
||||
|
||||
var comAcme = new PackageName("com.acme");
|
||||
var comAcmeA = new PackageName("com.acme.a");
|
||||
var comAcmeAFirst = new PackageName("com.acme.a.first");
|
||||
var comAcmeAFirstOne = new PackageName("com.acme.a.first.one");
|
||||
var comAcmeASecond = new PackageName("com.acme.a.second");
|
||||
var comAcmeB = new PackageName("com.acme.b");
|
||||
|
||||
assertThat(List.of(comAcmeAFirstOne, comAcmeB, comAcmeASecond, comAcmeAFirst, comAcme, comAcmeA)
|
||||
.stream()
|
||||
.sorted((l, r) -> -l.compareTo(r))
|
||||
.map(it -> it.getLocalName("com")))
|
||||
.containsExactly("acme.b", "acme.a.second", "acme.a.first.one", "acme.a.first", "acme.a", "acme");
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,17 @@ public class TestUtils {
|
||||
private static Supplier<Classes> classes = SingletonSupplier
|
||||
.of(() -> Classes.of(imported.get()).that(IS_MODULE_TYPE));
|
||||
|
||||
/**
|
||||
* Creates an {@link ApplicationModules} instance from the given package but only inspecting the test code.
|
||||
*
|
||||
* @param basePackage must not be {@literal null} or empty.
|
||||
* @return will never be {@literal null}.
|
||||
* @since 1.3
|
||||
*/
|
||||
public static ApplicationModules of(String basePackage, String... ignoredPackages) {
|
||||
return of(ModulithMetadata.of(basePackage), JavaClass.Predicates.resideInAnyPackage(ignoredPackages));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link Classes} of this module.
|
||||
*
|
||||
@@ -78,12 +89,12 @@ public class TestUtils {
|
||||
return JavaPackage.of(TestUtils.getClasses(packageType), packageType.getPackageName());
|
||||
}
|
||||
|
||||
public static ApplicationModules of(String basePackage, String... ignoredPackages) {
|
||||
return of(ModulithMetadata.of(basePackage), JavaClass.Predicates.resideInAnyPackage(ignoredPackages));
|
||||
}
|
||||
|
||||
public static ApplicationModule getApplicationModule(String packageName) {
|
||||
return new ApplicationModule(getPackage(packageName), false);
|
||||
|
||||
var pkg = getPackage(packageName);
|
||||
var source = ApplicationModuleSource.from(pkg, pkg.getLocalName());
|
||||
|
||||
return new ApplicationModule(source);
|
||||
}
|
||||
|
||||
private static JavaPackage getPackage(String name) {
|
||||
|
||||
Reference in New Issue
Block a user