Skip to content

Commit

Permalink
feat(progress-reporter): show timed out mutant count (#1818)
Browse files Browse the repository at this point in the history
Show the amount of mutants that resulted in a time-out in the progress reporter to help identify time outs early on.
  • Loading branch information
Chris Brody authored and simondel committed Nov 6, 2019
1 parent 87012b6 commit 067df6d
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 8 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/reporters/ProgressAppendOnlyReporter.ts
Expand Up @@ -19,7 +19,7 @@ export default class ProgressAppendOnlyReporter extends ProgressKeeper {
private render() {
process.stdout.write(
`Mutation testing ${this.getPercentDone()} (ETC ${this.getEtc()}) ` +
`${this.progress.tested}/${this.progress.total} tested (${this.progress.survived} survived)` +
`${this.progress.tested}/${this.progress.total} tested (${this.progress.survived} survived, ${this.progress.timedOut} timed out)` +
os.EOL
);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/reporters/ProgressKeeper.ts
Expand Up @@ -6,6 +6,7 @@ abstract class ProgressKeeper implements Reporter {
private timer: Timer;
protected progress = {
survived: 0,
timedOut: 0,
tested: 0,
total: 0
};
Expand All @@ -25,6 +26,9 @@ abstract class ProgressKeeper implements Reporter {
if (result.status === MutantStatus.Survived) {
this.progress.survived++;
}
if (result.status === MutantStatus.TimedOut) {
this.progress.timedOut++;
}
}

protected getEtc() {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/reporters/ProgressReporter.ts
Expand Up @@ -7,7 +7,7 @@ export default class ProgressBarReporter extends ProgressKeeper {

public onAllMutantsMatchedWithTests(matchedMutants: readonly MatchedMutant[]): void {
super.onAllMutantsMatchedWithTests(matchedMutants);
const progressBarContent = 'Mutation testing [:bar] :percent (ETC :etc) :tested/:total tested (:survived survived)';
const progressBarContent = 'Mutation testing [:bar] :percent (ETC :etc) :tested/:total tested (:survived survived, :timedOut timed out)';

this.progressBar = new ProgressBar(progressBarContent, {
complete: '=',
Expand Down
Expand Up @@ -8,6 +8,7 @@ import ProgressAppendOnlyReporter from '../../../src/reporters/ProgressAppendOnl
const SECOND = 1000;
const TEN_SECONDS = SECOND * 10;
const HUNDRED_SECONDS = SECOND * 100;
const THOUSAND_SECONDS = SECOND * 1000;
const TEN_THOUSAND_SECONDS = SECOND * 10000;

describe('ProgressAppendOnlyReporter', () => {
Expand All @@ -30,28 +31,35 @@ describe('ProgressAppendOnlyReporter', () => {

it('should log zero progress after ten seconds without completed tests', () => {
sinon.clock.tick(TEN_SECONDS);
expect(process.stdout.write).to.have.been.calledWith('Mutation testing 0% (ETC n/a) ' + `0/2 tested (0 survived)${os.EOL}`);
expect(process.stdout.write).to.have.been.calledWith('Mutation testing 0% (ETC n/a) ' + `0/2 tested (0 survived, 0 timed out)${os.EOL}`);
});

it('should log 50% with 10s ETC after ten seconds with 1 completed test', () => {
sut.onMutantTested(mutantResult({ status: MutantStatus.Killed }));
expect(process.stdout.write).to.not.have.been.called;
sinon.clock.tick(TEN_SECONDS);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 10s) 1/2 tested (0 survived)${os.EOL}`);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 10s) 1/2 tested (0 survived, 0 timed out)${os.EOL}`);
});

it('should log 50% with "1m, 40s" ETC after hundred seconds with 1 completed test', () => {
sut.onMutantTested(mutantResult({ status: MutantStatus.Killed }));
expect(process.stdout.write).to.not.have.been.called;
sinon.clock.tick(HUNDRED_SECONDS);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 1m, 40s) 1/2 tested (0 survived)${os.EOL}`);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 1m, 40s) 1/2 tested (0 survived, 0 timed out)${os.EOL}`);
});

it('should log 50% with "2h, 46m, 40s" ETC after ten tousand seconds with 1 completed test', () => {
it('should log 50% with "10m, 40s" ETC after thousand seconds with 1 completed test', () => {
sut.onMutantTested(mutantResult({ status: MutantStatus.Killed }));
expect(process.stdout.write).to.not.have.been.called;
sinon.clock.tick(THOUSAND_SECONDS);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 10m, 40s) 1/2 tested (0 survived, 0 timed out)${os.EOL}`);
});

it('should log 50% with "2h, 46m, 40s" ETC after ten thousand seconds with 1 completed test', () => {
sut.onMutantTested(mutantResult({ status: MutantStatus.TimedOut }));
expect(process.stdout.write).to.not.have.been.called;
sinon.clock.tick(TEN_THOUSAND_SECONDS);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 2h, 46m, 40s) 1/2 tested (0 survived)${os.EOL}`);
expect(process.stdout.write).to.have.been.calledWith(`Mutation testing 50% (ETC 2h, 46m, 40s) 1/2 tested (0 survived, 1 timed out)${os.EOL}`);
});
});
});
2 changes: 1 addition & 1 deletion packages/core/test/unit/reporters/ProgressReporter.spec.ts
Expand Up @@ -17,7 +17,7 @@ describe('ProgressReporter', () => {
let sut: ProgressReporter;
let matchedMutants: MatchedMutant[];
let progressBar: Mock<ProgressBar>;
const progressBarContent = 'Mutation testing [:bar] :percent (ETC :etc) :tested/:total tested (:survived survived)';
const progressBarContent = 'Mutation testing [:bar] :percent (ETC :etc) :tested/:total tested (:survived survived, :timedOut timed out)';

beforeEach(() => {
sinon.useFakeTimers();
Expand Down

0 comments on commit 067df6d

Please sign in to comment.