Stryker: StrykerCli an error occurred SyntaxError: Unexpected character '#'

Created on 1 Jul 2019  路  10Comments  路  Source: stryker-mutator/stryker

Summary

I am using Stryker with Babel as transpiller and in one of my classess I've got private property #hash. When I try to run Stryker on that class it fails.

Class:

const something = require('something');
const something2 = require('something2');
const something3 = require('something3');

class Example {
    #hash = '';

    constructor(hash) {
        this.#hash = hash;
    }
}

Error I am getting:

16:45:00 (12996) ERROR StrykerCli an error occurred SyntaxError: Unexpected character '#' (6:4)
    at Object.raise (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:6344:17)
    at Object.readToken_numberSign (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:6671:12)
    at Object.getTokenFromCode (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:7017:14)
    at Object.getTokenFromCode (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:3631:18)
    at Object.getTokenFromCode (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:2306:20)
    at Object.nextToken (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:6542:12)
    at Object.next (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:6482:10)
    at Object.eat (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:6487:12)
    at Object.expect (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:7645:10)
    at Object.parseClassBody (C:\Users\my_username\PhpstormProjects\my-project-name\node_modules\@babel\parser\lib\index.js:10562:10) {
  pos: 166,
  loc: Position { line: 6, column: 4 }
}

Stryker config

module.exports = function (config) {
    config.set({
        mutator: 'javascript',
        packageManager: 'npm',
        reporters: ['html', 'clear-text', 'progress'],
        testRunner: 'mocha',
        transpilers: ['babel'],
        coverageAnalysis: 'off',
        babel: {
            optionsFile: '.babelrc'
        },
        mochaOptions: {
            spec: ['test/**/*.js'],
        }
    });
};

Stryker environment

+-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected]
+-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected] deduped
| +-- @stryker-mutator/[email protected] deduped
+-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected] deduped
| +-- @stryker-mutator/[email protected] deduped
+-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected] deduped
+-- @stryker-mutator/[email protected]
| `-- @stryker-mutator/[email protected] deduped
+-- @stryker-mutator/[email protected]
| +-- @stryker-mutator/[email protected] deduped
+-- mocha ^6.1.4

Test runner environment

# Test command
mocha
# .mocharc.js
module.exports = {
    recursive: true
};
# .babelrc
{
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-private-methods"
  ]
}

Your Environment

| software | version(s)
| ---------------- | -------
| node | v12.3.1
| npm | 6.9.0
| Operating System | Windows 10

Add stryker.log



stryker.log

馃殌 Feature request

All 10 comments

Have you tried running babel itself? Or do you have some repo we could use to test it?

@simivar Thanks for showing that. It is an issue. After a short investigation, I have found that code is transpiled at first, but then after passing to mutate it, it is not transpiled at all(?) quite strange thing
image
image

@nicojs any thoughts?

@simivar I think I have nailed it :)
image
So...
Problem in stryker is, as i said, missing plugins in stryker/packages/javascript-mutator/src/helpers/BabelHelper.ts

'classPrivateProperties',
'classProperties',
'classPrivateMethods',

These 3 are missing (probably classProperties aren't necessary but still I have included them.

(note, you need to use files option in your stryker config - in this case files = [+(src|test)/classes/*.js]

The second (it is quite breaking issue) is in your code.
you have to add .js in require or somehow everything will crash (at least it crashed on my PC)
(@nicojs you should investigate this crash since it is super strange. I can open an issue if it's necessary. Code to replicate that is already given: https://github.com/simivar/stryker-issue-1614)

(note, you need to use files option in your stryker config - in this case files = [+(src|test)/classes/*.js]

This should never be needed (at least, not when running from inside a git repo).

Indeed @kmdrGroch is correct.

The @stryker-mutator/javascript-mutator right now brings it's own babel and babel plugins. Feel free to add more plugins here in a PR, or (better maybe) allow users to define their own plugins in stryker options. We should be able to add config like this to the mutator object in the stryker config

@nicojs I suggest using babelPlugins with javascript mutator like so: mutator: { name: 'javascript', excludedMutations: ['BooleanSubstitution', 'StringLiteral'], babelPlugins: [] }.
Then we can just extend our default plugins array in BabelHelper.ts by elements given by user

I don't know however what about Typescript.

And yea, these 'files' was my problem since I downloaded repo as zip, not cloned it so I didn't have .git

Wouldn't it be better to use transpillers settings? It seems like this option would be a duplicate.

As I think about it... what are transpilers for? Shouldn't mutations be run on transpiled files? Then that problem would cease to exist.

I guess the problem is in reporting @simivar... Like you get 'your code' in reports not compiled one. If we pass compiled code, you will get reports for ES5(?) babel code

and take a look @simivar that names of babelPlugins are different in these 2 places...

'classPrivateProperties',
'classProperties',
'classPrivateMethods',

vs

"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-private-methods"

It looks like that there is a similar issue in the version 4.0.0 with the ts-parser:

export async function parse(text: string, fileName: string): Promise<TSAst> {
  const isTSX = fileName.endsWith('x');
  const ast = await parseAsync(text, {
    filename: fileName,
    parserOpts: {
      ranges: true,
    },
    configFile: false,
    babelrc: false,
    presets: [[require.resolve('@babel/preset-typescript'), { isTSX, allExtensions: true }]],
    plugins: [[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }]],
  });

The plugins for ts-parser are fixed and with a set of plugins that do not give support for private properties like #hash

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
If you want to leave it as-is, add @babel/plugin-syntax-class-properties (https://git.io/vb4yQ) to the 'plugins' section to enable parsing.
    at Object._raise (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:766:17)
    at Object.raiseWithData (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:759:17)
    at Object.expectOnePlugin (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:8981:18)
    at Object.parseMaybePrivateName (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:10351:12)
    at Object.parsePropertyName (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:10854:155)
    at Object.parseClassElementName (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:12401:22)
    at Object.parseClassMemberWithIsStatic (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:12319:22)
    at Object.parseClassMemberWithIsStatic (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:6735:11)
    at Object.parseClassMember (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:12289:10)
    at Object.parseClassMember (D:\repository\Spider\NS-Netin-Logger-TypeScript\node_modules\@babel\parser\lib\index.js:6710:11) {
  loc: Position { line: 41, column: 2 },
  pos: 1635,
  missingPlugin: [ 'classPrivateProperties', 'classPrivateMethods' ],
  code: 'BABEL_PARSE_ERROR'
Was this page helpful?
0 / 5 - 0 ratings

Related issues

anthony-telljohann picture anthony-telljohann  路  19Comments

j-truax picture j-truax  路  20Comments

jeznag picture jeznag  路  17Comments

nosideeffects picture nosideeffects  路  32Comments

davesag picture davesag  路  17Comments