Files
kst4contest/core/src
Rsclub2_2andClaude Fable 5.1 91863fee1f Remove Thread.sleep timing coupling from the tests (#109) (#118)
* test: add bounded awaitUntil helper for timing-sensitive tests (#109)

One small class per module (core and app-desktop share no test sources):
polls a condition every 10 ms and fails with a message when the timeout
elapses, so tests no longer guess with fixed Thread.sleep pauses.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(map): let TileFetcher take its nano clock as a test seam (#109)

A package-private constructor accepts a LongSupplier for the monotonic
clock the retry pause is measured against; the public constructors
delegate with System::nanoTime, so production behaviour is unchanged.
TileFetcherTest advances a fake clock instead of sleeping 20 ms three
times and hoping the 1 ms pause has elapsed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(view): put CoalescingTrigger on a DelayTimer seam (#109)

DelayTimer is a package-private one-shot timer (restart/stop) with a
Factory; DelayTimer.SWING wraps javax.swing.Timer and is what the public
constructor uses, so production behaviour is unchanged. A package-private
constructor takes the factory. CoalescingTriggerTest fires a FakeDelayTimer
itself: the negative checks (no second run, cancel prevents the run) are
now deterministic and the four Thread.sleep calls are gone. One test keeps
the real Swing timer end to end, waiting with awaitUntil.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(view): put LayoutAutosave on the DelayTimer seam (#109)

The public constructor still builds a javax.swing.Timer via DelayTimer.SWING
with the same 750 ms delay; a package-private constructor takes the factory.
LayoutAutosaveTest fires a FakeDelayTimer on the event thread itself, so
"cancelled means not written" no longer rests on a 1.2 s sleep and the
burst test no longer sleeps 300 ms to prove the absence of a second write.
The foreign-thread test keeps the real Swing timer path with awaitUntil.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* refactor(controller): inject scheduler and clock into On4KstConnectionManager (#109)

A package-private constructor takes the ScheduledExecutorService and a
LongSupplier for wall-clock milliseconds; the existing constructor delegates
with the same single-thread supervisor and System::currentTimeMillis, so
production behaviour is unchanged. Session's idle clocks start from the
injected clock instead of a field initializer. The static
parseMessageTimestamp keeps the wall clock: it sanity-checks server
timestamps and is not part of the supervisor's timing.

On4KstConnectionProbeTest drives unansweredProbeUsesExistingReconnectFlow
through a ManualScheduler (immediate work on a real thread, delays and the
five-second tick released on demand) and a fake clock: 90 s of silence
sends the CK probe, which the test reads off the socket, 210 s fails the
session, and the released backoff opens the second connection. The
reflection-based state setup is gone because the state is now reached the
production way; the test takes well under a second instead of seven. The
two ignored await(2 s) results in the server stubs are asserted now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: close the profile picker as soon as it shows instead of after 1.5 s (#109)

The two display-bound picker tests disposed the modal dialog from a
Swing timer after a fixed 1.5 s, which was long enough on a fast machine
only and cost 3 s per run. The closer now waits with awaitUntil for the
dialog to appear and disposes it on the event thread; the suite drops
from 3.0 s to 0.26 s.

Remaining fixed sleep: TopPriorityCandidatesWindowTest waits 400 ms for
Compose's double-tap timeout; whether ImageComposeScene's time can
advance it deterministically is still to be checked.

Fixes #109

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 18:39:21 +02:00
..