svelte-routing icon indicating copy to clipboard operation
svelte-routing copied to clipboard

Unexpected token when using @testing-library/svelte

Open samedro opened this issue 5 years ago • 7 comments

Hi,

I'm new to svelte, and I'm trying to add some unit tests to my application. I followed explanations on how to setup the testing library, but when I execute the "npm test" command on a component that imports for exemple : import { link } from 'svelte-routing';, there is this error :

 Jest encountered an unexpected token

 Details:

 ~pathToMyProject/node_modules/svelte-routing/src/index.js:1
 export { default as Router } from "./Router.svelte";
 ^^^^^^

 SyntaxError: Unexpected token export

Could someone help me on this one ?

Thanks.

samedro avatar May 11 '20 14:05 samedro

Hi @samedro!

It's difficult to say what might have gone wrong with your test setup without seeing your project. Could you share a minimal reproducible example that we can ideally clone and try?

The issue is that your code has not been transpiled before testing and Jest doesn't know what to do with the export keyword.

EmilTholin avatar May 19 '20 11:05 EmilTholin

I'm also getting this issue with SSR. Does the code need to be transpiled for SSR?

Edit my mistake, I had an external rule in the Svelte build options causing svelte-routing not to get bundled.

gushogg-blake avatar Jun 29 '20 19:06 gushogg-blake

@EmilTholin the problem is Babel setups doesn't transpile files within node_modules. There is no build of the library for good old CommonJS.

sonicoder86 avatar Jul 21 '20 07:07 sonicoder86

There is no build step before publishing, just the raw svelte and es6 syntax files.

sonicoder86 avatar Jul 21 '20 07:07 sonicoder86

I was able to get past this error by adding a transformIgnorePatterns in my jest.config.js

jest.config.js

module.exports = {
    transform: {
      '^.+\\.svelte$': 'svelte-jester',
      '^.+\\.js$': 'babel-jest',
    },
    transformIgnorePatterns: [
        "node_modules/?!(svelte-routing)"
      ],
    moduleFileExtensions: ['js', 'svelte'],
  }

babel.config.js

module.exports = {
    presets: [
      [
        '@babel/preset-env',
        {
          targets: {
            node: 'current',
          },
        },
      ],
    ],
  }

However, this led to another error from Link.svelte as follows:

TypeError: Cannot destructure property 'base' of 'getContext(...)' as it is undefined.

I came across this thread while looking for a solution but haven't been able to solve it.

agrawal-rohit avatar Aug 06 '20 13:08 agrawal-rohit

@agrawal-rohit Having the same issue:

TypeError: Cannot destructure property 'base' of 'undefined' or 'null'.

  at instance (node_modules/svelte-routing/src/Link.svelte:105:8)
  at init (node_modules/svelte/internal/index.js:1474:11)
  at new Link (node_modules/svelte-routing/src/Link.svelte:236:3)
  at create_fragment (src/components/Nav/Nav.svelte:207:9)
  at init (node_modules/svelte/internal/index.js:1489:37)
  at new Nav (src/components/Nav/Nav.svelte:389:3)
  at Object.render (node_modules/@testing-library/svelte/dist/pure.js:81:21)
  at Object.<anonymous> (src/components/Nav/Nav.spec.ts:5:27)`

Have you found a solution?

nhe23 avatar Jan 03 '21 12:01 nhe23

Problem

Link.svelte

...
const { base } = getContext(ROUTER); // <-- this will assigned undefined
const location = getContext(LOCATION); // <-- same here too!
const dispatch = createEventDispatcher();
...

Router.svelte

...
  setContext(ROUTER, {
    activeRoute,
    base,
    routerBase,
    registerRoute,
    unregisterRoute
  });
</script>
...

In the Link.svelte component ROUTER given to getContext(ROUTER), will result in { base } be assigned to undefined, as setContext from the Router.svelte component has not been used pass down the context object ROUTER to getContext(ROUTER)

TypeError: Cannot destructure property 'base' of 'getContext(...)' as it is undefined.

Hence you'll need to configure your tests to pass down a Router or MockRouter component, to wrap around Link, during your Jest, including @testing-library/svelte tests

Workaround

It's not a nice workaround, as I'm currently using a package to convert my test files from *.js to *.jsx solely to enable me to easily test components that are nested (same as I would in React). 😢

  1. Follow @agrawal-rohit config setup
  2. Install the following npm install --save-dev svelte-jsx @babel/plugin-transform-react-jsx
  3. Read instructions in svelte-jsx on how to test nested components - https://github.com/kenoxa/svelte-jsx#babel-configuration

You'd expect something like;

render(
  <Router>
    <Link to="/"></Link>
  </Router>,
)

anthonytranDev avatar Jan 14 '21 05:01 anthonytranDev