question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When running in Jest, code assumes `setImmediate` and `clearImmediate`

See original GitHub issue

Relevant code or config:

require('@testing-libray/react')

What you did:

Ran the test without global setImmediate and clearImmediate defined

What happened:

image

Reproduction:

See https://github.com/facebook/jest/pull/11222. Essentially, delete setImmediate and clearImmediate from global in the JSDOM env Jest sets up.

Problem description:

It throws runtime errors at require/import-time

Suggested solution:

Do a typeof setImmediate !== 'undefined' before using it.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:12 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
facundop3commented, Mar 25, 2021

Proposed fix:

  const timerAPI = {
    clearInterval,
    clearTimeout,
    setInterval,
    setTimeout,
  }
  if (typeof setImmediate === 'function') {
    timerAPI.setImmediate = setImmediate;
  }
  if (typeof clearImmediate === 'function') {
    timerAPI.clearImmediate = clearImmediate;
  }
  // ...

This function depends on setImmediate to work properly in order to work, I think this could probably use the polyfill declared below in the same file.

function waitForDomChange({
  container = getDocument(),
  timeout = getConfig().asyncUtilTimeout,
  mutationObserverOptions = {
    subtree: true,
    childList: true,
    attributes: true,
    characterData: true,
  },
} = {}) {
  if (!hasWarned) {
    hasWarned = true
    console.warn(
      `\`waitForDomChange\` has been deprecated. Use \`waitFor\` instead: https://testing-library.com/docs/dom-testing-library/api-async#waitfor.`,
    )
  }
  return new Promise((resolve, reject) => {
    const timer = setTimeout(onTimeout, timeout)
    const {MutationObserver} = getWindowFromNode(container)
    const observer = new MutationObserver(onMutation)
    runWithRealTimers(() =>
      observer.observe(container, mutationObserverOptions),
    )

    function onDone(error, result) {
      clearTimeout(timer)
      setImmediate(() => observer.disconnect())
      if (error) {
        reject(error)
      } else {
        resolve(result)
      }
    }

    function onMutation(mutationsList) {
      onDone(null, mutationsList)
    }

    function onTimeout() {
      onDone(new Error('Timed out in waitForDomChange.'), null)
    }
  })
}

@renatoalencar is it possible to switch the setImmediate in favour of setTimeout(()=> observer.disconnect(), 0) in waitForDomChange implementation ?

1reaction
renatoalencarcommented, Mar 25, 2021

Proposed fix:

  const timerAPI = {
    clearInterval,
    clearTimeout,
    setInterval,
    setTimeout,
  }
  if (typeof setImmediate === 'function') {
    timerAPI.setImmediate = setImmediate;
  }
  if (typeof clearImmediate === 'function') {
    timerAPI.clearImmediate = clearImmediate;
  }
  // ...

This function depends on setImmediate to work properly in order to work, I think this could probably use the polyfill declared below in the same file.

function waitForDomChange({
  container = getDocument(),
  timeout = getConfig().asyncUtilTimeout,
  mutationObserverOptions = {
    subtree: true,
    childList: true,
    attributes: true,
    characterData: true,
  },
} = {}) {
  if (!hasWarned) {
    hasWarned = true
    console.warn(
      `\`waitForDomChange\` has been deprecated. Use \`waitFor\` instead: https://testing-library.com/docs/dom-testing-library/api-async#waitfor.`,
    )
  }
  return new Promise((resolve, reject) => {
    const timer = setTimeout(onTimeout, timeout)
    const {MutationObserver} = getWindowFromNode(container)
    const observer = new MutationObserver(onMutation)
    runWithRealTimers(() =>
      observer.observe(container, mutationObserverOptions),
    )

    function onDone(error, result) {
      clearTimeout(timer)
      setImmediate(() => observer.disconnect())
      if (error) {
        reject(error)
      } else {
        resolve(result)
      }
    }

    function onMutation(mutationsList) {
      onDone(null, mutationsList)
    }

    function onTimeout() {
      onDone(new Error('Timed out in waitForDomChange.'), null)
    }
  })
}

@renatoalencar is it possible to switch the setImmediate in favour of setTimeout(()=> observer.disconnect(), 0) in waitForDomChange implementation ?

I’m currently trying to see if there’s any way to break this, and actually works just fine. Let me do some more tests and see.

Read more comments on GitHub >

github_iconTop Results From Across the Web

дэн on Twitter: "A fix in React is blocked by a fix in Jest, which ...
When running in Jest, code assumes `setImmediate` and `clearImmediate` · Issue #914 · testing-lib... @testing-library/dom version: 7.29.6 Testing Framework ...
Read more >
Jest: tests can't fail within setImmediate or process.nextTick ...
But you create a promise, and even you resolve it in the test it will have no effect in the test run, you...
Read more >
jest 27 setimmediate is not defined - (주)이글벳
Instructs Jest to use fake versions of the standard timer functions (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate and ...
Read more >
Configuring Jest
Jest will run .mjs and .js files with nearest package.json 's type field set to module as ECMAScript Modules.
Read more >
CoCalc -- FakeTimers-test.js
This source code is licensed under the BSD-style license found in the ... it('mocks clearImmediate if setImmediate is on global', function() {.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found