uNmAnNeR / imaskjs

vanilla javascript input mask

Home Page:https://imask.js.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Testing library fails due to TypeError: IMask is not a function

Matt-Tranzact opened this issue · comments

commented

Describe the bug
After migration to 7.0.0. tests fails due to some TypeError when running testing-library.

To Reproduce

import React from 'react'
import { render } from '@testing-library/react'
import CustomNumber from './CustomNumber'

const createWrapper = () => render(<CustomNumber />)

describe('Test Component', () => {
  describe('Rendering', () => {
    it('should match snapshot', () => {
      const wrapper = createWrapper()
      expect(wrapper).toMatchSnapshot()
    })
  })
})
import React from 'react'
import { IMaskInput } from 'react-imask'

const CustomNumber: React.FC = () => {
  return <IMaskInput mask="(#00) 000-0000" />
}

export default CustomNumber

It throws following error in console:

image

Expected behavior
Unit Test should work as previous Imask version (6.6.3)

Environment:

  • OS: Windows
  • Testing Env
  • IMask v7.0.0
  • React with Testing library v14.0.0, typescript: 5.1.3, react: 18.2.0

Additional context
It seems the error is thrown when using mask property only, if I remove mask="(#00) 000-0000" the unit test works fine.
brw, the component seems to render fine in browser:

image

The error is happening only in test mode

@Matt-Tranzact may be related to handling imports. Make sure that your build config for tests allows to use default imports such as
import IMask from 'imask' and not just import { default as IMask } from 'imask'

commented

I checked my tsconfig which is the same being used for browser config, is has "esModuleInterop": true, an d "allowSyntheticDefaultImports": true, already enabled but the error is still being reported. Btw, it is the same configuration I used for v6.6.3.

I also notice that ther error has some more logs which points to an specific lib section, could that be related?

image

I'm attaching the full log for references.

 
console.error
    Error: Uncaught [TypeError: IMask is not a function]
   at reportException (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
        at innerInvokeEventListeners (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:353:9)
        at invokeEventListeners (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:286:3)
        at HTMLUnknownElementImpl._dispatch (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:233:9)
        at HTMLUnknownElementImpl.dispatchEvent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:104:17)
        at HTMLUnknownElement.dispatchEvent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:241:34)
        at Object.invokeGuardedCallbackDev (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:4213:16)
        at invokeGuardedCallback (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:4277:31)
        at reportUncaughtErrorInDEV (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:22838:5)
        at captureCommitPhaseError (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:27126:5)
        at commitLayoutMountEffects_complete (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24690:9)
        at commitLayoutEffects_begin (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24674:7)
        at commitLayoutEffects (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24612:3)
        at commitRootImpl (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26823:5)
        at commitRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26682:5)
        at finishConcurrentRender (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25981:9)
        at performConcurrentWorkOnRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25809:7)
        at flushActQueue (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2667:24)
        at act (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2582:11)
        at C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\act-compat.js:46:25
        at renderRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:161:26)
        at render (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:247:10)
        at createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:7:35)
        at Object.createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:12:23)
        at Promise.then.completed (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:293:28)
        at new Promise (<anonymous>)
        at callAsyncCircusFn (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:226:10)
        at _callCircusTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:297:40)
        at processTicksAndRejections (node:internal/process/task_queues:95:5)
        at _runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:233:3)
        at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:135:9)
        at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
        at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
        at run (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:68:3)
        at runAndTransformResultsToJestFormat (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:122:21)
        at jestAdapter (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
        at runTestInternal (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:367:16)
        at runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:444:34) {
      detail: TypeError: IMask is not a function
          at MaskedComponent.IMask [as initMask] (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:212:22)
          at MaskedComponent.initMask [as componentDidMount] (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:175:12)
          at commitLayoutEffectOnFiber (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:23310:28)
          at commitLayoutMountEffects_complete (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24688:9)
          at commitLayoutEffects_begin (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24674:7)
          at commitLayoutEffects (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24612:3)
          at commitRootImpl (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26823:5)
          at commitRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26682:5)
          at finishConcurrentRender (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25981:9)
          at performConcurrentWorkOnRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25809:7)
          at flushActQueue (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2667:24)
          at act (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2582:11)
          at C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\act-compat.js:46:25
          at renderRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:161:26)
          at render (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:247:10)
          at createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:7:35)
          at Object.createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:12:23)
          at Promise.then.completed (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:293:28)
          at new Promise (<anonymous>)
          at callAsyncCircusFn (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:226:10)
          at _callCircusTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:297:40)
          at processTicksAndRejections (node:internal/process/task_queues:95:5)
          at _runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:233:3)
          at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:135:9)
          at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
          at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
          at run (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:68:3)
          at runAndTransformResultsToJestFormat (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:122:21)
          at jestAdapter (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
          at runTestInternal (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:367:16)
          at runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:444:34),
      type: 'unhandled exception'
    }

       5 | import CustomNumber from './CustomNumber'
       6 |
    >  7 | const createWrapper = () => render(<CustomNumber />)
         |                                   ^
       8 |
       9 | describe('Transfer CustomNumber Component', () => {
      10 |   describe('Rendering', () => {

      at VirtualConsole.<anonymous> (node_modules/jest-environment-jsdom/build/index.js:60:23)
      at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:70:28)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:353:9)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
      at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
      at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
      at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:4213:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4277:31)
      at reportUncaughtErrorInDEV (node_modules/react-dom/cjs/react-dom.development.js:22838:5)
      at captureCommitPhaseError (node_modules/react-dom/cjs/react-dom.development.js:27126:5)
      at commitLayoutMountEffects_complete (node_modules/react-dom/cjs/react-dom.development.js:24690:9)
      at commitLayoutEffects_begin (node_modules/react-dom/cjs/react-dom.development.js:24674:7)
      at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:24612:3)
      at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26823:5)
      at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
      at finishConcurrentRender (node_modules/react-dom/cjs/react-dom.development.js:25981:9)
      at performConcurrentWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:25809:7)
      at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
      at act (node_modules/react/cjs/react.development.js:2582:11)
      at node_modules/@testing-library/react/dist/act-compat.js:46:25
      at renderRoot (node_modules/@testing-library/react/dist/pure.js:161:26)
      at render (node_modules/@testing-library/react/dist/pure.js:247:10)
      at createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:7:35)
      at Object.createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:12:23)

  console.error
    The above error occurred in the <IMask(Component)> component:

        at MaskedComponent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:168:7)
        at IMaskInputFn
        at CustomNumber

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

       5 | import CustomNumber from './CustomNumber'
       6 |
    >  7 | const createWrapper = () => render(<CustomNumber />)
         |                                   ^
       8 |
       9 | describe('Transfer CustomNumber Component', () => {
      10 |   describe('Rendering', () => {

      at logCapturedError (node_modules/react-dom/cjs/react-dom.development.js:18687:23)
      at update.callback (node_modules/react-dom/cjs/react-dom.development.js:18720:5)
      at callCallback (node_modules/react-dom/cjs/react-dom.development.js:13923:12)
      at commitUpdateQueue (node_modules/react-dom/cjs/react-dom.development.js:13944:9)
      at commitLayoutEffectOnFiber (node_modules/react-dom/cjs/react-dom.development.js:23391:13)
      at commitLayoutMountEffects_complete (node_modules/react-dom/cjs/react-dom.development.js:24688:9)
      at commitLayoutEffects_begin (node_modules/react-dom/cjs/react-dom.development.js:24674:7)
      at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:24612:3)
      at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26823:5)
      at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
      at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:26117:3)
      at flushSyncCallbacks (node_modules/react-dom/cjs/react-dom.development.js:12042:22)
      at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26959:3)
      at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
      at finishConcurrentRender (node_modules/react-dom/cjs/react-dom.development.js:25981:9)
      at performConcurrentWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:25809:7)
      at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
      at act (node_modules/react/cjs/react.development.js:2582:11)
      at node_modules/@testing-library/react/dist/act-compat.js:46:25
      at renderRoot (node_modules/@testing-library/react/dist/pure.js:161:26)
      at render (node_modules/@testing-library/react/dist/pure.js:247:10)
      at createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:7:35)
      at Object.createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:12:23)
      ````

