Skip to content

Add deterministic timer mock to Fantom (#57274)#57274

Open
rubennorte wants to merge 1 commit into
react:mainfrom
rubennorte:export-D109017304
Open

Add deterministic timer mock to Fantom (#57274)#57274
rubennorte wants to merge 1 commit into
react:mainfrom
rubennorte:export-D109017304

Conversation

@rubennorte

@rubennorte rubennorte commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary:

Fantom could not deterministically fire delayed JS timers: the timer registry it used scheduled timers on a real background thread with real wall-clock delays, so setTimeout(fn, 100)/setInterval callbacks never fired within a synchronous test. This adds a mockable timer registry and a public Fantom API to control it from JS, similar to installHighResTimeStampMock.

  • New Fantom.installTimerMock() returns a controller with advanceTimersByTime(ms), runAllTimers(), getPendingTimerCount(), and uninstall() (jest fake-timer style). While installed, setTimeout/setInterval callbacks only fire when the virtual clock is advanced.
  • New deterministic FantomTimerRegistry (no background thread) keyed off a virtual clock, injected via a new optional platformTimerRegistryFactory seam on ReactInstanceConfig (the default registry is unchanged for all other consumers).
  • PlatformTimerRegistry gains a virtual setTimerManager (default no-op) so the registry can be wired polymorphically.
  • Control flows from JS through new NativeFantom methods, the same way the high-res timestamp mock works.

Default (non-mock) behavior is preserved: zero-delay setTimeout still fires on the next work loop, and existing tests are unaffected.

Changelog: [Internal]

Differential Revision: D109017304

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 18, 2026
@meta-codesync

meta-codesync Bot commented Jun 18, 2026

Copy link
Copy Markdown

@rubennorte has exported this pull request. If you are a Meta employee, you can view the originating Diff in D109017304.

@meta-codesync meta-codesync Bot changed the title Add deterministic timer mock to Fantom Add deterministic timer mock to Fantom (#57274) Jun 18, 2026
rubennorte added a commit to rubennorte/react-native that referenced this pull request Jun 18, 2026
Summary:

Fantom could not deterministically fire delayed JS timers: the timer registry it used scheduled timers on a real background thread with real wall-clock delays, so `setTimeout(fn, 100)`/`setInterval` callbacks never fired within a synchronous test. This adds a mockable timer registry and a public Fantom API to control it from JS, similar to `installHighResTimeStampMock`.

- New `Fantom.installTimerMock()` returns a controller with `advanceTimersByTime(ms)`, `runAllTimers()`, `getPendingTimerCount()`, and `uninstall()` (jest fake-timer style). While installed, `setTimeout`/`setInterval` callbacks only fire when the virtual clock is advanced.
- New deterministic `FantomTimerRegistry` (no background thread) keyed off a virtual clock, injected via a new optional `platformTimerRegistryFactory` seam on `ReactInstanceConfig` (the default registry is unchanged for all other consumers).
- `PlatformTimerRegistry` gains a virtual `setTimerManager` (default no-op) so the registry can be wired polymorphically.
- Control flows from JS through new `NativeFantom` methods, the same way the high-res timestamp mock works.

Default (non-mock) behavior is preserved: zero-delay `setTimeout` still fires on the next work loop, and existing tests are unaffected.

Changelog: [Internal]

Differential Revision: D109017304
Summary:

Fantom could not deterministically fire delayed JS timers: the timer registry it used scheduled timers on a real background thread with real wall-clock delays, so `setTimeout(fn, 100)`/`setInterval` callbacks never fired within a synchronous test. This adds a mockable timer registry and a public Fantom API to control it from JS, similar to `installHighResTimeStampMock`.

- New `Fantom.installTimerMock()` returns a controller with `advanceTimersByTime(ms)`, `runAllTimers()`, `getPendingTimerCount()`, and `uninstall()` (jest fake-timer style). While installed, `setTimeout`/`setInterval` callbacks only fire when the virtual clock is advanced.
- New deterministic `FantomTimerRegistry` (no background thread) keyed off a virtual clock, injected via a new optional `platformTimerRegistryFactory` seam on `ReactInstanceConfig` (the default registry is unchanged for all other consumers).
- `PlatformTimerRegistry` gains a virtual `setTimerManager` (default no-op) so the registry can be wired polymorphically.
- Control flows from JS through new `NativeFantom` methods, the same way the high-res timestamp mock works.

Default (non-mock) behavior is preserved: zero-delay `setTimeout` still fires on the next work loop, and existing tests are unaffected.

Changelog: [Internal]

Differential Revision: D109017304
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant