Skip to content

Commit e673471

Browse files
committed
test(archunit): pin args sub-package as a true leaf
Adds argsPackageIsALeaf to LlamaArchitectureTest: classes in net.ladenthin.llama.args must not depend on the root API package or the json parser package. Catches a future drift like an enum gaining a "convenient" helper that pulls in JNI state or a JSON DTO. The traditional 3-layer layeredArchitecture() rule (Args -> Json -> Api) was attempted first and rejected on evidence: json parsers/ serializers genuinely depend on root-package DTOs (Pair, ChatMessage, ContentPart) AND the root API genuinely depends on json parsers (LlamaIterator, JsonParameters, LlamaModel, ModelParameters import from json). json and api are peers in the public API layer, not a stackable hierarchy. Splitting the DTOs into a dedicated net.ladenthin.llama.value package would enable real layering, but breaks published public-API FQNs (net.ladenthin.llama.Pair, etc.) and is out of scope for an ArchUnit rule. The argsPackageIsALeaf rule pins the only real layered invariant that the current package design supports. noPackageCycles already catches the looser "no cycles between subpackages" property. Tests: 10 of 10 pass (was 9; +1 for the new leaf rule).
1 parent 0a97ae7 commit e673471

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

src/test/java/net/ladenthin/llama/LlamaArchitectureTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,34 @@ public class LlamaArchitectureTest {
6363
.should()
6464
.beFreeOfCycles();
6565

66+
/**
67+
* The {@code args} sub-package is a true leaf: pure enums / constants
68+
* ({@code Sampler}, {@code PoolingType}, {@code ModelFlag}, …). It must not
69+
* import anything from elsewhere in the project — neither the root API
70+
* package nor the {@code json} parser package.
71+
*
72+
* <p>This pins the only stackable layer relationship in jllama. The
73+
* traditional {@code layeredArchitecture()} 3-layer rule (Args → Json → Api)
74+
* was attempted and rejected: {@code json} parsers/serializers genuinely
75+
* depend on root-package DTOs ({@code Pair}, {@code ChatMessage},
76+
* {@code ContentPart}) AND the root API genuinely depends on {@code json}
77+
* parsers — they are <em>peers in the public API layer</em>, not a
78+
* stackable hierarchy. Splitting the DTOs into a dedicated
79+
* {@code net.ladenthin.llama.value} package would enable real layering,
80+
* but breaks the published public-API FQNs ({@code net.ladenthin.llama.Pair}
81+
* etc.) and is out of scope for an ArchUnit rule.
82+
*
83+
* <p>So the only real architectural invariant worth enforcing here is "args
84+
* stays a leaf" — and that is what this rule does.
85+
*/
86+
@ArchTest
87+
static final ArchRule argsPackageIsALeaf = noClasses()
88+
.that()
89+
.resideInAPackage("net.ladenthin.llama.args..")
90+
.should()
91+
.dependOnClassesThat()
92+
.resideInAnyPackage("net.ladenthin.llama", "net.ladenthin.llama.json..");
93+
6694
/**
6795
* Production code must not import unsupported / internal JDK packages.
6896
* These are not part of the Java SE API and may change or disappear without notice.

0 commit comments

Comments
 (0)