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

Add a json reporter #2582

Merged
merged 6 commits into from Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/api/schema/stryker-core.json
Expand Up @@ -133,6 +133,23 @@
}
}
},
"jsonReporterOptions": {
"title": "JsonReporterOptions",
"additionalProperties": false,
"type": "object",
"properties": {
"baseDir": {
"description": "The output folder for the json report.",
"type": "string",
"default": "reports/mutation"
},
"spacing": {
"description": "The number of spaces used for indenion.",
"type": "number",
"default": 0
}
}
},
"mutationScoreThresholds": {
"title": "MutationScoreThresholds",
"additionalProperties": false,
Expand Down Expand Up @@ -349,6 +366,10 @@
"description": "The options for the html reporter",
"$ref": "#/definitions/htmlReporterOptions"
},
"jsonReporter": {
"description": "The options for the json reporter",
"$ref": "#/definitions/jsonReporterOptions"
},
"disableTypeChecks": {
"description": "Configure a pattern that matches the files of which type checking has to be disabled. This is needed because Stryker will create (typescript) type errors when inserting the mutants in your code. Stryker disables type checking by inserting `// @ts-nocheck` atop those files and removing other `// @ts-xxx` directives (so they won't interfere with `@ts-nocheck`). The default setting allows these directives to be stripped from all JavaScript and friend files in `lib`, `src` and `test` directories. You can specify a different glob expression or set it to `false` to completely disable this behavior.",
"anyOf": [
Expand Down
8 changes: 5 additions & 3 deletions packages/core/README.md
Expand Up @@ -301,17 +301,19 @@ you can consult [npm](https://www.npmjs.com/search?q=stryker-plugin) or
### `reporters` [`string[]`]

Default: `['clear-text', 'progress', 'html']`
Command line: `--reporters clear-text,progress,dots,dashboard,html`
Config file: `reporters: ['clear-text', 'progress', 'dots', 'dashboard', 'html']`
Command line: `--reporters clear-text,progress,dots,dashboard,html,json`
Config file: `reporters: ['clear-text', 'progress', 'dots', 'dashboard', 'html', 'json']`

With `reporters`, you can set the reporters for stryker to use.
These reporters can be used out of the box: `html`, `progress`, `clear-text`, `dots`, `dashboard` and `event-recorder`.
These reporters can be used out of the box: `html`, `json`, `progress`, `clear-text`, `dots`, `dashboard` and `event-recorder`.
By default, `clear-text`, `progress`, `html` are active if no reporters are configured.
You can load additional plugins to get more reporters. See [stryker-mutator.io](https://stryker-mutator.io)
for an up-to-date list of supported reporter plugins and a description on each reporter.

The `html` reporter allows you to specify an output folder. This defaults to `reports/mutation/html`. The config for your config file is: `htmlReporter: { baseDir: 'mypath/reports/stryker' }`

The `json` reporter also allows specifying an output folder and additionally provides a parameter for the indention (called `spacing`) which is 0 spaces by default, meaning no indention at all. The config for your config file is: `jsonReporter: { baseDir: 'mypath/reports/stryker', spacing: 2 }`

The `clear-text` reporter supports three additional config options:
* `allowColor` to use cyan and yellow in printing source file names and positions. This defaults to `true`, so specify as `clearTextReporter: { allowColor: false },` to disable if you must.
* `logTests` to log the names of unit tests that were run to allow mutants. By default, only the first three are logged. The config for your config file is: `clearTextReporter: { logTests: true },`
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
@@ -1,4 +1,5 @@
import Stryker from './stryker';
import StrykerCli from './stryker-cli';

export { Stryker, StrykerCli };
export default Stryker;
2 changes: 2 additions & 0 deletions packages/core/src/reporters/index.ts
Expand Up @@ -7,6 +7,7 @@ import EventRecorderReporter from './event-recorder-reporter';
import ProgressAppendOnlyReporter from './progress-append-only-reporter';
import ProgressReporter from './progress-reporter';
import HtmlReporter from './html/html-reporter';
import JsonReporter from './json-reporter';

export const strykerPlugins = [
declareClassPlugin(PluginKind.Reporter, 'clear-text', ClearTextReporter),
Expand All @@ -15,5 +16,6 @@ export const strykerPlugins = [
declareClassPlugin(PluginKind.Reporter, 'dots', DotsReporter),
declareClassPlugin(PluginKind.Reporter, 'event-recorder', EventRecorderReporter),
declareClassPlugin(PluginKind.Reporter, 'html', HtmlReporter),
declareClassPlugin(PluginKind.Reporter, 'json', JsonReporter),
declareFactoryPlugin(PluginKind.Reporter, 'dashboard', dashboardReporterFactory),
];
62 changes: 62 additions & 0 deletions packages/core/src/reporters/json-reporter.ts
@@ -0,0 +1,62 @@
import * as path from 'path';

import { StrykerOptions } from '@stryker-mutator/api/core';
import { Logger } from '@stryker-mutator/api/logging';
import { commonTokens, tokens } from '@stryker-mutator/api/plugin';
import { mutationTestReportSchema, Reporter } from '@stryker-mutator/api/report';

import fileUrl = require('file-url');

import * as HtmlReporterUtil from './html/html-reporter-util';

const DEFAULT_BASE_FOLDER = path.normalize('reports/mutation');
const DEFAULT_INDENTION = 0;
export const RESOURCES_DIR_NAME = 'strykerResources';

export default class JsonReporter implements Reporter {
private _baseDir!: string;
Tummerhore marked this conversation as resolved.
Show resolved Hide resolved
private mainPromise: Promise<void> | undefined;

constructor(private readonly options: StrykerOptions, private readonly log: Logger) {}

public static readonly inject = tokens(commonTokens.options, commonTokens.logger);

public onMutationTestReportReady(report: mutationTestReportSchema.MutationTestResult) {
this.mainPromise = this.generateReport(report);
}

public wrapUp() {
return this.mainPromise;
}

private async generateReport(report: mutationTestReportSchema.MutationTestResult) {
const jsonReportFile = path.resolve(this.baseDir, 'mutation.json');
await this.cleanBaseFolder();
let indent = DEFAULT_INDENTION;
if (this.options.jsonReporter && this.options.jsonReporter.spacing) {
indent = this.options.jsonReporter.spacing;
Tummerhore marked this conversation as resolved.
Show resolved Hide resolved
}
await HtmlReporterUtil.writeFile(jsonReportFile, JSON.stringify(report, null, indent));
this.log.info(`Your report can be found at: ${fileUrl(jsonReportFile)}`);
}

private get baseDir(): string {
if (!this._baseDir) {
if (this.options.jsonReporter && this.options.jsonReporter.baseDir) {
this._baseDir = this.options.jsonReporter.baseDir;
this.log.debug(`Using configured output folder ${this._baseDir}`);
} else {
this.log.debug(
`No base folder configuration found (using configuration: jsonReporter: { baseDir: 'output/folder' }), using default ${DEFAULT_BASE_FOLDER}`
);
this._baseDir = DEFAULT_BASE_FOLDER;
}
}
return this._baseDir;
}

private async cleanBaseFolder(): Promise<void> {
await HtmlReporterUtil.deleteDir(this.baseDir);
Tummerhore marked this conversation as resolved.
Show resolved Hide resolved
await HtmlReporterUtil.mkdir(this.baseDir);
}
}