Skip to content

Building and Testing

Petrus Pradella edited this page Aug 5, 2026 · 5 revisions

Building & Testing

Prerequisites

  • JDK 25 — the only JDK you need to launch the build. The wrapper is Gradle 9.5.1 (runs on JDK 25 directly). One toolchain compiles and runs everything.
  • The published bytecode targets Java 8: production sources compile on the Java 25 toolchain via Jabel (a fork that supports a Java 25 javac), with options.release = 8 keeping the API floor honest.
  • Auto-download is off; Gradle auto-detects locally installed JDKs (including ~/.jdks). A JDK in a non-standard location can be pointed at from your own ~/.gradle/gradle.properties.

Build

export JAVA_HOME=/path/to/jdk-25      # PowerShell: $env:JAVA_HOME = "C:\path\to\jdk-25"

./gradlew build                       # compile + run every module's tests on Java 25
./gradlew shadowJar                   # (n/a — EveryConfig ships thin jars; see Installation)
./gradlew publishToMavenLocal         # install everyconfig-core:1.1.0 + everyconfig-rules:1.1.0 to ~/.m2

Two modules: :core (everyconfig-core) and :rules (everyconfig-rules). A task with no project prefix runs in both — ./gradlew :core:test narrows it.

The Java 8 runtime floor

Jabel lifts syntax but not runtime APIs, so production and test code avoid Java 9+ APIs (List.of, String.repeat, Files.readString, record, …). The guard is running the suite on a Java 8 runtime:

./gradlew :core:test :rules:test -PtestJdk=8 --rerun-tasks   # also: 11, 17, 21, 25 (default is 25)

-PtestJdk does not invalidate the test task's up-to-date check, so without --rerun-tasks Gradle happily reports the previous run's result and you learn nothing.

Test bytecode is compiled to the Java 8 floor too (compileTestJava uses --release 8), so the suite can run on a Java 8 JVM. The library is validated green on Java 8, 11, 17, 21 and 25.

The codec matrix

CodecMatrixTest is the shared harness — the codec hooks, the capability flags and the residual handling. It lives in a testFixtures source set of :core, so a suite in ANY module can run its whole body against all four formats instead of copying the plumbing. (It is build-time only: the fixtures variants are kept out of the published component, so no consumer ever resolves a -test-fixtures jar.)

core/src/testFixtures/java/.../testkit/
└── CodecMatrixTest.java              # newCodec/fileExtension/fidelity + capability flags + residuals

core/src/test/java/.../
├── testdata/                         # shared DTOs (Dtos, UltraComplexDTO)
├── contract/
│   ├── AbstractConfigTest.java       # the config contract + the per-codec golden layouts
│   ├── JsonConfigTest.java           # newCodec()=JsonCodec, fidelity=NONE
│   ├── YamlConfigTest.java           # newCodec()=YamlCodec, fidelity=LOSSLESS
│   ├── TomlConfigTest.java           # newCodec()=TomlCodec, supportsNull()=false
│   ├── JsoncConfigTest.java          # newCodec()=JsoncCodec, fidelity=LOSSY
│   └── stress/                       # AbstractStressTest + 4 subclasses (gated by -Pstress)
└── codec/  binding/  io/  rule/      # per-feature unit tests

rules/src/test/java/.../ruleset/
├── contract/                         # AbstractRulesetTest + the same 4 codec subclasses
└── (root)                            # what no format can influence, bound in memory

A new subclass supplies a Codec, the file extension and a comment-fidelity flag; capability-gated tests (comments, null, key ordering) skip on codecs that don't support them via JUnit Assumptions.

Residuals

Real files are written under build/test-residuals/<group>/<ext>/<method>/ and kept for inspection by default (flip CLEAN_TEST_RESIDUALS in CodecMatrixTest to delete them). This lets you diff how the same scenario renders across all four formats; residualsGroup() keeps two contracts writing the same scenario side by side instead of overwriting each other.

Running specific tests

./gradlew test --tests "*YamlConfigTest"
./gradlew test --tests "br.com.finalcraft.everyconfig.config.modules.*"   # all four codec contracts
./gradlew cleanTest test -PtestJdk=8                                       # force a re-run on Java 8

→ See also Project Layout · Installation

Clone this wiki locally