Skip to content

Make the remaining excluded classes testable and cover them - #24

Merged
lpenap merged 1 commit into
masterfrom
lpenap/coverage-phase-3
Sep 16, 2026
Merged

lpenap merged 1 commit into
masterfrom
lpenap/coverage-phase-3

Conversation

@lpenap

@lpenap lpenap commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Summary

Second PR of the coverage plan (phase 3). Only the GUI shell (MainWindow, AppCommandLineRunner, the application class) remains excluded from JaCoCo.

Bug fixes

  • Consumer looped forever and swallowed interrupts. It now exits when its thread is interrupted.
  • ProducerConsumerExampleRunner never shut its executor down, leaking three threads per run. It now waits for the producer to finish and the queue to drain, then calls shutdownNow and awaits termination.
  • HyperlinkMouseListener.mouseClicked logged the MouseEvent instead of the exception on failure.

Testability

  • HyperlinkMouseListener gains a package-private LinkOpener functional interface. The public constructor keeps Desktop.browse as the default.

New tests

  • ExamplesCommandLineRunnerTests: disabled path, trace-enabled path, and the info-level hints, using a GenericApplicationContext with a fake runner bean and a logback ListAppender. Covers all 10 branches.
  • ConsumerTests: consumes then stops on interrupt; stops immediately if already interrupted.
  • ProducerConsumerExampleRunnerTests: runs to completion within a timeout and leaves no extra pool threads alive.
  • HyperlinkMouseListenerTests: click opens the entered link, malformed link and opener failure are logged not thrown, press and release are no-ops.
  • ObserverTests: removeAllListeners clears every listener.

Coverage

Instructions Branches
Before (PR 22) 673 / 673 = 100% 17 / 17 = 100%
After 1008 / 1015 = 99.3% 34 / 35 = 97.1%

The seven missed instructions are the "consumers did not stop in time" warning and the real Desktop.browse call, neither of which can run in a headless test.

Concurrency tests were run five extra times locally with no failures.

Next

Phase 4: raise the JaCoCo instruction minimum to 0.95 and add a 0.90 branch rule.

🤖 Generated with Claude Code

Consumer now stops when its thread is interrupted instead of looping
forever and swallowing the interruption, and ProducerConsumerExampleRunner
waits for production and consumption to finish, then shuts the executor
down so the pool threads no longer leak on every run.

HyperlinkMouseListener gets a package-private LinkOpener seam with
Desktop.browse as the default, so the click handler can be tested without
a desktop. The error log now includes the exception instead of the mouse
event.

New tests cover ExamplesCommandLineRunner through a GenericApplicationContext
with a fake runner bean and all logback level branches, Consumer,
ProducerConsumerExampleRunner including thread cleanup, the click paths of
HyperlinkMouseListener and ObservableAbstract.removeAllListeners. The
corresponding JaCoCo excludes are removed; only the GUI shell remains
excluded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@lpenap
lpenap merged commit edce0d1 into master Sep 16, 2026
3 checks passed
@lpenap
lpenap deleted the lpenap/coverage-phase-3 branch September 16, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant