Skip to content
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

export before class decorator breaks stryker #4879

Open
Rubenvdbrink opened this issue Jun 12, 2024 · 1 comment
Open

export before class decorator breaks stryker #4879

Rubenvdbrink opened this issue Jun 12, 2024 · 1 comment
Labels
🐛 Bug Something isn't working

Comments

@Rubenvdbrink
Copy link

Rubenvdbrink commented Jun 12, 2024

Summary
When i use export before any class decorator notation stryker will throw errors.

Does work

@Pipe({ name: 'contactName', standalone: true })
export class ContactNamePipe implements PipeTransform {
    transform(value: Contact) : string {
        return `${value.firstName} ${value.surname}`;
    }
}

this does not work

export @Pipe({ name: 'contactName', standalone: true })
class ContactNamePipe implements PipeTransform {
    transform(value: Contact) : string {
        return `${value.firstName} ${value.surname}`;
    }
}

Stryker config

{
  "$schema": "./node_modules/@stryker-mutator/core/schema/stryker-schema.json",
  "_comment": "This config was generated using 'stryker init'. Please see the guide for more information: https://stryker-mutator.io/docs/stryker-js/guides/angular",
  "mutate": [
    "src/**/*.ts",
    "!src/**/*.spec.ts",
    "!src/test.ts",
    "!src/environments/*.ts"
  ],
  "testRunner": "karma",
  "karma": {
    "configFile": "karma.conf.js",
    "projectType": "angular-cli",
    "config": {
      "browsers": [
        "ChromeHeadless"
      ]
    }
  },
  "reporters": [
    "progress",
    "clear-text",
    "html"
  ],
  "concurrency": 10,
  "concurrency_comment": "Recommended to use about half of your available cores when running stryker with angular",
  "coverageAnalysis": "perTest"
}

Test runner config

// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with random: false
// or set a specific seed with seed: 4321
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/date-picker'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
browsers: ['Chrome'],
restartOnFileChange: true
});
};

Stryker environment

@stryker-mutator/karma-runner@8.2.6
jasmine@5.1.0

Test runner environment

# stryker run

Your Environment

software version(s)
node v20.14.0
npm v10.2.5
Operating System windows 11 enterprise 10.0.22621

Add stryker.log