i tried

import { render } from '@testing-library/react'

const CustomNumber: React.FC = () => {
  return <IMaskInput mask="(#00) 000-0000" defaultValue="123" />
}

const createWrapper = () => render(<CustomNumber />)
const {debug} = createWrapper();
debug();

it's working fine. seems like a problem somewhere in jest/ts config

commented

I created a new project using vite sandbox with vitest instead of jest, the same error is being fired too:
image

here is the sandbox to test it: https://codesandbox.io/p/sandbox/rough-meadow-cwqcdm?file=%2Fsrc%2FReactImask.test.tsx%3A10%2C1

commented

Today I just crossed with a similar error when building a private lib. I'm using rollup to build my library and one of the dependencies is emotion/style. I build cjs and ems.
When building with cjs emotion/styled is bundled as export default styled
image

Then in my consumer app (in commonjs) when I installed the lib, everything works fine in browser but when running tests with babel and jest, I also got the error styled is not a function.

image

After some hours of digging, I found that for commonjs, my app babel config for jest doesn't understand how to read required('emotion/styled').default, it seems due to some issues realted to interop: https://rollupjs.org/configuration-options/#output-interop

What I did was to set interop to 'auto' mode in my lib.
image

Then the library was recognized successfully in my app for testing mode.
I guess something similar is happening when bundling react-imask in build mode.
Hope this info helps

@Matt-Tranzact thanks for your research and for providing link to the sandbox for reproduction. This helps me a lot.
It seems that jest does not understand esm format and uses cjs/umd instead, right?

commented

Haven't tried running my app with lib in esm (It's too attach to some other libs still in cjs). My guess is that if an app is build with type: "module" (esm) the lib should work fine since esm is capable of recognizing interop automatically.

The problem is happening only for cjs mode since browser can detect .default autoamtically but jest can't detect it (i tried with babel and ts-jest with no luck) and interop config needs to be set in lib as a fallback.

This rollup plugin also helped me to understand the problem a little better: https://www.npmjs.com/package/rollup-plugin-es-module-interop?activeTab=readme