Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest + Vue - SyntaxError: Unexpected token <

I'm trying to add testing to my Electron + Vue2 application written in TypeScript using ts-Jest/ Jest and Chai. However when I try and run the simple test I wrote to try and make sure Jest is working correctly I'm now running into the issue of Jest seemingly not liking the fact that I'm importing the template of the component I'm testing as can be seen in the Error. When I try and search for things related to this I'm not having much luck and a lot of it points to "Unexpected token import" which is a problem I've already fixed.

If anyone has any insight or knowledge on how I can get the test to not freak out over importing HTML that would be amazing because I'm stumped and the documentation doesn't point to anything helpful it seems.

Error:

$ npm run test

> [email protected] test C:\Users\daniel\Desktop\app\app
> jest --detectOpenHandles

FAIL src/app/features/app-window/app-window.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:

    C:\Users\daniel\Desktop\app\app\src\app\features\app-application-content\app-application-content.component.html:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<webview-component v-if="src"
                                                                                             ^

    SyntaxError: Unexpected token <

      2 | import Component from 'vue-class-component'
      3 | import { Prop, Watch } from 'vue-property-decorator'
    > 4 | import Template from './app-application-content.component.html'
        | ^
      5 |
      6 | import * as qs from 'qs'
      7 | import { INameValue } from '../../../contracts/Core'

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/app/features/app-application-content/app-application-content.component.ts:4:1)
      at Object.<anonymous> (src/app/features/app-content/app-content.component.ts:9:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        12.924s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: `jest --detectOpenHandles`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\daniel\AppData\Roaming\npm-cache\_logs\2018-11-21T14_25_23_427Z-debug.log

jest.config.js

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node'],
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: {
    'ts-jest': {
      tsConfig: './src/app/tsconfig.json'
    },
    NODE_ENV: 'test'
  }
}

tsconfig.json

{
  "compilerOptions": {
    "allowJs": true,
    "outDir": "./built/",
    "sourceMap": true,
    "strict": true,
    "moduleResolution": "node",
    "target": "ES2017",
    "experimentalDecorators": true,
    "noImplicitAny": false,
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "lib": ["es2017", "dom"],
    "include": [
      "**/*",
      "../types/**/*",
      "../../node_modules/bootstrap-vue/**/*",
      "../../node_modules/electron/**/*"
    ]
  }
}

app-window.component.spec.ts

import { expect } from 'chai'
import 'jest'
import { appWindowComponent } from './app-window.component'

const appWindowComponent = new appWindowComponent()

describe('Test: Set Title Function', () => {
  it('should set the variable title to the passed variable', () => {
    const title = 'this is a test'
    appWindowComponent.setTitle(title)
    expect(appWindowComponent.title).to.equal(title)
  })
})
like image 962
Daniel Turcich Avatar asked Nov 21 '18 15:11

Daniel Turcich


1 Answers

After sleuthing around I found the answer here

New jest.config.js

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  verbose: true,
  moduleDirectories: ['node_modules', 'src'],
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
  moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],
  transform: {
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  },
  transformIgnorePatterns: ['node_modules/(?!(bootstrap-vue)/)'],
  testPathIgnorePatterns: [
    '/build/',
    '/config/',
    '/data/',
    '/dist/',
    '/node_modules/',
    '/test/',
    '/vendor/'
  ],
  globals: {
    'ts-jest': {
      tsConfig: './src/app/tsconfig.json'
    },
    NODE_ENV: 'test'
  }
}

Note

transform: {
    '^.+\\.html$': '<rootDir>/config/htmlLoader.js'
  }, 

moduleFileExtensions: ['js', 'ts', 'json', 'node', 'html'],

Html Loader file

const htmlLoader = require('html-loader')

module.exports = {
  process(src, filename, config, options) {
    return htmlLoader(src)
  }
}

This seemingly has worked as I'm now getting a new error :)

like image 160
Daniel Turcich Avatar answered Oct 15 '22 17:10

Daniel Turcich