11:47:52 (2912) DEBUG ConfigReader Loading config from stryker.config.json
11:47:52 (2912) DEBUG ConfigReader Loaded config: {
  "$schema": "./node_modules/@stryker-mutator/core/schema/stryker-schema.json",
  "_comment": "This config was generated using 'stryker init'. Please see the guide for more information: https://stryker-mutator.io/docs/stryker-js/guides/angular",
  "mutate": [
    "src/**/*.ts",
    "!src/**/*.spec.ts",
    "!src/test.ts",
    "!src/environments/*.ts"
  ],
  "testRunner": "karma",
  "karma": {
    "configFile": "karma.conf.js",
    "projectType": "angular-cli",
    "config": {
      "browsers": [
        "ChromeHeadless"
      ]
    }
  },
  "reporters": [
    "progress",
    "clear-text",
    "html"
  ],
  "concurrency": 10,
  "concurrency_comment": "Recommended to use about half of your available cores when running stryker with angular",
  "coverageAnalysis": "perTest",
  "fileLogLevel": "trace",
  "allowConsoleColors": true,
  "checkers": [],
  "checkerNodeArgs": [],
  "commandRunner": {
    "command": "npm test"
  },
  "clearTextReporter": {
    "allowColor": true,
    "allowEmojis": false,
    "logTests": true,
    "maxTestsToLog": 3,
    "reportTests": true,
    "reportMutants": true,
    "reportScoreTable": true
  },
  "dashboard": {
    "baseUrl": "https://dashboard.stryker-mutator.io/api/reports",
    "reportType": "full"
  },
  "dryRunOnly": false,
  "eventReporter": {
    "baseDir": "reports/mutation/events"
  },
  "ignorePatterns": [],
  "ignoreStatic": false,
  "incremental": false,
  "incrementalFile": "reports/stryker-incremental.json",
  "force": false,
  "inPlace": false,
  "logLevel": "info",
  "maxConcurrentTestRunners": 9007199254740991,
  "maxTestRunnerReuse": 0,
  "mutator": {
    "plugins": null,
    "excludedMutations": []
  },
  "plugins": [
    "@stryker-mutator/*"
  ],
  "appendPlugins": [],
  "htmlReporter": {
    "fileName": "reports/mutation/mutation.html"
  },
  "jsonReporter": {
    "fileName": "reports/mutation/mutation.json"
  },
  "disableTypeChecks": true,
  "symlinkNodeModules": true,
  "tempDirName": ".stryker-tmp",
  "cleanTempDir": true,
  "testRunnerNodeArgs": [],
  "thresholds": {
    "high": 80,
    "low": 60,
    "break": null
  },
  "timeoutFactor": 1.5,
  "timeoutMS": 5000,
  "dryRunTimeoutMinutes": 5,
  "tsconfigFile": "tsconfig.json",
  "warnings": true,
  "disableBail": false,
  "allowEmpty": false,
  "ignorers": []
}
11:47:52 (2912) DEBUG PluginLoader Loading @stryker-mutator/* from C:\Users\..\date-picker\node_modules\@stryker-mutator
11:47:52 (2912) DEBUG PluginLoader Loading plugin "@stryker-mutator/karma-runner" (matched with expression @stryker-mutator/*)
11:47:52 (2912) DEBUG PluginLoader Loading plugin @stryker-mutator/karma-runner
11:47:52 (2912) DEBUG PluginLoader Loading plugin file:///C:/Users/../date-picker/node_modules/@stryker-mutator/core/dist/src/reporters/index.js
11:47:52 (2912) DEBUG MetaSchemaBuilder Contributing 1 schemas from plugins to options validation.
11:47:52 (2912) WARN ProjectReader Glob pattern "!src/test.ts" did not exclude any files.
11:47:52 (2912) INFO ProjectReader Found 9 of 318 file(s) to be mutated.
11:47:52 (2912) DEBUG ProjectReader All input files: [
  ...
]
11:47:52 (2912) DEBUG ProjectReader Files to mutate: [
  ...
]
11:47:52 (2912) DEBUG TemporaryDirectory Using temp directory "C:\Users\...\date-picker\.stryker-tmp"
11:47:52 (2912) DEBUG Instrumenter Instrumenting 9 source files with mutants
11:47:52 (2912) DEBUG Instrumenter Instrumented src\app\app.component.ts (8 mutant(s))
11:47:52 (2912) DEBUG Instrumenter Instrumented src\app\app.config.ts (4 mutant(s))
11:47:52 (2912) DEBUG Instrumenter Instrumented src\app\app.routes.ts (1 mutant(s))
11:47:52 (2912) DEBUG Instrumenter Instrumented src\app\contact-list\contact-list.component.ts (9 mutant(s))
11:47:52 (2912) DEBUG Stryker Not removing the temp dir because an error occurred
11:47:52 (2912) ERROR Stryker Unexpected error occurred while running Stryker SyntaxError: C:\Users\...\date-picker\src\app\contact-name\contact-name.pipe.ts: Unexpected token, expected "{" (4:7)
...
 {
  code: 'BABEL_PARSE_ERROR',
  reasonCode: 'UnexpectedToken',
  loc: Position { line: 4, column: 7, index: 109 },
  pos: 109
}
11:47:52 (2912) INFO Stryker This might be a known problem with a solution documented in our troubleshooting guide.
11:47:52 (2912) INFO Stryker You can find it at https://stryker-mutator.io/docs/stryker-js/troubleshooting/

@Rubenvdbrink Rubenvdbrink added the 🐛 Bug Something isn't working label Jun 12, 2024
@nicojs
Copy link
Member

nicojs commented Aug 1, 2024

Hi @Rubenvdbrink thanks for opening this issue.

We have reached a dilemma here. We're using Babel under the hood. Babel supports TypeScript using the @babel/preset-typescript. It enables TypeScript features like type annotations but not decorators. We enable decorators separately using the babel-plugin-proposal-decorators.

Decorators have evolved quite a lot over the years, as you can see from the "version" config option: "2023-11", "2023-05", "2023-01", "2022-03", "2021-12", "2018-09" or "legacy". TypeScript was traditionally fully compatible with the "legacy" version of Babel decorators. But since typescript 5.0, decorators are also allowed after the export keyword (as you've figured out). See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#differences-with-experimental-legacy-decorators. There is no way that I know of to get this behavior from Babel's decorator plugin. We can set the version to "2023-11" and that seems to solve it, but then constructor parameter decorators are not allowed (like constructor(@Inject(DOCUMENT) document) {}, since they are notably absent from the current decorator implementation, see the class method parameter decorators proposal

See also ts-parser.ts, where we configure the Babel plugins for TypeScript.

For now, the best we can do is add a remark in troubleshooting.md.

I'll try reaching out to the babel team for help.

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

2 participants