MCPcopy
hub / github.com/callstack/react-native-testing-library / waitForInternal

Function waitForInternal

src/wait-for.ts:24–220  ·  view source on GitHub ↗
(
  expectation: () => T,
  {
    timeout = getConfig().asyncUtilTimeout,
    interval = DEFAULT_INTERVAL,
    stackTraceError,
    onTimeout,
  }: WaitForOptions,
)

Source from the content-addressed store, hash-verified

22};
23
24function waitForInternal<T>(
25 expectation: () => T,
26 {
27 timeout = getConfig().asyncUtilTimeout,
28 interval = DEFAULT_INTERVAL,
29 stackTraceError,
30 onTimeout,
31 }: WaitForOptions,
32): Promise<T> {
33 if (typeof expectation !== 'function') {
34 throw new TypeError('Received `expectation` arg must be a function');
35 }
36
37 // eslint-disable-next-line no-async-promise-executor
38 return new Promise(async (resolve, reject) => {
39 let lastError: unknown;
40 let intervalId: ReturnType<typeof setInterval> | null = null;
41 let finished = false;
42 let promiseStatus = 'idle';
43
44 let overallTimeoutTimer: ReturnType<typeof setTimeout> | null = null;
45 const cleanupQueueCallback = () => finalizeWaitFor({ rejectOnAbort: true });
46
47 const fakeTimersType = getJestFakeTimersType();
48
49 if (fakeTimersType) {
50 checkExpectation();
51 // this is a dangerous rule to disable because it could lead to an
52 // infinite loop. However, eslint isn't smart enough to know that we're
53 // setting finished inside `onDone` which will be called when we're done
54 // waiting or when we've timed out.
55 let fakeTimeRemaining = timeout;
56 while (!finished) {
57 if (!jestFakeTimersAreEnabled()) {
58 const error = new Error(
59 `Changed from using fake timers to real timers while using waitFor. This is not allowed and will result in very strange behavior. Please ensure you're awaiting all async things your test is doing before changing to real timers. For more info, please go to https://github.com/testing-library/dom-testing-library/issues/830`,
60 );
61 copyStackTraceIfNeeded(error, stackTraceError);
62 reject(error);
63 return;
64 }
65
66 // when fake timers are used we want to simulate the interval time passing
67 if (fakeTimeRemaining <= 0) {
68 handleTimeout();
69 return;
70 } else {
71 fakeTimeRemaining -= interval;
72 }
73
74 // we *could* (maybe should?) use `advanceTimersToNextTimer` but it's
75 // possible that could make this loop go on forever if someone is using
76 // third party code that's setting up recursive timers so rapidly that
77 // the user's timer's don't get a chance to resolve. So we'll advance
78 // by an interval instead. (We have a test for this case).
79 await act(() =>
80 fakeTimersType === 'modern'
81 ? jest.advanceTimersByTimeAsync(interval)

Callers 1

waitForFunction · 0.85

Calls 9

getConfigFunction · 0.90
getJestFakeTimersTypeFunction · 0.90
jestFakeTimersAreEnabledFunction · 0.90
copyStackTraceIfNeededFunction · 0.90
actFunction · 0.90
flushMicroTasksFunction · 0.90
addToCleanupQueueFunction · 0.90
checkExpectationFunction · 0.85
handleTimeoutFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…