Skip to content

Commit

Permalink
feat(api): add id to Mutant interface (#2255)
Browse files Browse the repository at this point in the history
Add `id` property to `Mutant` api
  • Loading branch information
nicojs committed Jun 11, 2020
1 parent d330af9 commit cfc9053
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/api/src/core/Mutant.ts
@@ -1,6 +1,7 @@
import { Range } from '../../core';

interface Mutant {
id: number;
mutatorName: string;
fileName: string;
range: Range;
Expand Down
26 changes: 13 additions & 13 deletions packages/core/test/unit/mutants/MutantTestMatcher.spec.ts
Expand Up @@ -3,7 +3,7 @@ import { MatchedMutant } from '@stryker-mutator/api/report';
import { TestSelection } from '@stryker-mutator/api/test_framework';
import { CoverageCollection, CoveragePerTestResult, RunStatus, TestResult, TestStatus } from '@stryker-mutator/api/test_runner';
import { testInjector } from '@stryker-mutator/test-helpers';
import { mutant, testResult } from '@stryker-mutator/test-helpers/src/factory';
import { factory } from '@stryker-mutator/test-helpers';
import { expect } from 'chai';
import * as sinon from 'sinon';

Expand Down Expand Up @@ -57,21 +57,21 @@ describe(MutantTestMatcher.name, () => {
let testResultTwo: TestResult;

beforeEach(() => {
mutantOne = {
mutantOne = factory.mutant({
fileName: 'fileWithMutantOne',
mutatorName: 'myMutator',
range: [9, 9], // line 4:5 -> line 4:5
replacement: '>',
// location: { start: { line: 4, column: 5 }, end: { line: 4, column: 5 } },
};
});

mutantTwo = {
mutantTwo = factory.mutant({
fileName: 'fileWithMutantTwo',
mutatorName: 'myMutator',
range: [9, 9], // line 9:0 -> line 9:0
replacement: '<',
// location: { start: { line: 9, column: 0 }, end: { line: 9, column: 0 } },
};
});

testResultOne = {
name: 'test one',
Expand Down Expand Up @@ -332,7 +332,7 @@ describe(MutantTestMatcher.name, () => {
sourceFile.getLocation = () => ({ start: { line: 13, column: 38 }, end: { line: 24, column: 5 } });
const testableMutant = new TestableMutant(
'1',
mutant({
factory.mutant({
fileName: 'juice-shop\\app\\js\\controllers\\SearchResultController.js',
}),
sourceFile
Expand Down Expand Up @@ -455,8 +455,8 @@ describe(MutantTestMatcher.name, () => {
});

it('should match all mutants to all tests and log a warning when there is no coverage data', async () => {
mutants.push(mutant({ fileName: 'fileWithMutantOne' }), mutant({ fileName: 'fileWithMutantTwo' }));
initialRunResult.runResult.tests.push(testResult(), testResult());
mutants.push(factory.mutant({ fileName: 'fileWithMutantOne' }), factory.mutant({ fileName: 'fileWithMutantTwo' }));
initialRunResult.runResult.tests.push(factory.testResult(), factory.testResult());

const result = await sut.matchWithMutants(mutants);

Expand Down Expand Up @@ -485,7 +485,7 @@ describe(MutantTestMatcher.name, () => {

it('should retrieves source mapped location', async () => {
// Arrange
mutants.push(mutant({ fileName: 'fileWithMutantOne', range: [4, 5] }));
mutants.push(factory.mutant({ fileName: 'fileWithMutantOne', range: [4, 5] }));

// Act
await sut.matchWithMutants(mutants);
Expand All @@ -503,8 +503,8 @@ describe(MutantTestMatcher.name, () => {

it('should match mutant to single test result', async () => {
// Arrange
mutants.push(mutant({ fileName: 'fileWithMutantOne', range: [4, 5] }));
initialRunResult.runResult.tests.push(testResult({ name: 'test 1' }), testResult({ name: 'test 2' }));
mutants.push(factory.mutant({ fileName: 'fileWithMutantOne', range: [4, 5] }));
initialRunResult.runResult.tests.push(factory.testResult({ name: 'test 1' }), factory.testResult({ name: 'test 2' }));

// Act
const result = await sut.matchWithMutants(mutants);
Expand Down Expand Up @@ -533,8 +533,8 @@ describe(MutantTestMatcher.name, () => {
});

it('should match all mutants to all tests', async () => {
mutants.push(mutant({ fileName: 'fileWithMutantOne' }), mutant({ fileName: 'fileWithMutantTwo' }));
initialRunResult.runResult.tests.push(testResult(), testResult());
mutants.push(factory.mutant({ fileName: 'fileWithMutantOne' }), factory.mutant({ fileName: 'fileWithMutantTwo' }));
initialRunResult.runResult.tests.push(factory.testResult(), factory.testResult());

const result = await sut.matchWithMutants(mutants);

Expand Down
1 change: 1 addition & 0 deletions packages/javascript-mutator/src/JavaScriptMutator.ts
Expand Up @@ -28,6 +28,7 @@ export class JavaScriptMutator implements Mutator {
const replacement = types.isNode(mutation) ? this.parser.generateCode(mutation) : mutation.raw;

mutants.push({
id: 42, // TODO this code will be removed in #1514. Temp fill it with a string.
fileName: fileName,
mutatorName: mutatorName,
range: [original.start, original.end],
Expand Down
Expand Up @@ -30,6 +30,7 @@ describe('JavaScriptMutator', () => {

expect(mutants.length).to.equal(1);
expect(mutants[0]).to.deep.equal({
id: 42,
fileName: files[0].name,
mutatorName: 'ArithmeticOperator',
range: [22, 27],
Expand Down Expand Up @@ -65,6 +66,7 @@ describe('JavaScriptMutator', () => {

expect(mutants.length).to.equal(6);
expect(mutants).to.deep.include({
id: 42,
fileName: 'testFile.jsx',
mutatorName: 'ConditionalExpression',
range: [197, 202],
Expand Down Expand Up @@ -128,6 +130,7 @@ describe('JavaScriptMutator', () => {

expect(mutants.length).to.equal(6);
expect(mutants).to.deep.include({
id: 42,
fileName: 'testFile.js',
mutatorName: 'ConditionalExpression',
range: [121, 128],
Expand Down
11 changes: 11 additions & 0 deletions packages/test-helpers/src/factory.ts
Expand Up @@ -105,6 +105,7 @@ export const mutationTestReportSchemaMutationTestResult = factoryMethod<mutation
}));

export const mutant = factoryMethod<Mutant>(() => ({
id: 42,
fileName: 'file',
mutatorName: 'foobarMutator',
range: [0, 0],
Expand Down Expand Up @@ -172,6 +173,16 @@ export const testResult = factoryMethod<TestResult>(() => ({
timeSpentMs: 10,
}));

export const testSelection = factoryMethod<TestSelection>(() => ({
id: 23,
name: 'foo should bar',
}));

export const mutantRunOptions = factoryMethod<{ activeMutant: Mutant; timeout: number }>(() => ({
activeMutant: mutant(),
timeout: 2000,
}));

export const runResult = factoryMethod<RunResult>(() => ({
status: RunStatus.Complete,
tests: [testResult()],
Expand Down
1 change: 1 addition & 0 deletions packages/typescript/src/mutator/NodeMutator.ts
Expand Up @@ -20,6 +20,7 @@ export default abstract class NodeMutator<T extends ts.Node = ts.Node> {

private createMutant(original: ts.Node, replacement: string, sourceFile: ts.SourceFile): Mutant {
return {
id: 42, // TODO this code will be removed in #1514. Temp fill it with a string.
fileName: sourceFile.fileName.replace(/\//g, path.sep),
mutatorName: this.name,
range: [original.getStart(sourceFile), original.getEnd()],
Expand Down
5 changes: 5 additions & 0 deletions packages/typescript/test/unit/TypescriptMutator.spec.ts
Expand Up @@ -99,18 +99,21 @@ describe('TypescriptMutator', () => {
// Assert
expect(mutants).to.deep.equal([
{
id: 42,
fileName: 'file1.ts',
mutatorName: 'SourceFileForTest',
range: [0, 39],
replacement: '"stryker was here"',
},
{
id: 42,
fileName: 'file1.ts',
mutatorName: 'FunctionDeclarationForTest',
range: [0, 39],
replacement: '// Function declaration removed',
},
{
id: 42,
fileName: 'file1.ts',
mutatorName: 'FunctionDeclarationForTest',
range: [0, 39],
Expand All @@ -129,6 +132,7 @@ describe('TypescriptMutator', () => {
// Assert
expect(mutants).to.deep.equal([
{
id: 42,
fileName: 'file1.ts',
mutatorName: 'SourceFileForTest',
range: [0, 50],
Expand All @@ -153,6 +157,7 @@ describe('TypescriptMutator', () => {
// Assert
expect(mutants).to.deep.equal([
{
id: 42,
fileName: 'file1.ts',
mutatorName: 'SourceFileForTest',
range: [0, 85],
Expand Down
6 changes: 3 additions & 3 deletions packages/vue-mutator/test/unit/VueMutator.spec.ts
@@ -1,6 +1,6 @@
import { Mutant, File } from '@stryker-mutator/api/core';
import { Mutator } from '@stryker-mutator/api/mutant';
import { testInjector } from '@stryker-mutator/test-helpers';
import { testInjector, factory } from '@stryker-mutator/test-helpers';
import { expect } from 'chai';
import { SinonStubbedInstance } from 'sinon';
import * as sinon from 'sinon';
Expand Down Expand Up @@ -347,12 +347,12 @@ describe('VueMutator', () => {
<script>${script}</script>`
);
const files = [vueFile];
const jsMutant: Mutant = {
const jsMutant: Mutant = factory.mutant({
fileName: `${vueFile.name}.js`,
mutatorName: 'StringLiteral',
range: [script.indexOf(codeToMutate), script.indexOf(codeToMutate) + codeToMutate.length],
replacement: '',
};
});
stubJavaScriptMutator.mutate.returns([jsMutant]);
const sut = createSut();

Expand Down

0 comments on commit cfc9053

Please sign in to comment.