GH-11, GH-66, GH-67, GH-68 - Improve module canvas.

Overhauled the module canvas in various ways. By default, we now skip "empty" rows. In other words, if we do not find any published events for example, we skip the entire row. CanvasOptions.revealEmptyRows() can be used to keep those empty rows around. We now also expose all value types and Spring bean references.

Refactored the dependency lookup APIs on ApplicationModule. Both DependencyType and DependencyDepth are now top-level types. Also, ApplicationModuleDependency and ApplicationModuleDependencies were introduced as explicit types. In the course of that, ApplicationModule.getDependencies(…) has got its return type changed from List<ApplicationModule> to ApplicationModuleDependencies. The internal ModuleDependency type has been renamed to QualifiedDependency.
This commit is contained in:
Oliver Drotbohm
2022-11-11 13:52:42 +01:00
parent 62ac231ce4
commit d96263fe30
14 changed files with 784 additions and 373 deletions

View File

@@ -19,9 +19,10 @@ import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import org.springframework.modulith.model.ApplicationModuleDependencies;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.modulith.model.ApplicationModules.Filters;
import org.springframework.modulith.model.DependencyType;
import org.springframework.modulith.model.Violations;
import com.acme.myproject.invalid.InvalidComponent;
@@ -43,14 +44,14 @@ class ModulithTest {
@Test
void verifyModules() {
String componentName = InternalComponentB.class.getSimpleName();
String componentName = InternalComponentB.class.getName();
assertThatExceptionOfType(Violations.class) //
.isThrownBy(() -> ApplicationModules.of(Application.class, DEFAULT_EXCLUSIONS).verify()) //
.withMessageContaining(String.format("Module '%s' depends on non-exposed type %s within module 'moduleB'",
"invalid", InternalComponentB.class.getName()))
.withMessageContaining(String.format("%s declares constructor %s(%s)", InvalidComponent.class.getSimpleName(),
InvalidComponent.class.getSimpleName(), componentName));
.withMessageContaining(
String.format("Constructor <%s.<init>(%s)>", InvalidComponent.class.getName(), componentName));
}
@Test
@@ -94,11 +95,10 @@ class ModulithTest {
assertThat(modules.getModuleByName("moduleD")).hasValueSatisfying(it -> {
assertThat(it.getDependencies(modules, DependencyType.DEFAULT))
.map(ApplicationModule::getName)
.contains("moduleC"); // ConfigurationProperties -> Value
.matches(inner -> inner.containsModuleNamed("moduleC"));
assertThat(it.getDependencies(modules, DependencyType.USES_COMPONENT))
.isEmpty();
.matches(ApplicationModuleDependencies::isEmpty);
});
}
}

View File

@@ -28,7 +28,7 @@ import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.docs.Documenter.DiagramOptions;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import org.springframework.modulith.model.DependencyType;
import com.acme.myproject.Application;

View File

@@ -23,7 +23,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.springframework.modulith.model.ApplicationModule.DependencyType;
import com.acme.myproject.Application;
import com.acme.myproject.complex.internal.FirstTypeBasedPort;
@@ -117,8 +116,7 @@ class ModulesIntegrationTest {
ApplicationModule moduleA = modules.getModuleByName("moduleA").orElseThrow(IllegalStateException::new);
assertThat(module).hasValueSatisfying(it -> {
assertThat(it.getDependencies(modules, DependencyType.EVENT_LISTENER)) //
.contains(moduleA);
assertThat(it.getDependencies(modules, DependencyType.EVENT_LISTENER).contains(moduleA)).isTrue();
});
}