Jest-preset-angular: Jest with Angular 7 SyntaxError: Unexpected token {

Created on 31 May 2019  ·  13Comments  ·  Source: thymikee/jest-preset-angular

I don't even know where to start with this one as I am not too familiar with testing and using this package for jest testing. I have about 27 fails and all have a variety of :

 FAIL  src/Components/chat/chat.component.spec.ts
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/user/application/app/node_modules/@ionic/angular/dist/fesm5.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { __extends, __awaiter, __generator, __assign } from 'tslib';
                                                                                                    ^

    SyntaxError: Unexpected token {

      3 | import { MediaCapture, MediaFile, CaptureError, CaptureImageOptions } from '@ionic-native/media-capture';
      4 | //Schemas
    > 5 | import { Contact } from '../../Schemas/Contact';
        |                 ^
      6 | import { Message } from '../../Schemas/Message';
      7 | //Services
      8 | import { ChatService } from '../../app/Services/SocketIO/chat.service';

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
      at Object.<anonymous> (src/Components/chat/chat.component.ts:5:17)

I have seen posts regarding '<' but haven't encountered one with '{' I have no idea where to even start with this.

read this and this oh and can't forget this

Most helpful comment

how I have updated:

jest.config.js

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  moduleNameMapper: {
    '@app/(.*)': '<rootDir>/src/app/$1',
    '@assets/(.*)': '<rootDir>/src/assets/$1',
    '@core/(.*)': '<rootDir>/src/app/core/$1',
    '@env': '<rootDir>/src/environments/environment',
    '@src/(.*)': '<rootDir>/src/src/$1',
    '@state/(.*)': '<rootDir>/src/app/state/$1'
  },
  transformIgnorePatterns: [
    '/node_modules/(?!@ionic|ngx-socket-io/).+\\.js$'
  ]
};

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

ts.config.spec.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "allowJs": true,
    "types": [
      "jest",
      "jasmine",
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

hope this will save someone many hours!

All 13 comments

tsconfig.spec.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "types": [
      "jest",
      "jasmine",
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

jest.config.js

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  moduleNameMapper: {
    '@app/(.*)': '<rootDir>/src/app/$1',
    '@assets/(.*)': '<rootDir>/src/assets/$1',
    '@core/(.*)': '<rootDir>/src/app/core/$1',
    '@env': '<rootDir>/src/environments/environment',
    '@src/(.*)': '<rootDir>/src/src/$1',
    '@state/(.*)': '<rootDir>/src/app/state/$1'
  },
  transformIgnorePatterns: ['node_modules/(?!(jest-test))']
};

been trying to follow this thread and here for the solutions however it is still failing with the same issue, I also now have the .babelrc file that was mentioned and have the preset installed.

Can you also share your tsconfig.json? Which version of Angular are you using?

sure, I am using Angular 7, Ionic 4/Cordova

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

The problem is, that jest runs inside node.js. node.js only allows commonjs-style imports of other files using require(...), not import.

Before passing your files to jest, ts-jest will transpile the Angular TypeScript files to javascript and put them in commonjs syntax, so jest can load them and test them without any problem.

Packages in node_modules are expected by jest to not be required to transform. But if you look at node_modules/@ionic/angular/dist/fesm5.js, you will see that this is not the issue for the ionic package. It uses es6-style imports.

The solution to your problem is this, as suggested by the initial Jest message:

To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.

@wtho ok, thank you for your response. I will try and give that a try, again. I have tried so many things before wasting people's time here that I forgot all that I have tried. However, I tried to have all the node_modules be ignored but that didn't fix anything. Also,

• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.

so in order for it _TO BE_ transformed you add it to the _IGNORE_ patterns.... seems backwards no?

The default configuration of the transformIgnorePatterns are set to [/node_modules/], as you can see in the official documentation. When using this preset, it will be set to ['node_modules/(?!@ngrx)'].

When overriding you will want to say "ignore everything in node_modules except @ionic". An example of this is shown in our documentation:
transformIgnorePatterns: ['node_modules/(?!@ionic)']

Thanks but it is still not transforming somethings, for example:

    /Users/user/Desktop/application/app/node_modules/@ionic/angular/dist/fesm5.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { __extends, __awaiter, __generator, __assign } from 'tslib';

The error above is also repeated for the ngx-socket-io (which I have aded to the IgnorePatterns but does't appear to have taken effect.

I have updated my config to:

  transformIgnorePatterns: [
    'node_modules/(?!@ionic)',
    'node_modules/(?!@ionic/angular)',,
    'node_modules/(?!ngx-socket-io)'
  ]

sorry for being dense, 😅. I have also been running $ jest --clearCache to make sure that it is running fresh

This won't work:

  transformIgnorePatterns: [
    'node_modules/(?!@ionic)',
    'node_modules/(?!@ionic/angular)',,
    'node_modules/(?!ngx-socket-io)'
  ]

As stated in the docs:

If the test path matches any of the patterns, it will not be transformed.

Therefore node_modules/@ionic/angular/dist will match in /node_modules/(?!ngx-socket-io)/, and therefore be ignored. You can try this in any node repl or in online regex tools.

You have to put them all in one pattern, otherwise anything not matching the first ignore pattern will be matched in another one:
'node_modules/(?!@ionic)(?!ngx-socket-io)'

Yeah, running --clearCache is a good point. You can also run with --no-cache during the try-out phase.

still not working. I have been trying:

  • transformIgnorePatterns: ['node_modules/(?!@ionic/)']
  • transformIgnorePatterns: ['node_modules/(?!@ionic/).+\\.js$'] as recommended here
  • "node_modules/(?!(@ionic)/)"recommended here
  • "node_modules/(?!@ionic/)"
  • "node_modules/(?!@ionic)/"

I am trying to just ignore one file before I worry about two or three. I'm just trying the shotgun approach now because I am absolutely dumfounded by this.

Ok, after that you are passing all of the js files to ts-jest:

  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },

ts-jest will use tsc with your tsconfig.spec.ts. To let js files transformed by ts-jest, you will have to add "allowJs": true to the compilerOptions, otherwise they will be left untouched, which is not what we want.

So try to add this to tsconfig.spec.ts and see if it works then.

I had the "allowJs": true in my package.json, but ot in the tsconfig.spec.ts file! klajsdfkhasdiuadsiufaisuyfasu alright, now on to multiple node modules! thanks a lot for your help!

how I have updated:

jest.config.js

module.exports = {
  preset: 'jest-preset-angular',
  roots: ['src'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  setupFilesAfterEnv: ['<rootDir>/src/setup-jest.ts'],
  moduleNameMapper: {
    '@app/(.*)': '<rootDir>/src/app/$1',
    '@assets/(.*)': '<rootDir>/src/assets/$1',
    '@core/(.*)': '<rootDir>/src/app/core/$1',
    '@env': '<rootDir>/src/environments/environment',
    '@src/(.*)': '<rootDir>/src/src/$1',
    '@state/(.*)': '<rootDir>/src/app/state/$1'
  },
  transformIgnorePatterns: [
    '/node_modules/(?!@ionic|ngx-socket-io/).+\\.js$'
  ]
};

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

ts.config.spec.json

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "allowJs": true,
    "types": [
      "jest",
      "jasmine",
      "node"
    ],
    "module": "commonjs"
  },
  "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]
}

hope this will save someone many hours!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blackholegalaxy picture blackholegalaxy  ·  6Comments

thekip picture thekip  ·  6Comments

maxencefrenette picture maxencefrenette  ·  8Comments

Nxt3 picture Nxt3  ·  4Comments

r-kernberger picture r-kernberger  ·  7Comments