Testing Strategy

Test Layers

  • Unit tests: parsing, validation, state machines, and extracted class behavior.

  • Integration tests: WireMock-based API contract verification and E2E generation.

  • Deterministic async harnesses: TUI state machine tests use UiScheduler.immediate() and Duration.ZERO debounce.

  • Property-based tests: ZIP extraction edge cases (path traversal, large archives).

  • Headless CLI tests: HeadlessCli entry point smoke tests (no-subcommand, help, version).

  • Architecture guardrails: ArchUnit tests prevent headless/UI boundary drift.

TUI Test Strategy

TUI tests follow a two-layer approach:

  • Semantic behavior tests first: assert controller state (focusTarget, generation state, exit plans, filters, errors).

  • Golden/render tests selectively: keep a smaller set of snapshot-style assertions for UX copy/layout regression.

Prefer semantic assertions for navigation/workflow logic, and reserve render-string assertions for user-facing text contracts.

UI State-Machine Refactor Contract Baseline

Before and during the UI state-machine migration, these semantic contracts must remain green:

  • routing precedence (overlay/cancel/quit/loading/global/focus/input)

  • generation transitions (IDLE → LOADING → SUCCESS|ERROR|CANCELLED)

  • post-generation exit-plan semantics

  • focus transition semantics

  • extension cancel unwind order

  • overlay layering/z-order contracts

  • resize/tick event behavior

  • catalog load success/failure semantics and startup overlay visibility

  • stale-token completion no-op behavior for async catalog/generation callbacks

  • single-writer transition discipline (state transitions on render thread)

Dedicated Test Suites for Extracted Classes

Class Tests Coverage

PostGenerationMenuState

26

State transitions, key handling, sealed MenuKeyResult dispatch

MetadataSelectorManager

18

Selector sync, option cycling, boundary conditions

CatalogRowBuilder

16

Section headers, favorites, recents, deduplication

StartupOverlayTracker

8

Duration tracking, visibility state, timing edge cases

CoreUiReducer + UiStateSnapshotMapper

contract-focused

Reducer intent/effect outcomes and immutable state snapshot mapping contracts

Core Verification Commands

./mvnw -q spotless:check
./mvnw -q verify
./mvnw -q clean compile -Pheadless  # verify headless profile compiles

Or using the included justfile:

just format-check      # spotless:check
just test-unit         # unit tests only
just test-it           # integration tests only
just test              # unit + integration (verify)
just headless-check    # headless profile compile
just verify            # format-check + headless-check + test

Coverage

JaCoCo reports are generated during a full ./mvnw clean verify run.

  • ./mvnw test (unit-only) does not publish JaCoCo site reports.

  • ./mvnw clean verify publishes merged reports:

    • HTML: target/site/jacoco/index.html

    • XML: target/site/jacoco/jacoco.xml

In CI, a dedicated coverage job runs ./mvnw clean verify on Linux, generates both reports, and uploads them to Codecov and as GitHub Actions artifacts (14-day retention).

To generate coverage locally:

./mvnw clean verify
# or: just coverage
open target/site/jacoco/index.html  # macOS
x-www-browser target/site/jacoco/index.html  # Linux
start target/site/jacoco/index.html  # Windows (cmd.exe)

Platform Independence

  • Path assertions use Path.toString() instead of hard-coded forward slashes.

  • Temp directories use @TempDir for cross-platform cleanup.

Docs Verification

npm run docs:build --prefix site
npm run docs:linkcheck --prefix site