rtp-core Coverage Plan: 49% → 80%¶
Updated: 2026-04-16 (rescanned from live JaCoCo run) Scope:
rtp-coreonly (rtp-folia-common has broken tests; rtp-bukkit-common is a server impl layer)
Current Baseline¶
- 49% instructions / 35% branches across 38,863 instructions (19,540 covered)
- ~12,050 more instructions need coverage to reach 80% (target: 31,090 covered)
- JaCoCo is already configured in
build.gradlefor all subprojects - CI uploads HTML reports as
jacoco-coverageartifact but no minimum threshold is enforced - 57 test files already exist in
rtp-core/src/test
Per-Package Coverage Snapshot (2026-04-16)¶
Package (suffix after …rtp.common.) |
Instr % | Branch % | Missed Lines | Status |
|---|---|---|---|---|
tools |
16% | 6% | 630 | 🔴 Critical gap |
commands |
1% | 0% | 312 | 🔴 Critical gap |
selection |
7% | 0% | 82 | 🔴 Critical gap |
commands.config.list |
25% | 0% | 39 | 🔴 Critical gap |
database.options |
26% | 21% | 671 | 🔴 Critical gap |
tasks.teleport |
22% | 16% | 285 | 🔴 Critical gap |
(root) |
34% | 16% | 149 | 🟠 Large gap |
tasks.tick |
34% | 23% | 59 | 🟠 Large gap |
selection.region.selectors.verticalAdjustors |
40% | 16% | 20 | 🟠 Large gap |
selection.region |
44% | 31% | 656 | 🟠 Large gap |
selection.region.selectors.shapes |
47% | 12% | 31 | 🟠 Large gap |
database |
50% | 35% | 162 | 🟡 Moderate gap |
commands.config |
32% | 23% | 181 | 🟡 Moderate gap |
commands.parameters |
37% | 0% | 59 | 🟡 Moderate gap |
configuration |
63% | 53% | 177 | 🟡 Moderate gap |
tasks |
64% | 46% | 163 | 🟡 Moderate gap |
network |
65% | 33% | 9 | 🟡 Moderate gap |
commands.reload |
60% | 42% | 34 | 🟡 Moderate gap |
commands.info |
71% | 71% | 24 | 🟢 Near target |
selection.region.selectors.memory.shapes |
74% | 59% | 352 | 🟢 Near target |
factory |
80% | 72% | 37 | ✅ At target |
commands.fill |
83% | 60% | 27 | ✅ At target |
selection.region.selectors.verticalAdjustors.linear |
84% | 60% | 15 | ✅ At target |
selection.region.selectors.verticalAdjustors.jump |
95% | 75% | 1 | ✅ Done |
playerData |
96% | 100% | 2 | ✅ Done |
selection.worldborder |
97% | 70% | 0 | ✅ Done |
commands.help |
98% | 81% | 0 | ✅ Done |
configuration.enums |
100% | n/a | 0 | ✅ Done |
selection.region.selectors.memory.shapes.enums |
100% | n/a | 0 | ✅ Done |
selection.region.selectors.memory |
100% | n/a | 0 | ✅ Done |
selection.region.selectors.shapes.enums |
0% | n/a | 18 | 🔴 Critical gap (small) |
Remaining Attack Plan¶
Key principle: pure-logic first (no mocks), then lightweight Mockito mocks, then skip server-coupled code.
Tier A — tools Package (16% → 80+%) 🔴 HIGHEST PRIORITY¶
~630 missed lines — single biggest gap in the codebase.
Classes inside rtp.common.tools:
- TPS (~92 instructions, 8% covered) — tick recording and average calculation
- PerformanceTracker — large class, nearly untouched
- Other utility helpers
Prompts for Junie:
- "Write JUnit5 tests for TPS covering tick recording, average calculation, boundary conditions (empty, single tick, many ticks), and the get() return format."
- "Write JUnit5 tests for PerformanceTracker covering: start/stop tracking, multiple concurrent keys, elapsed time accuracy (within tolerance), and reset behavior."
- "Scan io.github.dailystruggle.rtp.common.tools for any remaining uncovered utility classes and write JUnit5 tests for each — check the JaCoCo HTML at rtp-core/build/reports/jacoco/test/html/io.github.dailystruggle.rtp.common.tools/index.html."
Tier B — database.options Package (26% → 80+%) 🔴 HIGH PRIORITY¶
~671 missed lines. YamlFileDatabaseTest and H2DatabaseAccessorTest exist but coverage is only 26%, indicating many branches and methods are not exercised.
Prompts for Junie:
- "Open the JaCoCo HTML report at rtp-core/build/reports/jacoco/test/html/io.github.dailystruggle.rtp.common.database.options/index.html and identify all red/yellow lines. Extend YamlFileDatabaseTest and H2DatabaseAccessorTest to cover those branches: error paths, missing-key fallbacks, concurrent access, and transaction rollback."
- "Write a stress test for YamlFileDatabase using @TempDir that inserts, reads, overwrites, and deletes 100 entries in rapid succession to cover iteration and cleanup paths."
- "Extend AbstractDatabaseAccessorTest to add tests for the getAll(), remove(), and contains() contract methods if not already covered."
Tier C — selection.region Package (44% → 80+%) 🟠 HIGH PRIORITY¶
~656 missed lines — second largest gap. RegionPipelineTest and RegionQueueManagerTest exist but cover only 44%.
Prompts for Junie:
- "Open the JaCoCo report at rtp-core/build/reports/jacoco/test/html/io.github.dailystruggle.rtp.common.selection.region/index.html. Identify the red classes and extend RegionPipelineTest and RegionQueueManagerTest to cover uncovered branches: empty region, full queue, cancelled pipeline, and concurrent enqueue/dequeue."
- "Write JUnit5+Mockito tests for RegionConfigLoader (if not already fully covered) covering: valid config load, missing keys with defaults, malformed values, and reload-after-mutation."
- "Write JUnit5+Mockito tests for DynamicWorldConfig covering: world registration, deregistration, config lookup for unknown world, and concurrent world registration."
Tier D — tasks.teleport Package (22% → 80+%) 🔴 HIGH PRIORITY¶
~285 missed lines. TeleportPipelineTaskPhaseTest and RTPTeleportCancelTest exist but cover only 22%.
Prompts for Junie:
- "Open the JaCoCo report at rtp-core/build/reports/jacoco/test/html/io.github.dailystruggle.rtp.common.tasks.teleport/index.html. Identify uncovered methods and extend TeleportPipelineTaskPhaseTest to exercise all state transitions: PENDING → RUNNING → COMPLETE, PENDING → CANCELLED, and RUNNING → FAILED. Mock RTPServer, RTPWorld, RTPPlayer, RTPScheduler via RTPTestSetup."
- "Write JUnit5+Mockito tests for DoTeleport (or equivalent executor class) covering: successful teleport, teleport to invalid location (null world), teleport with cooldown active, and teleport with permission denied."
Tier E — commands + commands.config + commands.config.list (1% / 32% / 25%) 🔴¶
~312 + ~181 + ~39 = ~532 missed lines combined.
Prompts for Junie:
- "Open the JaCoCo report for rtp.common.commands. The main command dispatcher is at ~1% — write JUnit5+Mockito tests for the top-level RTPCommand dispatch logic: valid subcommand routing, unknown subcommand → usage message, and permission-check short-circuit. Mock CommandSender."
- "Extend ConfigCmdTest and SubConfigCmdTest to cover branches currently marked red in the JaCoCo report — especially error paths, missing-argument fallbacks, and the config-value update path."
- "Write JUnit5+Mockito tests for ListConfigCmd/SubListConfigCmd covering: empty config list, non-empty list formatting, and invalid argument handling."
Tier F — selection root + commands.parameters + tasks.tick (7% / 37% / 34%) 🟠¶
~82 + ~59 + ~59 = ~200 missed lines combined.
Prompts for Junie:
- "Write JUnit5 tests for the io.github.dailystruggle.rtp.common.selection package root — likely SelectionAPI or similar. Cover: null-world guard, valid selection trigger, and selection result validation."
- "Extend ParameterParsingTest and ListParameterTest to cover the 0%-branch packages: BiomeParameter, BooleanParameter, FloatParameter, IntegerParameter, RegionParameter — test boundary values, invalid strings, and null inputs."
- "Extend tick-related tests (SLATest or equivalent) to cover rtp.common.tasks.tick branches: tick scheduling, overdue-tick detection, and tick cancellation."
Tier G — configuration + tasks + database + commands.reload (63% / 64% / 50% / 60%) 🟡¶
These packages have tests but still have meaningful uncovered branches worth closing.
Prompts for Junie:
- "Open JaCoCo reports for configuration (63%), tasks (64%), database (50%), and commands.reload (60%). For each, identify the red/yellow lines and add targeted tests for the specific uncovered branches — avoid rewriting existing tests."
Tier H — selection.region.selectors.memory.shapes (74% → 90%+) 🟢 NEAR TARGET¶
~352 missed lines — tests exist but branch coverage is only 59%.
Prompts for Junie:
- "Extend MemoryShapeTest, MemoryShapeCacheTest, and DeterministicShapeTest with parameterized @MethodSource tests covering: zero radius, max-int radius, negative min radius, cache hit/miss/invalidation, and uniform distribution verification across 10,000 samples."
What to Skip (for now)¶
| Class | Reason |
|---|---|
ChunkyChecker / ChunkyRTPShape |
Requires Chunky plugin at runtime |
RedisManager |
Requires live Redis server (RedisManagerTest should be @Disabled) |
ScanCmd family |
Deeply server-coupled (currently 83% — don't regress) |
| MySQL / PostgreSQL accessors | Require running DB server — use inline H2/SQLite instead |
Revised Coverage Projection¶
| Tier | Package(s) | Est. Lines Gained | Cumulative % |
|---|---|---|---|
| Baseline | — | — | 49% |
| Tier A | tools |
~530 lines | ~54% |
| Tier B | database.options |
~500 lines | ~59% |
| Tier C | selection.region |
~450 lines | ~63% |
| Tier D | tasks.teleport |
~220 lines | ~66% |
| Tier E | commands + config variants |
~400 lines | ~70% |
| Tier F | selection + parameters + tick |
~160 lines | ~72% |
| Tier G | Mid-coverage packages | ~300 lines | ~75% |
| Tier H | memory.shapes branch gaps |
~200 lines | ~78–80% |
Note: line counts are a proxy. Actual instruction gains may vary ±5%. Completing Tiers A–E alone is likely sufficient to cross 80% given instruction density in
toolsanddatabase.options.
Enforcing the Gate in CI¶
Add to build.gradle subprojects block once coverage is sufficient. Ratchet up gradually:
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
counter = 'INSTRUCTION'
minimum = 0.80 // raise gradually: 0.50 → 0.65 → 0.75 → 0.80
}
}
}
}
check.dependsOn jacocoTestCoverageVerification
Also enable XML reports for Codecov integration (optional):
jacocoTestReport {
reports {
xml.required = true
html.required = true
}
}
Then add to .github/workflows/gradle.yml:
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: '**/build/reports/jacoco/test/jacocoTestReport.xml'