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

feat(core): simple mutation switching process #2269

Merged
merged 23 commits into from
Jul 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
33b42a6
feat(mutant-api): add source location to the mutant api
nicojs Jun 19, 2020
b02d6a9
chore: set correct .npmignore
nicojs Jun 19, 2020
d39c874
feat(core): simple mutation switching process
nicojs Jun 23, 2020
6be2d7e
test(e2e): enable 3 e2e tests in the build
nicojs Jun 23, 2020
20a9258
test(perf): install instrumenter
nicojs Jun 23, 2020
27e43db
Merge branch 'epic/mutation-switching' into feat/simple-mutation-swit…
nicojs Jun 23, 2020
284eb9f
Ignore tests in javascript-mutator and typescript packages (will be r…
nicojs Jun 23, 2020
d48c74f
Add unit tests for prepare executor
nicojs Jun 23, 2020
1a6e447
Fix linting issues
nicojs Jun 23, 2020
0132668
Add unit tests for mutant instrumenter executor
nicojs Jun 23, 2020
0e33cda
refactor(TestRunnerApi): rename RunResult -> DryRunResult
nicojs Jun 24, 2020
3e5ed06
Add unit tests for dry run executor
nicojs Jun 24, 2020
52953b9
Add unit tests for mutation test executor
nicojs Jun 25, 2020
124129d
Add unit tests for sandbox
nicojs Jun 25, 2020
1bcad75
Add unit tests for TestRunnerPool
nicojs Jun 25, 2020
1966600
Fix test runner pool tests on machines with 2 cpus
nicojs Jun 26, 2020
51b1d61
Update integration tests for createTestRunnerFactory
nicojs Jun 26, 2020
f489d23
Migrate test runner decorator unit tests
nicojs Jun 26, 2020
e142ad3
Implement onAllMutantsMatched
nicojs Jun 26, 2020
6854371
Fix off-by-one error 🤦‍♂️
nicojs Jun 26, 2020
814ccbd
Remove dead code:
nicojs Jun 26, 2020
d78a288
Fix failing test in instrumenter
nicojs Jun 26, 2020
b2471a6
Remove unused catch clause
nicojs Jun 27, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ jobs:
- name: Build & lint & test
run: npm run all

# e2e:
# runs-on: ${{ matrix.os }}
# strategy:
# fail-fast: false
# matrix:
# os: ['ubuntu-latest', 'windows-latest']
e2e:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest']

# steps:
# - uses: actions/checkout@v1
# - name: Install dependencies
# run: npm install
# - name: Build packages
# run: npm run build
# - name: Run e2e tests
# run: npm run e2e
steps:
- uses: actions/checkout@v1
- name: Install dependencies
run: npm install
- name: Build packages
run: npm run build
- name: Run e2e tests
run: npm run e2e

1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"localDependencies": {
"grunt-stryker": "../packages/grunt-stryker",
"@stryker-mutator/core": "../packages/core",
"@stryker-mutator/instrumenter": "../packages/instrumenter",
"@stryker-mutator/api": "../packages/api",
"@stryker-mutator/babel-transpiler": "../packages/babel-transpiler",
"@stryker-mutator/jasmine-framework": "../packages/jasmine-framework",
Expand Down
7 changes: 7 additions & 0 deletions e2e/tasks/run-e2e-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import { tap, mergeAll, map, filter } from 'rxjs/operators';

const testRootDir = path.resolve(__dirname, '..', 'test');

const mutationSwitchingTempWhiteList = [
'jasmine-jasmine',
'karma-mocha',
'karma-jasmine',
]

function runE2eTests() {
const testDirs = fs.readdirSync(testRootDir);

// Create test$, an observable of test runs
const test$ = from(testDirs).pipe(
filter(dir => fs.statSync(path.join(testRootDir, dir)).isDirectory()),
filter(dir => mutationSwitchingTempWhiteList.includes(dir)),
map(testDir => defer(() => runTest(testDir)))
);

Expand Down
1 change: 1 addition & 0 deletions e2e/test/angular-project/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/karma-runner": "../../../packages/karma-runner",
"@stryker-mutator/typescript": "../../../packages/typescript",
"@stryker-mutator/util": "../../../packages/util"
Expand Down
5 changes: 3 additions & 2 deletions e2e/test/jasmine-jasmine/stryker.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ module.exports = function (config) {
testFramework: 'jasmine',
testRunner: 'jasmine',
reporters: ['clear-text', 'event-recorder'],
maxConcurrentTestRunners: 1,
maxConcurrentTestRunners: 2,
jasmineConfigFile: 'spec/support/jasmine.json',
fileLogLevel: 'debug'
fileLogLevel: 'debug',
plugins: ['@stryker-mutator/jasmine-runner']
});
};
28 changes: 13 additions & 15 deletions e2e/test/jasmine-jasmine/verify/verify.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
import { promises as fs } from 'fs';

import { expect } from 'chai';
import { expectMetricsResult, produceMetrics } from '../../../helpers';
import { expectMetrics } from '../../../helpers';

describe('After running stryker with test runner jasmine, test framework jasmine', () => {
it('should report 85% mutation score', async () => {
await expectMetricsResult({
metrics: produceMetrics({
killed: 12,
mutationScore: 85.71,
mutationScoreBasedOnCoveredCode: 92.31,
noCoverage: 1,
survived: 1,
totalCovered: 13,
totalDetected: 12,
totalMutants: 14,
totalUndetected: 2,
totalValid: 14
})
await expectMetrics({
killed: 12,
mutationScore: 85.71,
mutationScoreBasedOnCoveredCode: 100,
noCoverage: 2,
survived: 0,
totalCovered: 12,
totalDetected: 12,
totalMutants: 14,
totalUndetected: 2,
totalValid: 14
});
});

it('should write to a log file', async () => {
const strykerLog = await fs.readFile('./stryker.log', 'utf8');
expect(strykerLog).matches(/INFO InputFileResolver Found 2 of 9 file\(s\) to be mutated/);
expect(strykerLog).matches(/Stryker Done in \d+/);
expect(strykerLog).matches(/Done in \d+ second/);
// TODO, we now have an error because of a memory leak: https://github.com/jasmine/jasmine-npm/issues/134
// expect(strykerLog).not.contains('ERROR');
});
Expand Down
1 change: 1 addition & 0 deletions e2e/test/jest-react-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/typescript": "../../../packages/typescript",
"@stryker-mutator/jest-runner": "../../../packages/jest-runner",
"@stryker-mutator/util": "../../../packages/util"
Expand Down
1 change: 1 addition & 0 deletions e2e/test/jest-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/javascript-mutator": "../../../packages/javascript-mutator",
"@stryker-mutator/jest-runner": "../../../packages/jest-runner",
"@stryker-mutator/util": "../../../packages/util"
Expand Down
3 changes: 2 additions & 1 deletion e2e/test/karma-mocha/stryker.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = function (config) {
},
timeoutMS: 60000,
maxConcurrentTestRunners: 2,
coverageAnalysis: 'perTest'
coverageAnalysis: 'perTest',
plugins: ['@stryker-mutator/karma-runner']
});
};
8 changes: 4 additions & 4 deletions e2e/test/karma-mocha/verify/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ describe('Verify stryker has ran correctly', () => {
metrics: produceMetrics({
killed: 16,
mutationScore: 64,
mutationScoreBasedOnCoveredCode: 84.21,
noCoverage: 6,
survived: 3,
totalCovered: 19,
mutationScoreBasedOnCoveredCode: 94.12,
noCoverage: 8,
survived: 1,
totalCovered: 17,
totalDetected: 16,
totalMutants: 25,
totalUndetected: 9,
Expand Down
3 changes: 2 additions & 1 deletion e2e/test/karma-webpack-with-ts/stryker.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
"configFile": "karma.conf.js",
"projectType": "custom"
},
"tsconfigFile": "tsconfig.json"
"tsconfigFile": "tsconfig.json",
"logLevel": "trace"
}
1 change: 1 addition & 0 deletions e2e/test/polymer-project/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/wct-runner": "../../../packages/wct-runner",
"@stryker-mutator/javascript-mutator": "../../../packages/javascript-mutator",
"@stryker-mutator/util": "../../../packages/util"
Expand Down
1 change: 1 addition & 0 deletions e2e/test/vue-cli-javascript-jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/jest-runner": "../../../packages/jest-runner",
"@stryker-mutator/vue-mutator": "../../../packages/vue-mutator",
"@stryker-mutator/javascript-mutator": "../../../packages/javascript-mutator",
Expand Down
1 change: 1 addition & 0 deletions e2e/test/vue-cli-typescript-mocha/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/mocha-runner": "../../../packages/mocha-runner",
"@stryker-mutator/webpack-transpiler": "../../../packages/webpack-transpiler",
"@stryker-mutator/vue-mutator": "../../../packages/vue-mutator",
Expand Down
1 change: 1 addition & 0 deletions e2e/test/vue-javascript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"localDependencies": {
"@stryker-mutator/api": "../../../packages/api",
"@stryker-mutator/core": "../../../packages/core",
"@stryker-mutator/instrumenter": "../../../packages/instrumenter",
"@stryker-mutator/javascript-mutator": "../../../packages/javascript-mutator",
"@stryker-mutator/karma-runner": "../../../packages/karma-runner",
"@stryker-mutator/vue-mutator": "../../../packages/vue-mutator",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"prebuild": "npm run generate",
"build": "tsc -b && lerna run build",
"test": "npm run mocha",
"mocha": "lerna run test --stream --concurrency 4",
"mocha": "lerna run test --stream --concurrency 4 --ignore @stryker-mutator/javascript-mutator --ignore @stryker-mutator/typescript",
"e2e": "cd e2e && npm ci && npm t && cd ..",
"perf": "cd perf && npm ci && npm t && cd ..",
"start": "tsc -b -w",
Expand Down
4 changes: 3 additions & 1 deletion packages/api/src/core/Mutant.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Range } from '../../core';
import Range from './Range';
import Location from './Location';

interface Mutant {
id: number;
mutatorName: string;
fileName: string;
range: Range;
location: Location;
replacement: string;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/report/MatchedMutant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface MatchedMutant {
/**
* If not all tests will run for this mutant, this array will contain the ids of the tests that will run.
*/
readonly scopedTestIds: number[];
readonly testFilter: string[] | undefined;
/**
* The time spent on the tests that will run in initial test run
*/
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/test_runner2/DryRunResult.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MutantCoverage } from './MutantCoverage';
import { RunStatus } from './RunStatus';
import { DryRunStatus } from './DryRunStatus';
import { TestResult } from './TestResult';

export type DryRunResult = CompleteDryRunResult | TimeoutDryRunResult | ErrorDryRunResult;
Expand All @@ -15,20 +15,20 @@ export interface CompleteDryRunResult {
/**
* The status of the run
*/
status: RunStatus.Complete;
status: DryRunStatus.Complete;
}
export interface TimeoutDryRunResult {
/**
* The status of the run
*/
status: RunStatus.Timeout;
status: DryRunStatus.Timeout;
}

export interface ErrorDryRunResult {
/**
* The status of the run
*/
status: RunStatus.Error;
status: DryRunStatus.Error;

/**
* If `state` is `error`, this collection should contain the error messages
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export enum RunStatus {
export enum DryRunStatus {
/**
* Indicates that a test run is completed with failed or succeeded tests
*/
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/test_runner2/runResultHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { TestStatus } from './TestStatus';
import { DryRunResult } from './DryRunResult';
import { MutantRunResult } from './MutantRunResult';
import { RunStatus } from './RunStatus';
import { DryRunStatus } from './DryRunStatus';
import { MutantRunStatus } from './MutantRunResult';
import { FailedTestResult } from './TestResult';

export function toMutantRunResult(dryRunResult: DryRunResult): MutantRunResult {
switch (dryRunResult.status) {
case RunStatus.Complete: {
case DryRunStatus.Complete: {
const killedBy = dryRunResult.tests.find<FailedTestResult>((test): test is FailedTestResult => test.status === TestStatus.Failed);
if (killedBy) {
return {
Expand All @@ -21,12 +21,12 @@ export function toMutantRunResult(dryRunResult: DryRunResult): MutantRunResult {
};
}
}
case RunStatus.Error:
case DryRunStatus.Error:
return {
status: MutantRunStatus.Error,
errorMessage: dryRunResult.errorMessage,
};
case RunStatus.Timeout:
case DryRunStatus.Timeout:
return {
status: MutantRunStatus.Timeout,
};
Expand Down
12 changes: 6 additions & 6 deletions packages/api/test/unit/test_runner2/runResultHelpers.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { expect } from 'chai';

import { toMutantRunResult, RunStatus, MutantRunResult, MutantRunStatus } from '../../../test_runner2';
import { toMutantRunResult, DryRunStatus, MutantRunResult, MutantRunStatus } from '../../../test_runner2';
import TestStatus from '../../../src/test_runner/TestStatus';

describe('runResultHelpers', () => {
describe(toMutantRunResult.name, () => {
it('should convert "timeout" to "timeout"', () => {
const expected: MutantRunResult = { status: MutantRunStatus.Timeout };
expect(toMutantRunResult({ status: RunStatus.Timeout })).deep.eq(expected);
expect(toMutantRunResult({ status: DryRunStatus.Timeout })).deep.eq(expected);
});

it('should convert "error" to "error"', () => {
const expected: MutantRunResult = { status: MutantRunStatus.Error, errorMessage: 'some error' };
expect(toMutantRunResult({ status: RunStatus.Error, errorMessage: 'some error' })).deep.eq(expected);
expect(toMutantRunResult({ status: DryRunStatus.Error, errorMessage: 'some error' })).deep.eq(expected);
});

it('should report a failed test as "killed"', () => {
const expected: MutantRunResult = { status: MutantRunStatus.Killed, failureMessage: 'expected foo to be bar', killedBy: '42' };
expect(
toMutantRunResult({
status: RunStatus.Complete,
status: DryRunStatus.Complete,
tests: [
{ status: TestStatus.Success, id: 'success1', name: 'success1', timeSpentMs: 42 },
{ status: TestStatus.Failed, id: '42', name: 'error', timeSpentMs: 42, failureMessage: 'expected foo to be bar' },
Expand All @@ -33,7 +33,7 @@ describe('runResultHelpers', () => {
const expected: MutantRunResult = { status: MutantRunStatus.Survived };
expect(
toMutantRunResult({
status: RunStatus.Complete,
status: DryRunStatus.Complete,
tests: [
{ status: TestStatus.Success, id: 'success1', name: 'success1', timeSpentMs: 42 },
{ status: TestStatus.Success, id: '42', name: 'error', timeSpentMs: 42 },
Expand All @@ -47,7 +47,7 @@ describe('runResultHelpers', () => {
const expected: MutantRunResult = { status: MutantRunStatus.Survived };
expect(
toMutantRunResult({
status: RunStatus.Complete,
status: DryRunStatus.Complete,
tests: [],
})
).deep.eq(expected);
Expand Down
2 changes: 1 addition & 1 deletion packages/api/test_runner2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export * from './src/test_runner2/DryRunResult';
export * from './src/test_runner2/RunOptions';
export * from './src/test_runner2/MutantCoverage';
export * from './src/test_runner2/MutantRunResult';
export * from './src/test_runner2/RunStatus';
export * from './src/test_runner2/DryRunStatus';
export * from './src/test_runner2/runResultHelpers';
Loading