in jest test enzyme.shallow throws Unexpected token < error - javascript

I am currently setting up unit tests with usage of following stack:
react (v15) components are written with typescript (.tsx)
test setup is done with jest(v21) and enzyme(v3)
test files are written as plain js-files
Unfortunately something seems to go wrong with enzyme as I keep getting an error:
wrapper = enzyme.shallow(<Stepper>bla</Stepper>)
^
SyntaxError: Unexpected token <
at new Script (vm.js:51:7)
at Generator.next (<anonymous>)
at new Promise (<anonymous>)
Test Suites: 1 failed, 1 total
The respective test file looks like this:
var React = require('react');
var enzyme = require('enzyme');
var Stepper = require('./Stepper').default;
var wrapper;
describe('Stepper', () => {
beforeEach(() => {
wrapper = enzyme.shallow(<Stepper>bla</Stepper>)
});
test('has bla', () => {
expect(wrapper.contains('bla')).toBeTruthy();
});
});
I configured jest as followed in my package.json:
"jest": {
"transform": {
"^.+\\.(tsx|ts)$": "typescript-babel-jest"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testMatch": [
"<rootDir>/src/**/**/*.test.js"
],
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy"
},
"setupTestFrameworkScriptFile": "<rootDir>/setupTests.js"
}
And my setupTests.js file looks like this:
var enzyme = require('enzyme');
var Adapter = require('enzyme-adapter-react-15');
enzyme.configure({ adapter: new Adapter() });
I am running out of ideas what could be causing the issue, does anyone know a solution to this?

You need your test file to be transpiled by babel because it contains jsx. Using jsx requires to have React imported and the file to be transpiled by babel.
At the moment you do only transpile files ending with .tsx or .ts as definded in your package.json. Add .js as your test file ends on .js:
"transform": {
"^.+\\.(tsx|ts|js)$": "typescript-babel-jest"
},
Alternatively write your test file in typescript and use .tsx as the file ending.

First install ts-jest then use this command
npx ts-jest config:init
This work for me.

Related

Mocha / Webpack: Cannot use import statement outside a module

I'm new to Node and JS Testing. I have a web applications w/ Webpack as a bundler. I have some entry point JS's which are included into the page. The entry points are using module files like this:
export default function() {
...
}
Now I would like to Unit test this module. I have picked up Mocha but it is not critical to me. Could be Jest or anything else.
I wrote a very simple test.js like this. It it not doing anything but tests if the entire setup works:
import foo from '../js/someModuleOfMine'
const assert = require('assert')
describe('Test Suite', () => {
it('should at least run', () => {
assert.equal(true, true)
})
})
executing mocha from CLI gives me this error:
import foo from '../js/someModuleOfMine'
^^^^^^
SyntaxError: Cannot use import statement outside a module
Adhering to some advises I have tired to add "type": "module" to my package.json but it only changed error to something even more obscure:
Error: Not supported
I am definitely missing something obvious but I cannot comprehend what.
Not sure if it will help the OP, but I had the same problem and it was due to typescript. I solved in this way:
install ts-node:
npm install ts-node --save-dev
add the require line in the mocha config (I have it in the package.json, but one can also have it in the .mocharc.json file):
"mocha": {
"spec": "./**/*test.ts",
"ignore": "./node_modules/**",
"require": "ts-node/register/files",
"timeout": 20000
}

How can I get my typescript test to recognise JSX?

I'm working on an ASP.NET core project with a typescript front-end. I want to write tests for the typescript using Mocha, Chai and Mockito (since I want to test React components, I think I also need Enzyme). On running npm test I get errors at the first '<' in the line const element = <h1>Hello, world</h1>;
The test file is a .tsx and is referenced in the package.json as
"mocha": {
"extension": [ "ts", "tsx" ],
"spec": "wwwroot/ts-tests/**/*.test.tsx"
}
and in the tsconfig.json as
"include": ["./wwwroot/ts-tests/**/*.test.tsx"]
The test file is as follows:
describe('Rendering',
() => {
it('should show header',
() => {
const rootContainer = document.createElement('div');
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, rootContainer);
});
}
)
I think I've narrowed the problem down to the fact that node.js isn't recognising JSX because running tests with only javascript in works fine and the tsx is being transpiled into js fine as well.
Any ideas? I'd prefer not to keep adding more new modules if I can help it

Using jest to test an Angular Library?

