Skip to content

Commit 86620c1

Browse files
committed
Add isNoopScheduler with import-order guard in test harness
1 parent 93c3d30 commit 86620c1

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

runtime-singletons.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,8 @@ export function __setSingletons(
9191
export function getSingletons(): RuntimeSingletons {
9292
return current;
9393
}
94+
95+
/** True when scheduler is the pre-init noop — see createTestHarness() safety check. */
96+
export function isNoopScheduler(scheduler: RuntimeFrameScheduler): boolean {
97+
return NOOP_SCHEDULER_MARKER in scheduler;
98+
}

tests/test-utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
__setSingletons,
2727
createWriteLock,
2828
getSingletons,
29+
isNoopScheduler,
2930
type RuntimeSingletons,
3031
} from "../runtime-singletons.js";
3132
import { SpawnFrameScheduler } from "../spawn/renderer.js";
@@ -68,6 +69,17 @@ export function createTestHarness(): TestHarness {
6869
const originalWarn = console.warn;
6970
const originalError = console.error;
7071

72+
// Check whether spawn/renderer.ts was already statically imported before
73+
// this harness call — if previousSingletons still holds the noop marker,
74+
// the production registration at the bottom of spawn/renderer.ts never ran.
75+
if (isNoopScheduler(previousSingletons.frameScheduler)) {
76+
console.warn(
77+
"[test-utils] spawn/renderer.ts was not statically imported before " +
78+
"createTestHarness() — the production frame scheduler was never " +
79+
"registered. Frame-batched rendering tests will use the noop scheduler.",
80+
);
81+
}
82+
7183
// Atomic swap: replace the production singleton container (write lock,
7284
// context, frame scheduler) in one call.
7385
__setSingletons(singletons);

tests/unit/runtime-singletons.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
__setSingletons,
77
createWriteLock,
88
getSingletons,
9+
isNoopScheduler,
910
} from "../../runtime-singletons.js";
1011

1112
test("createTestHarness swaps singleton state atomically and restores it on teardown", () => {
@@ -83,3 +84,15 @@ test("write lock serializes concurrent writers and completes all", async () => {
8384

8485
h.teardown();
8586
});
87+
88+
test("isNoopScheduler returns false for SpawnFrameScheduler", () => {
89+
// The noop scheduler is created at module init but overwritten by
90+
// spawn/renderer.ts at import time — so the global singleton always
91+
// holds a real scheduler. The true path (returns true) is exercised by
92+
// the import-order guard in createTestHarness() — see test-utils.ts.
93+
assert.equal(isNoopScheduler(getSingletons().frameScheduler), false);
94+
95+
const h = createTestHarness();
96+
assert.equal(isNoopScheduler(getSingletons().frameScheduler), false);
97+
h.teardown();
98+
});

0 commit comments

Comments
 (0)