Stryker

BaselineReporter.ts - Stryker report

File / Directory
Mutation score
# Killed
# Survived
# Timeout
# No coverage
# Runtime errors
# Transpile errors
Total detected
Total undetected
Total mutants
BaselineReporter.ts
100.00 %
100.00 39 0 0 0 0 7 39 0 46
Expand all
import { MutantResult, Reporter, MutantStatus } from 'stryker-api/report';

import * as fs from 'mz/fs';
import * as chalk from 'chalk';
import { StrykerOptions } from 'stryker-api/core';
import * as _ from 'lodash';
const tempy = require('tempy');
import * as path from 'path';

export default class implements Reporter {
    surviving: MutantResult[];
    public filename = path.join(tempy.directory(), 'stryker.baseline.js');

    constructor(_?: StrykerOptions,
        private baseline: MutantResult[] | undefined = read(),
        private write: (data: string) => void = console.log) {
    }

    public onAllMutantsTested(results: MutantResult[]): void 0{
        this.surviving = results.filter(_ => _.status 1=== MutantStatus.Survived 2|| _.status 3=== MutantStatus.NoCoverage);

        if (4567!this.baseline) 8{
            this.ReportWithNoBaselineFile(this.surviving);
        } else 9{
            this.ReportDifferenceWithBaseline(this.surviving, this.baseline);
        }
    }

    public async wrapUp(): Promise<void> 10{
        this.write(`Saved a new baseline file: ${this.filename}`);
        await fs.writeFile(this.filename, JSON.stringify(this.surviving));
    }

    public compare(lhs: MutantResult, rhs: MutantResult) 11{
        return lhs.mutatedLines 12=== rhs.mutatedLines
            13&& lhs.originalLines 14=== rhs.originalLines
            15&& lhs.mutatorName 16=== rhs.mutatorName
            17&& lhs.sourceFilePath 18=== rhs.sourceFilePath;
    }

    private ReportWithNoBaselineFile(surviving: MutantResult[]) 19{
        if (2021surviving.length 2223> 0) 24{
            this.write(chalk.yellow(chalk.bold('No hard feelings.'), 'Mutants survived but it may be not your fault after all.'));
            this.write('Copy the baseline file mentioned at the end of this log to the root dir of your project.');
            this.write('Mind though that including a baseline file at this point will let them live on forever...');
        } else 25{
            this.write(chalk.yellow(chalk.green('You rock!'), 'No surviving mutants at all.'));
            this.write('Who needs a baseline file anyway?!');
        }
    }

    private ReportDifferenceWithBaseline(surviving: MutantResult[], baseline: MutantResult[]) 26{
        let fresh = _.differenceWith(surviving, this.baseline, (lhs: MutantResult, rhs: MutantResult) => this.compare(lhs, rhs));

        if (2728fresh.length 29=== 0) 30{
            this.ReportNoNewSurvivingMutants(surviving, baseline);
        } else 31{
            this.ReportNewSurvivingMutants(surviving, baseline);
        }
    }

    private ReportNoNewSurvivingMutants(surviving: MutantResult[], baseline: MutantResult[]) 32{
        if (3334surviving.length 35=== baseline.length) 36{
            this.write(chalk.green(chalk.bold('Good job!'), 'At least you didn\'t create new surviving mutants.'));
        } else 37{
            this.write(chalk.green(chalk.bold('Great job!'), 'You killed some mutants that survived before.'));
            this.write('You should update the baseline file right now!');
            this.write('Overwrite your baseline file with the one mentioned at the end of this log.');
        }
    }

    private ReportNewSurvivingMutants(surviving: MutantResult[], baseline: MutantResult[]) 38{
        let gone = _.differenceWith(baseline, surviving, (lhs: MutantResult, rhs: MutantResult) => this.compare(lhs, rhs));
        if (3940gone.length 41=== 0) 42{
            this.write(chalk.red(chalk.bold('Shame on you!'), 'New mutants survived. Let\'s go kill them!'));
            this.write('If you can\'t kill them you should update the baseline file.');
        } else 43{
            this.write(chalk.yellow(chalk.bold('Mixed feelings.'), 'You killed some mutants but also created some new surviving.'));
            this.write('Mind that updating the baseline file now will let them live on forever...');
        }

        this.write('Overwrite your baseline file with the one mentioned at the end of this log.');
    }
}

export function read(filename = 'stryker.baseline.js'): MutantResult[] | undefined 44{
    return 45fs.existsSync(filename) ? JSON.parse(fs.readFileSync(filename, 'utf-8')) : undefined;
}
# Mutator State Location Original Replacement
0 BinaryExpression TranspileError 19 : 80 || &&
1 BinaryExpression TranspileError 19 : 54 === !==
2 IfStatement TranspileError 21 : 12 ! .
3 IfStatement TranspileError 21 : 12 ! .
4 UnaryNot TranspileError 21 : 12 ! . .
5 PrefixUnaryExpression TranspileError 21 : 12 ! . .
6 Block Killed 18 : 61 { ... } {}
7 BinaryExpression Killed 36 : 12 && ||
8 BinaryExpression Killed 35 : 12 && ||
9 BinaryExpression Killed 34 : 32 === !==
10 BinaryExpression Killed 19 : 92 === !==
11 Block Killed 23 : 15 { ... } {}
12 BinaryExpression Killed 35 : 33 === !==
13 BinaryExpression Killed 37 : 34 === !==
14 BinaryExpression Killed 36 : 31 === !==
15 Block Killed 21 : 28 { ... } {}
16 BinaryExpression Killed 37 : 12 && ||
17 IfStatement Killed 41 : 12 . >
18 Block Killed 33 : 57 { ... } {}
19 Block Killed 40 : 64 { ... } {}
20 BinaryExpression Killed 41 : 29 > <=
21 Block Killed 51 : 94 { ... } {}
22 Block Killed 41 : 34 { ... } {}
23 IfStatement Killed 41 : 12 . >
24 BinaryExpression Killed 41 : 29 > >=
25 IfStatement Killed 54 : 12 . ===
26 Block Killed 28 : 41 { ... } {}
27 IfStatement Killed 54 : 12 . ===
28 Block Killed 45 : 15 { ... } {}
29 BinaryExpression Killed 54 : 25 === !==
30 Block Killed 54 : 32 { ... } {}
31 Block Killed 56 : 15 { ... } {}
32 Block Killed 61 : 93 { ... } {}
33 IfStatement Killed 62 : 12 . ... .
34 IfStatement Killed 62 : 12 . ... .
35 BinaryExpression Killed 62 : 29 === !==
36 Block Killed 62 : 50 { ... } {}
37 Block Killed 64 : 15 { ... } {}
38 Block Killed 71 : 91 { ... } {}
39 IfStatement Killed 73 : 12 . ===
40 IfStatement Killed 73 : 12 . ===
41 BinaryExpression Killed 73 : 24 === !==
42 Block Killed 73 : 31 { ... } {}
43 Block Killed 76 : 15 { ... } {}
44 Block TranspileError 85 : 83 { ... ; } {}
45 ConditionalExpression Killed 86 : 11 . ... )