Trying to test an Angular 9 library with Jest, and I've installed the dependencies for Jest and Typescript within the local library package.json like this:
"devDependencies": {
"#types/jest": "^25.1.3",
"jest": "^25.1.0",
"ts-jest": "^25.2.1"
},
And also setup jest.config.js like this:
module.exports = {
"roots": [
"<rootDir>/src/"
],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
}
}
However it looks as if jest is not running through the ts-jest transform as I'm getting errors like this:
SyntaxError: Unexpected token export
> 1 | import assertString from './util/assertString';
| ^
2 | import toString from './util/toString';```
Figured it out. I'm converting ValidatorJS into a Typescript project using the Angular Package Format, and I forget to change the file name extension on the utilities from .js to .ts, hence Jest was complaining about the import statement.
In case anyone else wants to setup their project to do this type of thing I wrote up a few articles here:
https://medium.com/#ole.ersoy/unit-testing-angular-with-jest-b65888ff33f6
https://medium.com/#ole.ersoy/unit-testing-your-angular-library-project-with-jest-42429a8716eb

How do I correctly configure mocha tests with ts_transformer_keys?

I can't seem to set the custom transformer for ts-transform-keys with my mocha tests.
I’m using mocha 6.1.4
ts-node 8.3.0 https://www.npmjs.com/package/ts-node
ts-trasnformer-keys 0.3.5 https://github.com/kimamula/ts-transformer-keys
ttypescript 1.5.7 https://github.com/cevek/ttypescript
The ts-node documentation says that you cannot set a custom transformer on the CLI, only programatically. So I'm trying to use ttypescript to get around that restriction.
I've tried the following...
Note: test.ts contains the following
import { keys } from 'ts-transformer-keys';
describe("xyz"), () => {
it("123", (done) => {
keys<CustomInterface>();
});
});
Attempt 1) - Set the ts-node with an environment variable
TS_NODE_COMPILER="ttypescript" mocha test/test.ts --require ts-node/register
Then I have the following in test/tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "transform": "ts-transformer-keys/transformer" }
]
}
}
This results in Uncaught TypeError: ts_transformer_keys_1.keys is not a function which indicates that the custom transformer wasn't used at compile time.
Attempt 2) Following the typescript API example from ts-transformer-keys
I added a mocha.opts file with the following
--file test/transformer-config.js
and a transformer-config.js file with the following
const ts = require('typescript');
const keysTransformer = require('ts-transformer-keys/transformer').default;
const program = ts.createProgram(['test/test.ts'], {
strict: true,
noEmitOnError: true,
target: ts.ScriptTarget.ES5
});
const transformers = {
before: [keysTransformer(program)],
after: []
};
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, false, transformers);
if (emitSkipped) {
throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
}
Then I invoke it like this mocha test/test.ts --require ts-node/register
This results in the following error
/Users/jjohnson/Documents/OCS/hmp/git/hmp-server/server/test/ttypescript-register.js:17
throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
^
Error: [object Object]
[object Object]
[object Object]
at Object.<anonymous> (/Users/jjohnson/Documents/OCS/hmp/git/hmp-server/server/test/ttypescript-register.js:17:9)
at Module._compile (internal/modules/cjs/loader.js:777:30)
...
It feels like in Attempt 1 it wasn't ever calling the code that sets the custom transformer in tsconfig.json or if it was getting called the code was failing silently.
It feels like in Attempt 2 I'm creating a new instance of the typescript program and then that fails for some reason. And even if it succeeded I'm not sure that this is the right way to go about configuring things since the ts.createProgram wants a list of RootNames for the files it will transpile.
Maybe my entire approach is wrong.
All I really want is a way that in my mocha tests I can verify that the expected result type is what the method returned. And I'd like to be able to do this w/out touching too much of the source code.
you should be able to define your required module (see below) and run ts-node programmatically. In this way, you can safely use any customer transformer.
// tsnode.js
const transformer = require('ts-transformer-keys/transformer').default;
require("ts-node").register({
transformers: program => ({
before: [
transformer(program)
]
})
});
then you can run mocha with require
mocha --require './tsnode.js' --watch-extensions ts,tsx "test/**/*.{ts,tsx}
You can tell ts-node which compiler to use in tsconfig.json. This is covered in the ts-node docs. If your using transformers presumably your also using ttypescript compiler. You just need to add this:
"ts-node": {
"compiler": "ttypescript"
}

Ava unit tests failing with TypeScript ("SyntaxError: Unexpected identifier")

I'm learning TypeScript and I created a TypeScript React app with create-react-app. It uses a separate TypeScript file, logic.ts, which in turn imports a JSON file
import pastaData from './data/users-pasta.json'
const ParsedUserData = pastaData.map(data => ({name: data.name, gender:data.gender,favorites: data.favorites}));
export const getPastaData = () => ParsedUserData;
It works fine. But when I run my Ava test (which for the moment does nothing)
const {getPastaData} = require( '../src/logic.ts')
describe("A suite", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
I get the following error
/src/logic.ts:1
(function (exports, require, module, __filename, __dirname) { import pastaData from './data/users-pasta.json';
SyntaxError: Unexpected identifier
It's complaining about the 'pastaData' import here.
I set up Ava to work with Typescript (from package.json)
{
"ava": {
"compileEnhancements": false,
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
}
}
And have now been trying to get Ava-ts to work. Same problem.
I think it's an issue with ts-node but changing all the linked files to 'require' is proving problematic (and TypeScript starts complaining). Is there a way to get this to work with 'ES-6' 'imports'? Or is there something else I'm missing entirely?
Any help much appreciated!
AVA (with TypeScript setup) compiles the TypeScript code back to JavaScript before execution.
And NodeJS does not support esm syntax unless you are doing *.mjs.
So you have to set your "module" to "commonjs" in your tsconfig.json:
{
"compilerOptions": {
"module": "commonjs"
}
}

Categories

Resources