Skip to content

SyntaxError: Unexpected token export using jest #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
loic-lopez opened this issue Mar 14, 2019 · 37 comments
Closed

SyntaxError: Unexpected token export using jest #39

loic-lopez opened this issue Mar 14, 2019 · 37 comments
Labels
bug Something isn't working

Comments

@loic-lopez
Copy link

loic-lopez commented Mar 14, 2019

Current behavior

/@react-native-community/async-storage/lib/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export default from './AsyncStorage';

 SyntaxError: Unexpected token export

    > 1 | import AsyncStorage  from "@react-native-community/async-storage"
        | ^
      2 | 
      3 | /**
      4 |  * Loads a string from storage.

Repro steps

import @react-native-community/async-storage and test with jest.

Environment

  • Async Storage version: 1.2.1
  • React-Native version: 0.57.7
  • Platform tested: iOS / Android
  • Jest version: 24.0.11
  • Logs/Error that are relevant: see above
@krizzu krizzu added the bug Something isn't working label Mar 15, 2019
@krizzu
Copy link
Member

krizzu commented Mar 15, 2019

Hey @loic-lopez

Async Storage is not being transformed by Jest, so in your jest.config.js or jest entry in package.json, add:

"transformIgnorePatterns": ["/node_modules/@react-native-community/async-storage/(?!(lib))"]

@vgm8
Copy link

vgm8 commented Mar 15, 2019

The error still happening after adding your solution.

@loic-lopez
Copy link
Author

@krizzu thanks for reply and yes transformIgnorePatterns seems to have solved the problem but,
when i try to mock the library like that:
Capture d’écran 2019-03-15 à 11 30 54

I got:

● save

    expect(jest.fn()).toHaveBeenCalledWith(expected)

    Expected mock function to have been called with:
      ["something", "{\"x\":1}"]
    But it was not called.

      34 | test("save", async () => {
      35 |   await save("something", VALUE_OBJECT)
    > 36 |   expect(mockSetItem).toHaveBeenCalledWith("something", VALUE_STRING)
         |                       ^
      37 | })
      38 | 
      39 | test("saveString", async () => {

      at Object.<anonymous>.test (test/tests/storage.test.ts:36:23)

as if the mock did not work

@krizzu
Copy link
Member

krizzu commented Mar 15, 2019

@loic-lopez This is more like Jest question :) You can checkout Jest docs about mocking node_modules libs.

Basically, create __mocks__ in project root (unless your roots Jest settings says differently), create @react-native-community/async-storage/index.js in there and export mocked functions.

@vgm8 Anything particular that could help me figuring this out?

@loic-lopez
Copy link
Author

loic-lopez commented Mar 15, 2019

@krizzu the mock is on top of my @react-native-community/async-storage test see bellow:
Capture d’écran 2019-03-15 à 12 08 05

@vgm8
Copy link

vgm8 commented Mar 17, 2019

@krizzu your solution was not working because i had some errors in the jest configuration. After I fixed it works fine, thank you!

@krizzu
Copy link
Member

krizzu commented Mar 19, 2019

@vgm8 Thanks great!

Would you mind sharing your solution, for future references?

@loic-lopez
Copy link
Author

@krizzu As you can see above, the mock is being running before my tests.

@NemanjaManot
Copy link

I have same issue. @loic-lopez

@vgm8
Copy link

vgm8 commented Mar 20, 2019

Sure @krizzu! As you said in your comment I've created __mocks__/@react-native-community/async-storage/index.js

let cache = {};
export default {
  setItem: (key, value) => {
    return new Promise((resolve, reject) => {
      return (typeof key !== 'string' || typeof value !== 'string')
        ? reject(new Error('key and value must be string'))
        : resolve(cache[key] = value);
    });
  },
  getItem: (key, value) => {
    return new Promise((resolve) => {
      return cache.hasOwnProperty(key)
        ? resolve(cache[key])
        : resolve(null);
    });
  },
  removeItem: (key) => {
    return new Promise((resolve, reject) => {
      return cache.hasOwnProperty(key)
        ? resolve(delete cache[key])
        : reject('No such key!');
    });
  },
  clear: (key) => {
    return new Promise((resolve, reject) => resolve(cache = {}));
  },

  getAllKeys: (key) => {
    return new Promise((resolve, reject) => resolve(Object.keys(cache)));
  },
}

An then in my tests I just import and mock @react-native-community/async-storage like this:

import AsyncStorage from '@react-native-community/async-storage';
jest.mock('@react-native-community/async-storage');

@loic-lopez
Copy link
Author

@NemanjaManot Do you have resolved your issue?

@NemanjaManot
Copy link

@loic-lopez not yet.

@opiruyan
Copy link

getting
@RNCommunity/AsyncStorage: NativeModule.RCTAsyncStorage is null.
after adding transformIgnorePatterns

@krizzu
Copy link
Member

krizzu commented Mar 27, 2019

@opiruyan Thanks!

This is from latest release (1.2.2), where we notice devs to link the library in order to use it.

I'll try to come up with custom mocks + docs to help people test this library on the weekend.

thanks.

@tsvetan-ganev
Copy link

@vgm8, thanks for your mock implementation, it saved me time and I can confirm that it works.

@krizzu
Copy link
Member

krizzu commented Apr 1, 2019

Hey everyone participating in this issue,

I've created a PR with mocks and jest integration guide, so I hope future issues with testing would be resolved.

Let me know what you think!

thanks.

#edit fixed link

@loic-lopez
Copy link
Author

@krizzu thanks but your link seems to be broken.

@nirre7
Copy link

nirre7 commented Apr 8, 2019

@krizzu

Updated the lib but I din't get the @react-native-community/async-storage/jest/async-storage-mock

The jest folder doesn't seem to be included in the dist of react-native-async-storage?

"dependencies": { "@react-native-community/async-storage": "1.2.4",

@krizzu
Copy link
Member

krizzu commented Apr 8, 2019

@nirre7,

Jest mocking is not yet releases, going to do it after merging #61 and #57 later today.

@nirre7
Copy link

nirre7 commented Apr 8, 2019

Oh, I thought it was since it was in the docs.
No worries, thanks for the quick answer though.

@opiruyan
Copy link

opiruyan commented Apr 9, 2019

looks like RN took care of transformIgnorePatters-part of the issue
https://github.com/facebook/react-native/releases/tag/v0.59.4

@krizzu
Copy link
Member

krizzu commented Apr 9, 2019

@krizzu krizzu mentioned this issue Apr 10, 2019
@krizzu
Copy link
Member

krizzu commented Apr 11, 2019

Released in v1.3.0, please check it out 🙏

@krizzu krizzu closed this as completed Apr 11, 2019
@redreceipt
Copy link

@krizzu I'm still have issues, are you aware of this problem:

 FAIL  src/slides/AskNotifications/AskNotificationsConnected.tests.js
  ● Test suite failed to run

    .../node_modules/@react-native-community/async-storage/jest/async-storage-mock.js:6
    type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

The solution here was switching to a different mocking package but I'm hoping that's not necessary.

@redreceipt
Copy link

redreceipt commented Jul 21, 2019

@krizzu I'm still have issues, are you aware of this problem:

 FAIL  src/slides/AskNotifications/AskNotificationsConnected.tests.js
  ● Test suite failed to run

    .../node_modules/@react-native-community/async-storage/jest/async-storage-mock.js:6
    type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

The solution here was switching to a different mocking package but I'm hoping that's not necessary.

turns out I fixed it by using @vgm8's mock above So maybe there's a syntax error in your official one that Jest doesn't like.

@janpe
Copy link

janpe commented Aug 29, 2019

@krizzu should the problem mentioned above be fixed in the official mock? I'm getting the same thing.

@krizzu
Copy link
Member

krizzu commented Aug 30, 2019

@redreceipt @janpe We use this setup on the repo's example app and it's fine. Seems like your setup might be missing a proper flow handling.
What's the preset you use? How does your setup look like? Could you come up with a repo that I could look into?

@frozenzia
Copy link

We see the same KeysType error. Also fixable by using @vgm8's mock.

@krizzu
Copy link
Member

krizzu commented Sep 17, 2019

It seems like the issue comes from the lack of transformation by Jest. We have a docs on how to fix this here. Let me know if it worked.

@frozenzia
Copy link

frozenzia commented Sep 17, 2019

@krizzu, no help, at least, with the "Jest setup file" option.

So to be clear, I've followed the instructions to include 2 lines in my setup file, AND included the transformIgnorePatterns you suggested.

[EDIT] Ah, right, but I'm also using RN 0.59.10, so since that ignore pattern is already part of 0.59.4, my understanding is that this should be unnecessary.

[EDIT2] I'd swear this has something to do with Typescript not being recognized. Does that help?

[EDIT3] Ok, so FLOW, not TypeScript, and I seem to have determined, "No, it's not a tumor!" (i.e. that's not the problem) BTW, sorry for the constant EDITs -- hopefully this is clearer than replying to myself a million times in separate posts.

[EDIT4] Some progress. So creating __mocks__/@react-native-community/async-storage.js and copying the contents of node_modules/@react-native-community/jest/async-storage-mock.js into there, I get errors related to async/await not being properly transpiled by Babel. So adding @babel/preset-env to my project (npm i -D @babel/preset-env) and including the following in my babel.config.js:

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

With this setup, tests pass. But if instead of copying the contents I just have the export default from '@react-native-community/async-storage/jest/async-storage-mock' line from the instructions, I get errors pointing to KeysType again.

As far as I understand things, which at this point is not all that well, this would sure seem to indicate that my node_modules files are, in fact, not being transpiled by Babel before being passed on to Jest.

@cinder92
Copy link

@frozenzia did you find the solution for this? im having the same...

@frozenzia
Copy link

frozenzia commented Sep 24, 2019

@cinder92 , no, actually. I got fed up / out-of-time trying to figure out what was going on with the mock included in the package, and just went with a modified version of @vgm8's mock. We only needed setItem, getItem, and removeItem, AND we have some airBnB eslint rules in place so that the end result was that __mocks__/@react-native-community/async-storage.js (note name! opted for this instead of making an additional async-storage folder and putting index.js in it) looks like this:

const cache = {};
export default {
    setItem: (key, value) => new Promise((resolve, reject) => {
        const retVal = (typeof key !== 'string' || typeof value !== 'string')
            ? reject(new Error('key and value must be string'))
            : resolve(cache[key] = value);
        return retVal;
    }),
    getItem: key => new Promise(resolve => (
        Object.prototype.hasOwnProperty.call(cache, key)
            ? resolve(cache[key])
            : resolve(null))),
    removeItem: key => new Promise((resolve, reject) => (
        Object.prototype.hasOwnProperty.call(cache, key)
            ? resolve(delete cache[key])
            : reject(new Error('No such key!')))),
};

@krizzu
Copy link
Member

krizzu commented Sep 24, 2019

@frozenzia How does your setup looks like? Is it monorepo by any chance?

type KeysType = Array<string>;
     ^^^^^^^^

SyntaxError: Unexpected identifier

Looks like an issue with Flow type striping. Do you have it included in your project?

@janhesters
Copy link

janhesters commented Nov 5, 2019

My project neither contains Flow nor TypeScript and I too get the KeysType error:

  ● Test suite failed to runmponent.test.js

    /Users/jan/dev/my-app/node_modules/@react-native-communit
y/async-storage/jest/async-storage-mock.js:
6
    type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

It feels like @react-native-community/async-storage/jest/async-storage-mock needs to be fixed to work with plain JS projects.

@jsidorenko
Copy link

It's also possible to exclude this file in .flowconfig by adding <PROJECT_ROOT>/node_modules/@react-native-community/async-storage/jest/.* under the [ignore] section

@fabiendem
Copy link

I have fixed the error

type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

using those instructions in my project: https://github.com/react-native-community/async-storage/blob/LEGACY/docs/Jest-integration.md#syntaxerror-unexpected-token-export-in-async-storagelibindexjs

@belgamo
Copy link

belgamo commented Apr 23, 2020

I have fixed the error

type KeysType = Array<string>;
         ^^^^^^^^

    SyntaxError: Unexpected identifier

using those instructions in my project: https://github.com/react-native-community/async-storage/blob/LEGACY/docs/Jest-integration.md#syntaxerror-unexpected-token-export-in-async-storagelibindexjs

#194 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests