refactor(core): make boot and middleware ordering deterministic
CI / Build & Test (push) Failing after 4m51s
CI / Build & Test (pull_request) Canceled after 23s

This commit is contained in:
Zakaria El Orche
2026-08-12 16:42:49 +00:00
parent d7f36a7aea
commit 891ef99b8e
51 changed files with 1395 additions and 504 deletions
@@ -0,0 +1,46 @@
package dev.relism.flash.extension;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class FlashContextTest {
@Test
void resolvesDeclaredGraphRegardlessOfDeclarationOrder() {
FlashContext ctx = new FlashContext();
ctx.supply(Service.class, Dependency.class, Service::new);
ctx.provide(Dependency.class, new Dependency());
ctx.resolveAll();
assertNotNull(ctx.require(Service.class).dependency);
}
@Test
void rejectsCircularDeclaredGraphBeforeReadyCallbacks() {
FlashContext ctx = new FlashContext();
ctx.supply(Left.class, services -> new Left(), Right.class);
ctx.supply(Right.class, services -> new Right(), Left.class);
IllegalStateException error = assertThrows(IllegalStateException.class, ctx::resolveAll);
assertEquals("Circular service dependency: Left -> Right -> Left", error.getMessage());
}
@Test
void rejectsAFactoryLookupThatWasNotDeclared() {
FlashContext ctx = new FlashContext();
ctx.provide(Dependency.class, new Dependency());
ctx.supply(Service.class, services -> new Service(services.require(Dependency.class)));
IllegalStateException error = assertThrows(IllegalStateException.class, ctx::resolveAll);
assertTrue(error.getMessage().contains("undeclared dependency"));
}
private static final class Dependency {}
private static final class Service { final Dependency dependency; Service(Dependency dependency) { this.dependency = dependency; } }
private static final class Left {}
private static final class Right {}
}
@@ -0,0 +1,42 @@
package dev.relism.flash.routing;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class MiddlewareGraphTest {
private static final Middleware NOOP = next -> next::handle;
@Test
void ordersNodesFromConstraintsNotRegistrationOrder() {
MiddlewareKey auth = MiddlewareKey.of("auth");
MiddlewareKey audit = MiddlewareKey.of("audit");
Middleware authMiddleware = next -> next::handle;
Middleware auditMiddleware = next -> next::handle;
MiddlewareNode auditNode = MiddlewareNode.of(audit, auditMiddleware).after(auth);
MiddlewareNode authNode = MiddlewareNode.of(auth, authMiddleware);
Middleware[] ordered = MiddlewareGraph.order("GET /", List.of(auditNode, authNode));
assertSame(authMiddleware, ordered[0]);
assertSame(auditMiddleware, ordered[1]);
}
@Test
void rejectsAbsentRequiredPredecessor() {
MiddlewareNode audit = MiddlewareNode.of(MiddlewareKey.of("audit"), NOOP)
.after(MiddlewareKey.of("auth"));
assertThrows(IllegalStateException.class, () -> MiddlewareGraph.order("GET /", List.of(audit)));
}
@Test
void acceptsAbsentOptionalPredecessor() {
MiddlewareNode audit = MiddlewareNode.of(MiddlewareKey.of("audit"), NOOP)
.afterIfPresent(MiddlewareKey.of("auth"));
assertEquals(1, MiddlewareGraph.order("GET /", List.of(audit)).length);
}
}