New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

stryker

Package Overview
Dependencies
Maintainers
3
Versions
107
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

stryker - npm Package Compare versions

Comparing version 0.20.1 to 0.21.0

src/input/InputFileCollection.d.ts

25

CHANGELOG.md

@@ -6,2 +6,27 @@ # Change Log

<a name="0.21.0"></a>
# [0.21.0](https://github.com/stryker-mutator/stryker/compare/stryker@0.20.1...stryker@0.21.0) (2018-04-04)
### Bug Fixes
* **Progress reporter:** don't prevent stryker from closing ([21255aa](https://github.com/stryker-mutator/stryker/commit/21255aa))
### Features
* **identify-files:** use git to list files in `InputFileResolver` ([df6169a](https://github.com/stryker-mutator/stryker/commit/df6169a))
### BREAKING CHANGES
* **identify-files:** * The `InputFileDescriptor` syntax for files is no longer supported.
* Test runner plugins should keep track of which files are included
into a test run and in which order.
* Transpiler plugins should keep track of which files are to be
transpiled.
<a name="0.20.1"></a>

@@ -8,0 +33,0 @@ ## [0.20.1](https://github.com/stryker-mutator/stryker/compare/stryker@0.20.0...stryker@0.20.1) (2018-03-22)

8

package.json
{
"name": "stryker",
"version": "0.20.1",
"version": "0.21.0",
"description": "The extendable JavaScript mutation testing framework",

@@ -71,4 +71,4 @@ "main": "src/Stryker.js",

"rxjs": "^5.4.3",
"serialize-javascript": "^1.3.0",
"source-map": "^0.6.1",
"surrial": "^0.1.3",
"tslib": "^1.5.0",

@@ -83,7 +83,7 @@ "typed-rest-client": "^1.0.7"

"@types/progress": "^2.0.1",
"stryker-api": "^0.14.0"
"stryker-api": "^0.15.0"
},
"peerDependencies": {
"stryker-api": "^0.14.0"
"stryker-api": "^0.15.0"
}
}

@@ -50,7 +50,6 @@ [![Build Status](https://travis-ci.org/stryker-mutator/stryker.svg?branch=master)](https://travis-ci.org/stryker-mutator/stryker)

config.set({
files: ['test/helpers/**/*.js',
'test/unit/**/*.js',
{ pattern: 'src/**/*.js', included: false, mutated: true }
{ pattern: 'src/templates/*.html', included: false, mutated: false }
'!src/fileToIgnore.js'],
mutate: [
'src/**/*.js'
'!src/index.js'
],
testFramework: 'mocha',

@@ -65,5 +64,5 @@ testRunner: 'mocha',

As you can see, the config file is *not* a simple JSON file. It should be a common js (a.k.a. node) module. You might recognize this way of working from the karma test runner.
As you can see, the config file is *not* a simple JSON file. It should be a node module. You might recognize this way of working from the karma test runner.
Make sure you *at least* specify the `files` and the `testRunner` options when mixing the config file and/or command line options.
Make sure you *at least* specify the `testRunner` options when mixing the config file and/or command line options.

@@ -75,3 +74,3 @@ ## Command-line interface

```
```bash
$ npm install -g stryker-cli

@@ -82,6 +81,8 @@ ```

## Supported mutators
## Supported mutators
See our website for the [list of currently supported mutators](https://stryker-mutator.io/mutators.html).
## Configuration
All configuration options can either be set via the command line or via the `stryker.conf.js` config file.

@@ -91,34 +92,14 @@

This is the same globbing format you might know from [Grunt](https://github.com/gruntjs/grunt) or [Karma](https://github.com/karma-runner/karma).
You can *ignore* files by adding an exclamation mark (`!`) at the start of an expression.
#### Files required to run your tests
**Command line:** `[--files|-f] node_modules/a-lib/**/*.js,src/**/*.js,a.js,test/**/*.js`
**Config file:** `files: ['{ pattern: 'src/**/*.js', mutated: true }, '!src/**/index.js', 'test/**/*.js']`
**Default value:** *none*
**Mandatory**: yes
**Description:**
With `files` you specify all files needed to run your tests. If the test runner you use already provides the test framework (Jasmine, Mocha, etc.),
you should *not* include those files here as well.
The files will be loaded in the order in which they are specified. Files that you want to ignore should be mentioned last.
When using the command line, the list can only contain a comma separated list of globbing expressions.
When using the config file you can provide an array with `string`s or `InputFileDescriptor` objects, like so:
* `string`: The globbing expression used for selecting the files needed to run the tests.
* `InputFileDescriptor` object: `{ pattern: 'pattern', included: true, mutated: false }`:
* The `pattern` property is mandatory and contains the globbing expression used for selecting the files. Using `!` to ignore files is *not* supported here.
* The `included` property is optional and determines whether or not this file should be loaded initially by the test-runner (default: true). With `included: false` the files will be copied to the sandbox during testing, but they wont be explicitly loaded by the test runner. Two usecases for `included: false` are for HTML files and for source files when your tests `require()` them.
* The `mutated` property is optional and determines whether or not this file should be targeted for mutations (default: false)
*Note*: To include a file/folder which start with an exclamation mark (`!`), use the `InputFileDescriptor` syntax.
#### Source code files to mutate
#### Files to mutate
**Command line:** `[--mutate|-m] src/**/*.js,a.js`
**Config file:** `mutate: ['src/**/*.js', 'a.js']`
**Default value:** *none*
**Mandatory**: no
**Mandatory**: No
**Description:**
With `mutate` you configure the subset of files to use for mutation testing. Generally speaking, these should be your own source files.
This is optional, as you can also use the `mutated` property with the `files` parameter or not mutate any files at all to perform a dry-run (test-run).
We expect a comma separated list of globbing expressions, which will be used to select the files to be mutated.
With `mutate` you configure the subset of files to use for mutation testing.
Generally speaking, these should be your own source files.
This is optional, as you can choose to not mutate any files at all and perform a dry-run (running only your tests without mutating).

@@ -139,7 +120,10 @@ #### Test runner

**Default value:** *none*
**Mandatory**: yes
**Mandatory**: No
**Description:**
With `testFramework` you configure which test framework your tests are using. This value is directly consumed by the test runner and therefore
depends what framework that specific test runner supports. By default, this value is also used for `testFramework`.
Configure which test framework you are using.
This option is not mandatory, as Stryker is test framework agnostic (it doesn't care what framework you use),
However, it is required when `coverageAnalysis` is set to `'perTest'`, because Stryker needs to hook into the test framework in order to measure code coverage results per test and filter tests to run.
Make sure the a plugin is installed for your chosen test framework. E.g. install `stryker-mocha-framework` to use `'mocha'` as a test framework.
#### Type of coverage analysis

@@ -151,3 +135,4 @@ **Full notation:** `--coverageAnalysis perTest`

**Description:**
With `coverageAnalysis` you specify which coverage analysis strategy you want to use.
With `coverageAnalysis` you specify which coverage analysis strategy you want to use.
Stryker can analyse code coverage results. This can potentially speed up mutation testing a lot, as only the tests covering a

@@ -222,2 +207,20 @@ particular mutation are tested for each mutant.

#### Files in the sandbox
**Command line:** `[--files|-f] src/**/*.js,a.js,test/**/*.js`
**Config file:** `files: ['src/**/*.js', '!src/**/index.js', 'test/**/*.js']`
**Default value:** result of `git ls-files --others --exclude-standard --cached`
**Mandatory**: No
**Description:**
With `files` you can choose which files should be included in your test runner sandbox.
This is normally not needed as it defaults to all files not ignored by git.
Try it out yourself with this command: `git ls-files --others --exclude-standard --cached`.
If you do need to override `files` (for example: when your project does not live in a git repository),
you can override the files here.
When using the command line, the list can only contain a comma separated list of globbing expressions.
When using the config file you can provide an array with `string`s
You can *ignore* files by adding an exclamation mark (`!`) at the start of an expression.
#### Plugins

@@ -298,4 +301,3 @@ **Command line:** `--plugins stryker-html-reporter,stryker-karma-runner`

It is not allowed to only supply one value. However, `high` and `low` values can be the same, making sure colors are either red or green.
Set `break` to `null` (default) to never let the process crash.
It is not allowed to only supply one value of the values (it's all or nothing). However, `high` and `low` values can be the same, making sure colors are either red or green. Set `break` to `null` (default) to never let your build fail.

@@ -302,0 +304,0 @@ #### Log level

@@ -10,2 +10,3 @@ export declare type ChildProxy<T> = {

private workerTasks;
private log;
private constructor();

@@ -29,2 +30,3 @@ /**

dispose(): void;
private logUnidentifiedMessage(message);
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var child_process_1 = require("child_process");
var core_1 = require("stryker-api/core");
var messageProtocol_1 = require("./messageProtocol");
var objectUtils_1 = require("../utils/objectUtils");
var Task_1 = require("../utils/Task");
var log4js_1 = require("log4js");
var ChildProcessProxy = /** @class */ (function () {

@@ -12,2 +14,3 @@ function ChildProcessProxy(requirePath, logLevel, plugins, constructorFunction, constructorParams) {

this.workerTasks = [];
this.log = log4js_1.getLogger(ChildProcessProxy.name);
this.worker = child_process_1.fork(require.resolve('./ChildProcessProxyWorker'), [messageProtocol_1.autoStart], { silent: false, execArgv: [] });

@@ -67,9 +70,17 @@ this.initTask = new Task_1.default();

this.worker.on('message', function (serializedMessage) {
var message = objectUtils_1.deserialize(serializedMessage);
if (message === 'init_done') {
_this.initTask.resolve(undefined);
var message = objectUtils_1.deserialize(serializedMessage, [core_1.File]);
switch (message.kind) {
case messageProtocol_1.ParentMessageKind.Initialized:
_this.initTask.resolve(undefined);
break;
case messageProtocol_1.ParentMessageKind.Result:
_this.workerTasks[message.correlationId].resolve(message.result);
break;
case messageProtocol_1.ParentMessageKind.Rejection:
_this.workerTasks[message.correlationId].reject(new Error(message.error));
break;
default:
_this.logUnidentifiedMessage(message);
break;
}
else {
_this.workerTasks[message.correlationId].resolve(message.result);
}
});

@@ -80,2 +91,5 @@ };

};
ChildProcessProxy.prototype.logUnidentifiedMessage = function (message) {
this.log.error("Received unidentified message " + message);
};
return ChildProcessProxy;

@@ -82,0 +96,0 @@ }());

@@ -0,0 +0,0 @@ export default class ChildProcessProxyWorker {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var log4js_1 = require("log4js");
var core_1 = require("stryker-api/core");
var objectUtils_1 = require("../utils/objectUtils");
var messageProtocol_1 = require("./messageProtocol");
var log4js_1 = require("log4js");
var PluginLoader_1 = require("../PluginLoader");

@@ -20,3 +21,3 @@ var ChildProcessProxyWorker = /** @class */ (function () {

var handler = function (serializedMessage) {
var message = objectUtils_1.deserialize(serializedMessage);
var message = objectUtils_1.deserialize(serializedMessage, [core_1.File]);
switch (message.kind) {

@@ -28,12 +29,22 @@ case messageProtocol_1.WorkerMessageKind.Init:

_this.realSubject = new (RealSubjectClass.bind.apply(RealSubjectClass, [void 0].concat(message.constructorArgs)))();
_this.send('init_done');
_this.send({ kind: messageProtocol_1.ParentMessageKind.Initialized });
_this.removeAnyAdditionalMessageListeners(handler);
break;
case messageProtocol_1.WorkerMessageKind.Work:
var result = (_a = _this.realSubject)[message.methodName].apply(_a, message.args);
Promise.resolve(result).then(function (result) {
new Promise(function (resolve) {
return resolve((_a = _this.realSubject)[message.methodName].apply(_a, message.args));
var _a;
})
.then(function (result) {
_this.send({
kind: messageProtocol_1.ParentMessageKind.Result,
correlationId: message.correlationId,
result: result
});
}).catch(function (error) {
_this.send({
kind: messageProtocol_1.ParentMessageKind.Rejection,
error: objectUtils_1.errorToString(error),
correlationId: message.correlationId
});
});

@@ -43,3 +54,2 @@ _this.removeAnyAdditionalMessageListeners(handler);

}
var _a;
};

@@ -46,0 +56,0 @@ process.on('message', handler);

@@ -5,4 +5,11 @@ export declare enum WorkerMessageKind {

}
export declare enum ParentMessageKind {
'Initialized' = 0,
'Result' = 1,
'Rejection' = 2,
}
export declare type WorkerMessage = InitMessage | WorkMessage;
export declare type ParentMessage = WorkResult | 'init_done';
export declare type ParentMessage = WorkResult | {
kind: ParentMessageKind.Initialized;
} | RejectionResult;
export declare const autoStart = "childProcessAutoStart12937129s7d";

@@ -17,5 +24,11 @@ export interface InitMessage {

export interface WorkResult {
kind: ParentMessageKind.Result;
correlationId: number;
result: any;
}
export interface RejectionResult {
kind: ParentMessageKind.Rejection;
correlationId: number;
error: string;
}
export interface WorkMessage {

@@ -22,0 +35,0 @@ correlationId: number;

@@ -8,2 +8,8 @@ "use strict";

})(WorkerMessageKind = exports.WorkerMessageKind || (exports.WorkerMessageKind = {}));
var ParentMessageKind;
(function (ParentMessageKind) {
ParentMessageKind[ParentMessageKind["Initialized"] = 0] = "Initialized";
ParentMessageKind[ParentMessageKind["Result"] = 1] = "Result";
ParentMessageKind[ParentMessageKind["Rejection"] = 2] = "Rejection";
})(ParentMessageKind = exports.ParentMessageKind || (exports.ParentMessageKind = {}));
// Make this an unlikely command line argument

@@ -10,0 +16,0 @@ // (prevents incidental start of child process)

@@ -0,0 +0,0 @@ import { Config } from 'stryker-api/config';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { TestFramework } from 'stryker-api/test_framework';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { StatementMap } from 'stryker-api/test_runner';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=FileStatements.js.map

@@ -0,0 +0,0 @@ /**

@@ -0,0 +0,0 @@ import { RestClient } from 'typed-rest-client/RestClient';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ interface PromptOption {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=PromptOption.js.map

@@ -0,0 +0,0 @@ import { StrykerOptions } from 'stryker-api/core';

@@ -30,6 +30,2 @@ "use strict";

configObject = {
files: [
{ pattern: 'src/**/*.js', mutated: true, included: false },
'test/**/*.js'
],
testRunner: selectedTestRunner ? selectedTestRunner.name : '',

@@ -36,0 +32,0 @@ mutator: selectedMutator ? selectedMutator.name : '',

@@ -0,0 +0,0 @@ import NpmClient from './NpmClient';

@@ -57,3 +57,2 @@ "use strict";

.concat(selectedReporters));
this.installNpmDependencies(npmDependencies);
_c = (_b = configWriter).write;

@@ -69,3 +68,4 @@ _d = [selectedTestRunner,

_e.sent();
this.out('Done configuring stryker. Please review `stryker.conf.js`, you might need to configure your files and test runner correctly.');
this.installNpmDependencies(npmDependencies);
this.out('Done configuring stryker. Please review `stryker.conf.js`, you might need to configure transpilers or your test runner correctly.');
this.out('Let\'s kill some mutants with this command: `stryker run`');

@@ -72,0 +72,0 @@ return [2 /*return*/];

@@ -0,0 +0,0 @@ import PromptOption from './PromptOption';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { RunnerOptions } from 'stryker-api/test_runner';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IsolatedRunnerOptions.js.map

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -94,3 +94,8 @@ "use strict";

if (_this.currentTask.kind === 'init') {
_this.currentTask.resolve(undefined);
if (message.errorMessage) {
_this.currentTask.reject(message.errorMessage);
}
else {
_this.currentTask.resolve(undefined);
}
}

@@ -97,0 +102,0 @@ else {

@@ -64,11 +64,19 @@ "use strict";

return tslib_1.__awaiter(this, void 0, void 0, function () {
var err_1;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.underlyingTestRunner.init) return [3 /*break*/, 2];
if (!this.underlyingTestRunner.init) return [3 /*break*/, 4];
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this.underlyingTestRunner.init()];
case 1:
case 2:
_a.sent();
_a.label = 2;
case 2:
return [3 /*break*/, 4];
case 3:
err_1 = _a.sent();
this.sendInitDone(objectUtils_1.errorToString(err_1));
return [3 /*break*/, 4];
case 4:
this.sendInitDone();

@@ -80,4 +88,5 @@ return [2 /*return*/];

};
IsolatedTestRunnerAdapterWorker.prototype.sendInitDone = function () {
var message = { kind: 'initDone' };
IsolatedTestRunnerAdapterWorker.prototype.sendInitDone = function (errorMessage) {
if (errorMessage === void 0) { errorMessage = null; }
var message = { kind: 'initDone', errorMessage: errorMessage };
if (process.send) {

@@ -84,0 +93,0 @@ process.send(message);

@@ -5,3 +5,3 @@ import { RunResult } from 'stryker-api/test_runner';

export declare type AdapterMessage = RunMessage | StartMessage | EmptyAdapterMessage;
export declare type WorkerMessage = ResultMessage | EmptyWorkerMessage;
export declare type WorkerMessage = ResultMessage | EmptyWorkerMessage | InitDoneMessage;
export interface ResultMessage {

@@ -20,2 +20,6 @@ kind: 'result';

}
export interface InitDoneMessage {
kind: 'initDone';
errorMessage: string | null;
}
export interface EmptyAdapterMessage {

@@ -25,3 +29,3 @@ kind: 'init' | 'dispose';

export interface EmptyWorkerMessage {
kind: 'initDone' | 'disposeDone';
kind: 'disposeDone';
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=MessageProtocol.js.map

@@ -0,0 +0,0 @@ import IsolatedRunnerOptions from './IsolatedRunnerOptions';

@@ -0,0 +0,0 @@ import { RunOptions, RunResult } from 'stryker-api/test_runner';

@@ -0,0 +0,0 @@ "use strict";

@@ -1,5 +0,3 @@

/// <reference types="node" />
import { EventEmitter } from 'events';
import { TestRunner, RunOptions, RunResult } from 'stryker-api/test_runner';
export default class TestRunnerDecorator extends EventEmitter implements TestRunner {
export default class TestRunnerDecorator implements TestRunner {
private testRunnerProducer;

@@ -6,0 +4,0 @@ protected innerRunner: TestRunner;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var events_1 = require("events");
var TestRunnerDecorator = /** @class */ (function (_super) {
tslib_1.__extends(TestRunnerDecorator, _super);
var TestRunnerDecorator = /** @class */ (function () {
function TestRunnerDecorator(testRunnerProducer) {
var _this = _super.call(this) || this;
_this.testRunnerProducer = testRunnerProducer;
_this.createInnerRunner();
return _this;
this.testRunnerProducer = testRunnerProducer;
this.createInnerRunner();
}

@@ -36,4 +31,4 @@ TestRunnerDecorator.prototype.init = function () {

return TestRunnerDecorator;
}(events_1.EventEmitter));
}());
exports.default = TestRunnerDecorator;
//# sourceMappingURL=TestRunnerDecorator.js.map

@@ -7,2 +7,3 @@ import { RunOptions, RunResult } from 'stryker-api/test_runner';

export default class TimeoutDecorator extends TestRunnerDecorator {
private readonly log;
run(options: RunOptions): Promise<RunResult>;

@@ -9,0 +10,0 @@ dispose(): Promise<any>;

@@ -8,2 +8,3 @@ "use strict";

var TestRunnerDecorator_1 = require("./TestRunnerDecorator");
var log4js_1 = require("log4js");
var MAX_WAIT_FOR_DISPOSE = 2500;

@@ -16,6 +17,9 @@ /**

function TimeoutDecorator() {
return _super !== null && _super.apply(this, arguments) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.log = log4js_1.getLogger(TimeoutDecorator.name);
return _this;
}
TimeoutDecorator.prototype.run = function (options) {
var _this = this;
this.log.debug('Starting timeout timer (%s ms) for a test run', options.timeout);
var runTask = new Task_1.default(options.timeout, function () { return _this.handleTimeout(); });

@@ -22,0 +26,0 @@ runTask.chainTo(_super.prototype.run.call(this, options));

@@ -10,3 +10,3 @@ import { RunResult } from 'stryker-api/test_runner';

private mutants;
private files;
private filesToMutate;
private initialRunResult;

@@ -18,3 +18,3 @@ private sourceMapper;

private readonly log;
constructor(mutants: Mutant[], files: File[], initialRunResult: RunResult, sourceMapper: SourceMapper, coveragePerFile: CoverageMapsByFile, options: StrykerOptions, reporter: StrictReporter);
constructor(mutants: ReadonlyArray<Mutant>, filesToMutate: ReadonlyArray<File>, initialRunResult: RunResult, sourceMapper: SourceMapper, coveragePerFile: CoverageMapsByFile, options: StrykerOptions, reporter: StrictReporter);
private readonly baseline;

@@ -21,0 +21,0 @@ matchWithMutants(): TestableMutant[];

@@ -15,5 +15,5 @@ "use strict";

var MutantTestMatcher = /** @class */ (function () {
function MutantTestMatcher(mutants, files, initialRunResult, sourceMapper, coveragePerFile, options, reporter) {
function MutantTestMatcher(mutants, filesToMutate, initialRunResult, sourceMapper, coveragePerFile, options, reporter) {
this.mutants = mutants;
this.files = files;
this.filesToMutate = filesToMutate;
this.initialRunResult = initialRunResult;

@@ -46,3 +46,3 @@ this.sourceMapper = sourceMapper;

this.log.warn('No coverage result found, even though coverageAnalysis is "%s". Assuming that all tests cover each mutant. This might have a big impact on the performance.', this.options.coverageAnalysis);
testableMutants.forEach(function (mutant) { return mutant.selectAllTests(_this.initialRunResult, TestableMutant_1.TestSelectionResult.FailedButAlreadyReporter); });
testableMutants.forEach(function (mutant) { return mutant.selectAllTests(_this.initialRunResult, TestableMutant_1.TestSelectionResult.FailedButAlreadyReported); });
}

@@ -112,3 +112,3 @@ else {

var _this = this;
var sourceFiles = this.files.filter(function (file) { return file.mutated; }).map(function (file) { return new SourceFile_1.default(file); });
var sourceFiles = this.filesToMutate.map(function (file) { return new SourceFile_1.default(file); });
return objectUtils_1.filterEmpty(this.mutants.map(function (mutant, index) {

@@ -115,0 +115,0 @@ var sourceFile = sourceFiles.find(function (file) { return file.name === mutant.fileName; });

@@ -7,4 +7,4 @@ import { File } from 'stryker-api/core';

constructor(config: Config);
mutate(inputFiles: File[]): Mutant[];
mutate(inputFiles: ReadonlyArray<File>): ReadonlyArray<Mutant>;
private getMutatorName(mutator);
}

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -11,3 +11,3 @@ import { Config } from 'stryker-api/config';

private mutateForFile(file);
private mutateForNodes(sourceFile, nodes);
private mutateForNodes(file, nodes);
}

@@ -5,3 +5,2 @@ "use strict";

var log4js_1 = require("log4js");
var core_1 = require("stryker-api/core");
var parserUtils = require("../utils/parserUtils");

@@ -35,17 +34,10 @@ var objectUtils_1 = require("../utils/objectUtils");

var _this = this;
return _.flatMap(files, function (file) {
if (file.mutated && file.kind === core_1.FileKind.Text) {
return _this.mutateForFile(file);
}
else {
return [];
}
});
return _.flatMap(files, function (file) { return _this.mutateForFile(file); });
};
ES5Mutator.prototype.mutateForFile = function (file) {
var abstractSyntaxTree = parserUtils.parse(file.content);
var abstractSyntaxTree = parserUtils.parse(file.textContent);
var nodes = new parserUtils.NodeIdentifier().identifyAndFreeze(abstractSyntaxTree);
return this.mutateForNodes(file, nodes);
};
ES5Mutator.prototype.mutateForNodes = function (sourceFile, nodes) {
ES5Mutator.prototype.mutateForNodes = function (file, nodes) {
var _this = this;

@@ -63,3 +55,3 @@ return _.flatMap(nodes, function (astNode) {

if (mutatedNodes.length > 0) {
_this.log.debug("The mutator '" + mutator.name + "' mutated " + mutatedNodes.length + " node" + (mutatedNodes.length > 1 ? 's' : '') + " between (Ln " + astNode.loc.start.line + ", Col " + astNode.loc.start.column + ") and (Ln " + astNode.loc.end.line + ", Col " + astNode.loc.end.column + ") in file " + sourceFile.name);
_this.log.debug("The mutator '" + mutator.name + "' mutated " + mutatedNodes.length + " node" + (mutatedNodes.length > 1 ? 's' : '') + " between (Ln " + astNode.loc.start.line + ", Col " + astNode.loc.start.column + ") and (Ln " + astNode.loc.end.line + ", Col " + astNode.loc.end.column + ") in file " + file.name);
}

@@ -69,3 +61,3 @@ return mutatedNodes.map(function (mutatedNode) {

var originalNode = nodes[mutatedNode.nodeID];
var mutant = { mutatorName: mutator.name, fileName: sourceFile.name, replacement: replacement, range: originalNode.range };
var mutant = { mutatorName: mutator.name, fileName: file.name, replacement: replacement, range: originalNode.range };
return mutant;

@@ -72,0 +64,0 @@ });

@@ -0,0 +0,0 @@ import { Node } from 'estree';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=IdentifiedNode.js.map

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { IdentifiedNode } from './IdentifiedNode';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=NodeMutator.js.map

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import NodeMutator from './NodeMutator';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export default class PluginLoader {

@@ -0,0 +0,0 @@ "use strict";

import { RunResult } from 'stryker-api/test_runner';
import { TestFramework } from 'stryker-api/test_framework';
import { Config } from 'stryker-api/config';
import { File } from 'stryker-api/core';
import Timer from '../utils/Timer';
import { CoverageMapsByFile } from '../transpiler/CoverageInstrumenterTranspiler';
import InputFileCollection from '../input/InputFileCollection';
import SourceMapper from '../transpiler/SourceMapper';
export interface InitialTestRunResult {
runResult: RunResult;
transpiledFiles: File[];
sourceMapper: SourceMapper;
coverageMaps: CoverageMapsByFile;

@@ -14,11 +15,12 @@ }

private options;
private files;
private inputFiles;
private testFramework;
private timer;
private readonly log;
constructor(options: Config, files: File[], testFramework: TestFramework | null, timer: Timer);
constructor(options: Config, inputFiles: InputFileCollection, testFramework: TestFramework | null, timer: Timer);
run(): Promise<InitialTestRunResult>;
private initialRunInSandbox();
private runInSandbox(files);
private transpileInputFiles();
private annotateForCodeCoverage(files, sourceMapper);
private validateResult(runResult);
private createDryRunResult();
/**

@@ -29,5 +31,5 @@ * Creates a facade for the transpile pipeline.

*/
private createTranspilerFacade(coverageInstrumenterTranspiler);
private createCoverageInstrumenterTranspiler();
private logTranspileResult(transpileResult);
private createTranspilerFacade();
private getCollectCoverageHooksIfNeeded();
private logTranspileResult(transpiledFiles);
private filterOutFailedTests(runResult);

@@ -34,0 +36,0 @@ private logInitialTestRunSucceeded(tests);

@@ -10,2 +10,4 @@ "use strict";

var CoverageInstrumenterTranspiler_1 = require("../transpiler/CoverageInstrumenterTranspiler");
var SourceMapper_1 = require("../transpiler/SourceMapper");
var coverageHooks_1 = require("../transpiler/coverageHooks");
// The initial run might take a while.

@@ -16,5 +18,5 @@ // For example: angular-bootstrap takes up to 45 seconds.

var InitialTestExecutor = /** @class */ (function () {
function InitialTestExecutor(options, files, testFramework, timer) {
function InitialTestExecutor(options, inputFiles, testFramework, timer) {
this.options = options;
this.files = files;
this.inputFiles = inputFiles;
this.testFramework = testFramework;

@@ -26,16 +28,24 @@ this.timer = timer;

return tslib_1.__awaiter(this, void 0, void 0, function () {
var result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
var transpiledFiles, sourceMapper, _a, coverageMaps, instrumentedFiles, runResult;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(this.files.length > 0)) return [3 /*break*/, 2];
this.log.info("Starting initial test run. This may take a while.");
return [4 /*yield*/, this.initialRunInSandbox()];
return [4 /*yield*/, this.transpileInputFiles()];
case 1:
result = _a.sent();
this.validateResult(result.runResult);
return [2 /*return*/, result];
transpiledFiles = _b.sent();
sourceMapper = SourceMapper_1.default.create(transpiledFiles, this.options);
return [4 /*yield*/, this.annotateForCodeCoverage(transpiledFiles, sourceMapper)];
case 2:
this.log.info("No files have been found. Aborting initial test run.");
return [2 /*return*/, this.createDryRunResult()];
_a = _b.sent(), coverageMaps = _a.coverageMaps, instrumentedFiles = _a.instrumentedFiles;
this.logTranspileResult(instrumentedFiles);
return [4 /*yield*/, this.runInSandbox(instrumentedFiles)];
case 3:
runResult = _b.sent();
this.validateResult(runResult);
return [2 /*return*/, {
sourceMapper: sourceMapper,
runResult: runResult,
coverageMaps: coverageMaps
}];
}

@@ -45,31 +55,17 @@ });

};
InitialTestExecutor.prototype.initialRunInSandbox = function () {
InitialTestExecutor.prototype.runInSandbox = function (files) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var coverageInstrumenterTranspiler, transpilerFacade, transpileResult, sandbox_1, runResult;
var sandbox, runResult;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
coverageInstrumenterTranspiler = this.createCoverageInstrumenterTranspiler();
transpilerFacade = this.createTranspilerFacade(coverageInstrumenterTranspiler);
return [4 /*yield*/, transpilerFacade.transpile(this.files)];
case 0: return [4 /*yield*/, Sandbox_1.default.create(this.options, 0, files, this.testFramework)];
case 1:
transpileResult = _a.sent();
if (!transpileResult.error) return [3 /*break*/, 2];
throw new Error("Could not transpile input files: " + transpileResult.error);
sandbox = _a.sent();
return [4 /*yield*/, sandbox.run(INITIAL_RUN_TIMEOUT, this.getCollectCoverageHooksIfNeeded())];
case 2:
this.logTranspileResult(transpileResult);
return [4 /*yield*/, Sandbox_1.default.create(this.options, 0, transpileResult.outputFiles, this.testFramework)];
runResult = _a.sent();
return [4 /*yield*/, sandbox.dispose()];
case 3:
sandbox_1 = _a.sent();
return [4 /*yield*/, sandbox_1.run(INITIAL_RUN_TIMEOUT)];
case 4:
runResult = _a.sent();
return [4 /*yield*/, sandbox_1.dispose()];
case 5:
_a.sent();
return [2 /*return*/, {
runResult: runResult,
transpiledFiles: transpileResult.outputFiles,
coverageMaps: coverageInstrumenterTranspiler.fileCoverageMaps
}];
return [2 /*return*/, runResult];
}

@@ -79,2 +75,31 @@ });

};
InitialTestExecutor.prototype.transpileInputFiles = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var transpilerFacade;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
transpilerFacade = this.createTranspilerFacade();
return [4 /*yield*/, transpilerFacade.transpile(this.inputFiles.files)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
InitialTestExecutor.prototype.annotateForCodeCoverage = function (files, sourceMapper) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var filesToInstrument, coverageInstrumenterTranspiler, instrumentedFiles;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
filesToInstrument = this.inputFiles.filesToMutate.map(function (mutateFile) { return sourceMapper.transpiledFileNameFor(mutateFile.name); });
coverageInstrumenterTranspiler = new CoverageInstrumenterTranspiler_1.default(this.options, filesToInstrument);
return [4 /*yield*/, coverageInstrumenterTranspiler.transpile(files)];
case 1:
instrumentedFiles = _a.sent();
return [2 /*return*/, { coverageMaps: coverageInstrumenterTranspiler.fileCoverageMaps, instrumentedFiles: instrumentedFiles }];
}
});
});
};
InitialTestExecutor.prototype.validateResult = function (runResult) {

@@ -105,13 +130,2 @@ switch (runResult.status) {

};
InitialTestExecutor.prototype.createDryRunResult = function () {
return {
runResult: {
status: test_runner_1.RunStatus.Complete,
tests: [],
errorMessages: []
},
transpiledFiles: [],
coverageMaps: Object.create(null)
};
};
/**

@@ -122,3 +136,3 @@ * Creates a facade for the transpile pipeline.

*/
InitialTestExecutor.prototype.createTranspilerFacade = function (coverageInstrumenterTranspiler) {
InitialTestExecutor.prototype.createTranspilerFacade = function () {
// Let the transpiler produce source maps only if coverage analysis is enabled

@@ -129,13 +143,20 @@ var transpilerSettings = {

};
return new TranspilerFacade_1.default(transpilerSettings, {
name: CoverageInstrumenterTranspiler_1.default.name,
transpiler: coverageInstrumenterTranspiler
});
return new TranspilerFacade_1.default(transpilerSettings);
};
InitialTestExecutor.prototype.createCoverageInstrumenterTranspiler = function () {
return new CoverageInstrumenterTranspiler_1.default({ produceSourceMaps: true, config: this.options }, this.testFramework);
InitialTestExecutor.prototype.getCollectCoverageHooksIfNeeded = function () {
if (this.options.coverageAnalysis === 'perTest') {
if (this.testFramework) {
// Add piece of javascript to collect coverage per test results
this.log.debug("Adding test hooks for coverageAnalysis \"perTest\".");
return coverageHooks_1.coveragePerTestHooks(this.testFramework);
}
else {
this.log.warn('Cannot measure coverage results per test, there is no testFramework and thus no way of executing code right before and after each test.');
}
}
return undefined;
};
InitialTestExecutor.prototype.logTranspileResult = function (transpileResult) {
InitialTestExecutor.prototype.logTranspileResult = function (transpiledFiles) {
if (this.options.transpilers.length && this.log.isDebugEnabled()) {
this.log.debug("Transpiled files in order:" + os_1.EOL + transpileResult.outputFiles.map(function (f) { return f.name + " (included: " + f.included + ")"; }).join(os_1.EOL));
this.log.debug("Transpiled files: " + JSON.stringify(transpiledFiles.map(function (f) { return "" + f.name; }), null, 2));
}

@@ -142,0 +163,0 @@ };

@@ -12,5 +12,5 @@ import { MutantResult } from 'stryker-api/report';

private reporter;
constructor(config: Config, inputFiles: File[], testFramework: TestFramework | null, reporter: StrictReporter);
constructor(config: Config, inputFiles: ReadonlyArray<File>, testFramework: TestFramework | null, reporter: StrictReporter);
run(allMutants: TestableMutant[]): Promise<MutantResult[]>;
private runInsideSandboxes(sandboxes, transpiledMutants);
}

@@ -18,3 +18,3 @@ "use strict";

return tslib_1.__awaiter(this, void 0, void 0, function () {
var mutantTranspiler, transpileResult, sandboxPool, result;
var mutantTranspiler, transpiledFiles, sandboxPool, result;
return tslib_1.__generator(this, function (_a) {

@@ -26,4 +26,4 @@ switch (_a.label) {

case 1:
transpileResult = _a.sent();
sandboxPool = new SandboxPool_1.default(this.config, this.testFramework, transpileResult.outputFiles);
transpiledFiles = _a.sent();
sandboxPool = new SandboxPool_1.default(this.config, this.testFramework, transpiledFiles);
return [4 /*yield*/, this.runInsideSandboxes(sandboxPool.streamSandboxes(), mutantTranspiler.transpileMutants(allMutants))];

@@ -30,0 +30,0 @@ case 2:

@@ -0,0 +0,0 @@ import { StrykerOptions } from 'stryker-api/core';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { Reporter, SourceFile, MutantResult, MatchedMutant, ScoreResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { Reporter, MutantResult, ScoreResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { MutationScoreThresholds } from 'stryker-api/core';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { HttpClient } from 'typed-rest-client/HttpClient';

@@ -0,0 +0,0 @@ import { Reporter, ScoreResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { Reporter, MutantResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { StrykerOptions } from 'stryker-api/core';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { MatchedMutant } from 'stryker-api/report';

@@ -15,4 +15,6 @@ "use strict";

_super.prototype.onAllMutantsMatchedWithTests.call(this, matchedMutants);
this.timer = new Timer_1.default();
this.intervalReference = setInterval(function () { return _this.render(); }, 10000);
if (matchedMutants.length) {
this.timer = new Timer_1.default();
this.intervalReference = setInterval(function () { return _this.render(); }, 10000);
}
};

@@ -19,0 +21,0 @@ ProgressAppendOnlyReporter.prototype.onAllMutantsTested = function () {

import ProgressBar = require('progress');
export default ProgressBar;

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { MatchedMutant, Reporter, MutantResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { MatchedMutant, MutantResult } from 'stryker-api/report';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { Reporter, SourceFile, MutantResult, MatchedMutant, ScoreResult } from 'stryker-api/report';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=StrictReporter.js.map

@@ -15,7 +15,6 @@ import { Config } from 'stryker-api/config';

private workingFolder;
private testHooksFile;
private constructor();
private initialize();
static create(options: Config, index: number, files: ReadonlyArray<File>, testFramework: TestFramework | null): Promise<Sandbox>;
run(timeout: number): Promise<RunResult>;
run(timeout: number, testHooks: string | undefined): Promise<RunResult>;
dispose(): Promise<void>;

@@ -29,3 +28,3 @@ runMutant(transpiledMutant: TranspiledMutant): Promise<RunResult>;

private calculateTimeout(mutant);
private filterTests(mutant);
private getFilterTestsHooks(mutant);
}

@@ -7,7 +7,6 @@ "use strict";

var mkdirp = require("mkdirp");
var core_1 = require("stryker-api/core");
var objectUtils_1 = require("./utils/objectUtils");
var ResilientTestRunnerFactory_1 = require("./isolated-runner/ResilientTestRunnerFactory");
var TempFolder_1 = require("./utils/TempFolder");
var fileUtils = require("./utils/fileUtils");
var fileUtils_1 = require("./utils/fileUtils");
var TestableMutant_1 = require("./TestableMutant");

@@ -20,17 +19,5 @@ var Sandbox = /** @class */ (function () {

this.log = log4js_1.getLogger(Sandbox.name);
this.testHooksFile = path.resolve('___testHooksForStryker.js');
this.workingFolder = TempFolder_1.TempFolder.instance().createRandomFolder('sandbox');
this.log.debug('Creating a sandbox for files in %s', this.workingFolder);
this.files = files.slice(); // Create a copy
if (testFramework) {
this.testHooksFile = path.resolve('___testHooksForStryker.js');
this.files.unshift({
name: this.testHooksFile,
content: '',
mutated: false,
included: true,
transpiled: false,
kind: core_1.FileKind.Text
});
}
}

@@ -53,4 +40,4 @@ Sandbox.prototype.initialize = function () {

};
Sandbox.prototype.run = function (timeout) {
return this.testRunner.run({ timeout: timeout });
Sandbox.prototype.run = function (timeout, testHooks) {
return this.testRunner.run({ timeout: timeout, testHooks: testHooks });
};

@@ -71,6 +58,6 @@ Sandbox.prototype.dispose = function () {

}
return [4 /*yield*/, Promise.all(mutantFiles.map(function (mutatedFile) { return _this.writeFileInSandbox(mutatedFile); }).concat(this.filterTests(transpiledMutant.mutant)))];
return [4 /*yield*/, Promise.all(mutantFiles.map(function (mutatedFile) { return _this.writeFileInSandbox(mutatedFile); }))];
case 1:
_a.sent();
return [4 /*yield*/, this.run(this.calculateTimeout(transpiledMutant.mutant))];
return [4 /*yield*/, this.run(this.calculateTimeout(transpiledMutant.mutant), this.getFilterTestsHooks(transpiledMutant.mutant))];
case 2:

@@ -89,19 +76,7 @@ runResult = _a.sent();

var originalFiles = this.files.filter(function (originalFile) { return mutatedFiles.some(function (mutatedFile) { return mutatedFile.name === originalFile.name; }); });
return Promise.all(originalFiles.map(function (file) {
if (file.kind !== core_1.FileKind.Web) {
return fileUtils.writeFile(_this.fileMap[file.name], file.content);
}
else {
return Promise.resolve();
}
}));
return Promise.all(originalFiles.map(function (file) { return fileUtils_1.writeFile(_this.fileMap[file.name], file.content); }));
};
Sandbox.prototype.writeFileInSandbox = function (file) {
switch (file.kind) {
case core_1.FileKind.Web:
return Promise.resolve();
default:
var fileNameInSandbox = this.fileMap[file.name];
return fileUtils.writeFile(fileNameInSandbox, file.content);
}
var fileNameInSandbox = this.fileMap[file.name];
return fileUtils_1.writeFile(fileNameInSandbox, file.content);
};

@@ -116,27 +91,13 @@ Sandbox.prototype.fillSandbox = function () {

Sandbox.prototype.fillFile = function (file) {
switch (file.kind) {
case core_1.FileKind.Web:
this.fileMap[file.name] = file.name;
return Promise.resolve();
default:
var cwd = process.cwd();
var relativePath = path.relative(cwd, file.name);
var folderName = path.join(this.workingFolder, path.dirname(relativePath));
mkdirp.sync(folderName);
var targetFile = path.join(folderName, path.basename(relativePath));
this.fileMap[file.name] = targetFile;
return fileUtils.writeFile(targetFile, file.content);
}
var relativePath = path.relative(process.cwd(), file.name);
var folderName = path.join(this.workingFolder, path.dirname(relativePath));
mkdirp.sync(folderName);
var targetFile = path.join(folderName, path.basename(relativePath));
this.fileMap[file.name] = targetFile;
return fileUtils_1.writeFile(targetFile, file.content);
};
Sandbox.prototype.initializeTestRunner = function () {
var _this = this;
var files = this.files.map(function (originalFile) { return ({
name: _this.fileMap[originalFile.name],
mutated: originalFile.mutated,
included: originalFile.included,
kind: originalFile.kind,
transpiled: originalFile.transpiled
}); });
var settings = {
files: files,
fileNames: Object.keys(this.fileMap).map(function (sourceFileName) { return _this.fileMap[sourceFileName]; }),
strykerOptions: this.options,

@@ -154,9 +115,8 @@ port: this.options.port + this.index,

};
Sandbox.prototype.filterTests = function (mutant) {
Sandbox.prototype.getFilterTestsHooks = function (mutant) {
if (this.testFramework) {
var fileContent = objectUtils_1.wrapInClosure(this.testFramework.filter(mutant.selectedTests));
return fileUtils.writeFile(this.fileMap[this.testHooksFile], fileContent);
return objectUtils_1.wrapInClosure(this.testFramework.filter(mutant.selectedTests));
}
else {
return Promise.resolve(void 0);
return undefined;
}

@@ -163,0 +123,0 @@ };

@@ -13,3 +13,3 @@ import { Observable } from 'rxjs';

private isDisposed;
constructor(options: Config, testFramework: TestFramework | null, initialFiles: File[]);
constructor(options: Config, testFramework: TestFramework | null, initialFiles: ReadonlyArray<File>);
streamSandboxes(): Observable<Sandbox>;

@@ -16,0 +16,0 @@ private registerSandbox(promisedSandbox);

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { MutationScoreThresholds } from 'stryker-api/core';

@@ -0,0 +0,0 @@ "use strict";

@@ -1,7 +0,7 @@

import { TextFile, Range, Location, Position } from 'stryker-api/core';
import { File, Range, Location, Position } from 'stryker-api/core';
export declare function isLineBreak(ch: number): boolean;
export default class SourceFile {
file: TextFile;
file: File;
private lineStarts;
constructor(file: TextFile);
constructor(file: File);
readonly name: string;

@@ -8,0 +8,0 @@ readonly content: string;

@@ -34,3 +34,3 @@ "use strict";

get: function () {
return this.file.content;
return this.file.textContent;
},

@@ -93,8 +93,8 @@ enumerable: true,

var lineStart = 0;
while (pos < this.file.content.length) {
var ch = this.file.content.charCodeAt(pos);
while (pos < this.file.textContent.length) {
var ch = this.file.textContent.charCodeAt(pos);
pos++;
switch (ch) {
case 13 /* carriageReturn */:
if (this.file.content.charCodeAt(pos) === 10 /* lineFeed */) {
if (this.file.textContent.charCodeAt(pos) === 10 /* lineFeed */) {
pos++;

@@ -101,0 +101,0 @@ }

@@ -17,3 +17,3 @@ import { Config } from 'stryker-api/config';

runMutationTest(): Promise<MutantResult[]>;
private mutate(inputFiles, initialTestRunResult);
private mutate(input, initialTestRunResult);
private logMutantCount(includedMutantCount, totalMutantCount);

@@ -27,5 +27,3 @@ private removeExcludedMutants(mutants);

private setGlobalLogLevel();
private createMutationTester(inputFiles);
private createInitialTestRunProcess(inputFiles);
private reportScore(mutantResults);
}

@@ -8,3 +8,3 @@ "use strict";

var MutantTestMatcher_1 = require("./MutantTestMatcher");
var InputFileResolver_1 = require("./InputFileResolver");
var InputFileResolver_1 = require("./input/InputFileResolver");
var ConfigReader_1 = require("./ConfigReader");

@@ -21,3 +21,2 @@ var PluginLoader_1 = require("./PluginLoader");

var MutationTestExecutor_1 = require("./process/MutationTestExecutor");
var SourceMapper_1 = require("./transpiler/SourceMapper");
var Stryker = /** @class */ (function () {

@@ -53,4 +52,5 @@ /**

inputFiles = _a.sent();
if (!inputFiles.files.length) return [3 /*break*/, 8];
TempFolder_1.TempFolder.instance().initialize();
initialTestRunProcess = this.createInitialTestRunProcess(inputFiles);
initialTestRunProcess = new InitialTestExecutor_1.default(this.config, inputFiles, this.testFramework, this.timer);
return [4 /*yield*/, initialTestRunProcess.run()];

@@ -63,3 +63,3 @@ case 2:

if (!(initialTestRunResult.runResult.tests.length && testableMutants.length)) return [3 /*break*/, 8];
mutationTestExecutor = this.createMutationTester(inputFiles);
mutationTestExecutor = new MutationTestExecutor_1.default(this.config, inputFiles.files, this.testFramework, this.reporter);
return [4 /*yield*/, mutationTestExecutor.run(testableMutants)];

@@ -84,8 +84,8 @@ case 4:

};
Stryker.prototype.mutate = function (inputFiles, initialTestRunResult) {
Stryker.prototype.mutate = function (input, initialTestRunResult) {
var mutator = new MutatorFacade_1.default(this.config);
var allMutants = mutator.mutate(inputFiles);
var allMutants = mutator.mutate(input.filesToMutate);
var includedMutants = this.removeExcludedMutants(allMutants);
this.logMutantCount(includedMutants.length, allMutants.length);
var mutantRunResultMatcher = new MutantTestMatcher_1.default(includedMutants, inputFiles, initialTestRunResult.runResult, SourceMapper_1.default.create(initialTestRunResult.transpiledFiles, this.config), initialTestRunResult.coverageMaps, this.config, this.reporter);
var mutantRunResultMatcher = new MutantTestMatcher_1.default(includedMutants, input.filesToMutate, initialTestRunResult.runResult, initialTestRunResult.sourceMapper, initialTestRunResult.coverageMaps, this.config, this.reporter);
return mutantRunResultMatcher.matchWithMutants();

@@ -137,3 +137,10 @@ };

Stryker.prototype.freezeConfig = function () {
objectUtils_1.freezeRecursively(this.config);
// A config class instance is not serializable using surrial.
// This is a temporary work around
// See https://github.com/stryker-mutator/stryker/issues/365
var config = {};
for (var prop in this.config) {
config[prop] = this.config[prop];
}
this.config = objectUtils_1.freezeRecursively(config);
if (this.log.isDebugEnabled()) {

@@ -149,8 +156,2 @@ this.log.debug("Using config: " + JSON.stringify(this.config));

};
Stryker.prototype.createMutationTester = function (inputFiles) {
return new MutationTestExecutor_1.default(this.config, inputFiles, this.testFramework, this.reporter);
};
Stryker.prototype.createInitialTestRunProcess = function (inputFiles) {
return new InitialTestExecutor_1.default(this.config, inputFiles, this.testFramework, this.timer);
};
Stryker.prototype.reportScore = function (mutantResults) {

@@ -157,0 +158,0 @@ var calculator = new ScoreResultCalculator_1.default();

@@ -0,0 +0,0 @@ export default class StrykerCli {

@@ -0,0 +0,0 @@ "use strict";

@@ -9,3 +9,3 @@ import { Location } from 'stryker-api/core';

Failed = 0,
FailedButAlreadyReporter = 1,
FailedButAlreadyReported = 1,
Success = 2,

@@ -25,3 +25,2 @@ }

readonly fileName: string;
readonly included: boolean;
readonly mutatorName: string;

@@ -28,0 +27,0 @@ readonly range: [number, number];

@@ -8,3 +8,3 @@ "use strict";

TestSelectionResult[TestSelectionResult["Failed"] = 0] = "Failed";
TestSelectionResult[TestSelectionResult["FailedButAlreadyReporter"] = 1] = "FailedButAlreadyReporter";
TestSelectionResult[TestSelectionResult["FailedButAlreadyReported"] = 1] = "FailedButAlreadyReported";
TestSelectionResult[TestSelectionResult["Success"] = 2] = "Success";

@@ -43,9 +43,2 @@ })(TestSelectionResult = exports.TestSelectionResult || (exports.TestSelectionResult = {}));

});
Object.defineProperty(TestableMutant.prototype, "included", {
get: function () {
return this.sourceFile.file.included;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TestableMutant.prototype, "mutatorName", {

@@ -52,0 +45,0 @@ get: function () {

@@ -0,0 +0,0 @@ import { TestFramework } from 'stryker-api/test_framework';

@@ -0,0 +0,0 @@ "use strict";

import TestableMutant from './TestableMutant';
import { TranspileResult } from 'stryker-api/transpile';
import { File } from 'stryker-api/core';
import TranspileResult from './transpiler/TranspileResult';
export default class TranspiledMutant {

@@ -15,3 +14,2 @@ mutant: TestableMutant;

constructor(mutant: TestableMutant, transpileResult: TranspileResult, changedAnyTranspiledFiles: boolean);
static create(mutant: TestableMutant, transpileResult: TranspileResult, unMutatedFiles: File[]): TranspiledMutant;
}

@@ -15,17 +15,2 @@ "use strict";

}
TranspiledMutant.create = function (mutant, transpileResult, unMutatedFiles) {
return new TranspiledMutant(mutant, transpileResult, someFilesChanged());
function someFilesChanged() {
return transpileResult.outputFiles.some(function (file) { return fileChanged(file); });
}
function fileChanged(file) {
if (unMutatedFiles) {
var unMutatedFile = unMutatedFiles.find(function (f) { return f.name === file.name; });
return !unMutatedFile || unMutatedFile.content !== file.content;
}
else {
return true;
}
}
};
return TranspiledMutant;

@@ -32,0 +17,0 @@ }());

@@ -1,4 +0,3 @@

import { Transpiler, TranspileResult, TranspilerOptions } from 'stryker-api/transpile';
import { File } from 'stryker-api/core';
import { TestFramework } from 'stryker-api/test_framework';
import { Transpiler } from 'stryker-api/transpile';
import { StrykerOptions, File } from 'stryker-api/core';
import { Range } from 'istanbul-lib-coverage';

@@ -18,8 +17,7 @@ export interface CoverageMaps {

private settings;
private testFramework;
private filesToInstrument;
private instrumenter;
fileCoverageMaps: CoverageMapsByFile;
private log;
constructor(settings: TranspilerOptions, testFramework: TestFramework | null);
transpile(files: File[]): Promise<TranspileResult>;
constructor(settings: StrykerOptions, filesToInstrument: ReadonlyArray<string>);
transpile(files: ReadonlyArray<File>): Promise<ReadonlyArray<File>>;
/**

@@ -39,5 +37,2 @@ * Coverage variable *must* have the name '__coverage__'. Only that variable

private retrieveCoverageMaps(input);
private addCollectCoverageFileIfNeeded(result);
private coveragePerTestFileContent(testFramework);
private errorResult(error);
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var istanbul_lib_instrument_1 = require("istanbul-lib-instrument");
var core_1 = require("stryker-api/core");
var istanbul_lib_instrument_1 = require("istanbul-lib-instrument");
var objectUtils_1 = require("../utils/objectUtils");
var log4js_1 = require("log4js");
var COVERAGE_CURRENT_TEST_VARIABLE_NAME = '__strykerCoverageCurrentTest__';
var coverageHooks_1 = require("./coverageHooks");
var StrykerError_1 = require("../utils/StrykerError");
var CoverageInstrumenterTranspiler = /** @class */ (function () {
function CoverageInstrumenterTranspiler(settings, testFramework) {
function CoverageInstrumenterTranspiler(settings, filesToInstrument) {
this.settings = settings;
this.testFramework = testFramework;
this.filesToInstrument = filesToInstrument;
this.fileCoverageMaps = Object.create(null);
this.instrumenter = istanbul_lib_instrument_1.createInstrumenter({ coverageVariable: this.coverageVariable, preserveComments: true });
this.log = log4js_1.getLogger(CoverageInstrumenterTranspiler.name);
}
CoverageInstrumenterTranspiler.prototype.transpile = function (files) {
var _this = this;
try {
var result = {
outputFiles: files.map(function (file) { return _this.instrumentFileIfNeeded(file); }),
error: null
};
return Promise.resolve(this.addCollectCoverageFileIfNeeded(result));
}
catch (error) {
return Promise.resolve(this.errorResult(objectUtils_1.errorToString(error)));
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, files.map(function (file) { return _this.instrumentFileIfNeeded(file); })];
});
});
};

@@ -40,5 +34,5 @@ Object.defineProperty(CoverageInstrumenterTranspiler.prototype, "coverageVariable", {

get: function () {
switch (this.settings.config.coverageAnalysis) {
switch (this.settings.coverageAnalysis) {
case 'perTest':
return COVERAGE_CURRENT_TEST_VARIABLE_NAME;
return coverageHooks_1.COVERAGE_CURRENT_TEST_VARIABLE_NAME;
default:

@@ -71,3 +65,3 @@ return '__coverage__';

CoverageInstrumenterTranspiler.prototype.instrumentFileIfNeeded = function (file) {
if (this.settings.config.coverageAnalysis !== 'off' && file.kind === core_1.FileKind.Text && file.mutated) {
if (this.settings.coverageAnalysis !== 'off' && this.filesToInstrument.some(function (fileName) { return fileName === file.name; })) {
return this.instrumentFile(file);

@@ -81,16 +75,9 @@ }

try {
var content = this.instrumenter.instrumentSync(sourceFile.content, sourceFile.name);
var content = this.instrumenter.instrumentSync(sourceFile.textContent, sourceFile.name);
var fileCoverage = this.patchRanges(this.instrumenter.lastFileCoverage());
this.fileCoverageMaps[sourceFile.name] = this.retrieveCoverageMaps(fileCoverage);
return {
mutated: sourceFile.mutated,
included: sourceFile.included,
name: sourceFile.name,
transpiled: sourceFile.transpiled,
kind: core_1.FileKind.Text,
content: content
};
return new core_1.File(sourceFile.name, Buffer.from(content));
}
catch (error) {
throw new Error("Could not instrument \"" + sourceFile.name + "\" for code coverage. " + objectUtils_1.errorToString(error));
throw new StrykerError_1.default("Could not instrument \"" + sourceFile.name + "\" for code coverage", error);
}

@@ -106,39 +93,5 @@ };

};
CoverageInstrumenterTranspiler.prototype.addCollectCoverageFileIfNeeded = function (result) {
if (Object.keys(this.fileCoverageMaps).length && this.settings.config.coverageAnalysis === 'perTest') {
if (this.testFramework) {
// Add piece of javascript to collect coverage per test results
var content = this.coveragePerTestFileContent(this.testFramework);
var fileName = '____collectCoveragePerTest____.js';
result.outputFiles.unshift({
kind: core_1.FileKind.Text,
name: fileName,
included: true,
transpiled: false,
mutated: false,
content: content
});
this.log.debug("Adding test hooks file for coverageAnalysis \"perTest\": " + fileName);
}
else {
return this.errorResult('Cannot measure coverage results per test, there is no testFramework and thus no way of executing code right before and after each test.');
}
}
return result;
};
CoverageInstrumenterTranspiler.prototype.coveragePerTestFileContent = function (testFramework) {
return objectUtils_1.wrapInClosure("\n var id = 0, globalCoverage, coverageResult;\n window.__coverage__ = globalCoverage = { deviations: {} };\n " + testFramework.beforeEach(beforeEachFragmentPerTest) + "\n " + testFramework.afterEach(afterEachFragmentPerTest) + "\n " + cloneFunctionFragment + ";\n ");
};
CoverageInstrumenterTranspiler.prototype.errorResult = function (error) {
return {
error: error,
outputFiles: []
};
};
return CoverageInstrumenterTranspiler;
}());
exports.default = CoverageInstrumenterTranspiler;
var cloneFunctionFragment = " \nfunction clone(source) {\n var result = source;\n if (Array.isArray(source)) {\n result = [];\n source.forEach(function (child, index) {\n result[index] = clone(child);\n });\n } else if (typeof source == \"object\") {\n result = {};\n for (var i in source) {\n result[i] = clone(source[i]);\n }\n }\n return result;\n}";
var beforeEachFragmentPerTest = "\nif (!globalCoverage.baseline && window." + COVERAGE_CURRENT_TEST_VARIABLE_NAME + ") {\nglobalCoverage.baseline = clone(window." + COVERAGE_CURRENT_TEST_VARIABLE_NAME + ");\n}";
var afterEachFragmentPerTest = "\nglobalCoverage.deviations[id] = coverageResult = {};\nid++;\nvar coveragePerFile = window." + COVERAGE_CURRENT_TEST_VARIABLE_NAME + ";\nif(coveragePerFile) {\nObject.keys(coveragePerFile).forEach(function (file) {\n var coverage = coveragePerFile[file];\n var baseline = globalCoverage.baseline[file];\n var fileResult = { s: {}, f: {} };\n var touchedFile = false;\n for(var i in coverage.s){\n if(coverage.s[i] !== baseline.s[i]){\n fileResult.s[i] = coverage.s[i];\n touchedFile = true;\n }\n }\n for(var i in coverage.f){\n if(coverage.f[i] !== baseline.f[i]){\n fileResult.f[i] = coverage.f[i];\n touchedFile = true;\n }\n }\n if(touchedFile){\n coverageResult[file] = fileResult;\n }\n});\n}";
//# sourceMappingURL=CoverageInstrumenterTranspiler.js.map

@@ -5,3 +5,2 @@ import { Observable } from 'rxjs';

import { File } from 'stryker-api/core';
import { TranspileResult } from 'stryker-api/transpile';
import TranspiledMutant from '../TranspiledMutant';

@@ -19,6 +18,7 @@ export default class MutantTranspiler {

constructor(config: Config);
initialize(files: File[]): Promise<TranspileResult>;
initialize(files: ReadonlyArray<File>): Promise<ReadonlyArray<File>>;
transpileMutants(allMutants: TestableMutant[]): Observable<TranspiledMutant>;
dispose(): void;
private createTranspiledMutant(mutant, transpileResult, unMutatedFiles);
private transpileMutant(mutant);
}

@@ -8,2 +8,3 @@ "use strict";

var TranspiledMutant_1 = require("../TranspiledMutant");
var objectUtils_1 = require("../utils/objectUtils");
var MutantTranspiler = /** @class */ (function () {

@@ -27,5 +28,5 @@ /**

var _this = this;
return this.proxy.transpile(files).then(function (transpileResult) {
_this.unMutatedFiles = transpileResult.outputFiles;
return transpileResult;
return this.proxy.transpile(files).then(function (transpiledFiles) {
_this.unMutatedFiles = transpiledFiles;
return transpiledFiles;
});

@@ -41,3 +42,3 @@ };

_this.transpileMutant(mutant)
.then(function (transpileResult) { return observer.next(TranspiledMutant_1.default.create(mutant, transpileResult, _this.unMutatedFiles)); })
.then(function (transpiledFiles) { return observer.next(_this.createTranspiledMutant(mutant, transpiledFiles, _this.unMutatedFiles)); })
.then(nextMutant)

@@ -58,18 +59,28 @@ .catch(function (error) { return observer.error(error); });

};
MutantTranspiler.prototype.createTranspiledMutant = function (mutant, transpileResult, unMutatedFiles) {
return new TranspiledMutant_1.default(mutant, transpileResult, someFilesChanged());
function someFilesChanged() {
return transpileResult.outputFiles.some(function (file) { return fileChanged(file); });
}
function fileChanged(file) {
if (unMutatedFiles) {
var unMutatedFile = unMutatedFiles.find(function (f) { return f.name === file.name; });
return !unMutatedFile || unMutatedFile.textContent !== file.textContent;
}
else {
return true;
}
}
};
MutantTranspiler.prototype.transpileMutant = function (mutant) {
var filesToTranspile = [];
if (this.currentMutatedFile && this.currentMutatedFile.file.name !== mutant.fileName) {
if (this.currentMutatedFile && this.currentMutatedFile.name !== mutant.fileName) {
filesToTranspile.push(this.currentMutatedFile.file);
}
this.currentMutatedFile = mutant.sourceFile;
var mutatedFile = {
name: mutant.fileName,
content: mutant.mutatedCode,
kind: core_1.FileKind.Text,
mutated: this.currentMutatedFile.file.mutated,
transpiled: this.currentMutatedFile.file.transpiled,
included: mutant.included
};
var mutatedFile = new core_1.File(mutant.fileName, Buffer.from(mutant.mutatedCode));
filesToTranspile.push(mutatedFile);
return this.proxy.transpile(filesToTranspile);
return this.proxy.transpile(filesToTranspile)
.then(function (transpiledFiles) { return ({ outputFiles: transpiledFiles, error: null }); })
.catch(function (error) { return ({ outputFiles: [], error: objectUtils_1.errorToString(error) }); });
};

@@ -76,0 +87,0 @@ return MutantTranspiler;

import { File, Location } from 'stryker-api/core';
import { Config } from 'stryker-api/config';
import StrykerError from '../utils/StrykerError';
export interface MappedLocation {

@@ -7,4 +8,4 @@ fileName: string;

}
export declare class SourceMapError extends Error {
constructor(message: string);
export declare class SourceMapError extends StrykerError {
constructor(message: string, innerError?: Error);
}

@@ -22,3 +23,4 @@ /**

abstract transpiledLocationFor(originalLocation: MappedLocation): MappedLocation;
static create(transpiledFiles: File[], config: Config): SourceMapper;
abstract transpiledFileNameFor(originalFileName: string): string;
static create(transpiledFiles: ReadonlyArray<File>, config: Config): SourceMapper;
}

@@ -28,4 +30,9 @@ export declare class TranspiledSourceMapper extends SourceMapper {

private sourceMaps;
constructor(transpiledFiles: File[]);
private log;
constructor(transpiledFiles: ReadonlyArray<File>);
/**
* @inheritDoc
*/
transpiledFileNameFor(originalFileName: string): string;
/**
* @inheritdoc

@@ -43,2 +50,3 @@ */

private createSourceMaps();
private getRawSourceMap(sourceMapFile);
private getSourceMapForFile(transpiledFile);

@@ -69,3 +77,7 @@ /**

*/
transpiledFileNameFor(originalFileName: string): string;
/**
* @inheritdoc
*/
transpiledLocationFor(originalLocation: MappedLocation): MappedLocation;
}

@@ -8,7 +8,9 @@ "use strict";

var objectUtils_1 = require("../utils/objectUtils");
var log4js_1 = require("log4js");
var StrykerError_1 = require("../utils/StrykerError");
var SOURCE_MAP_URL_REGEX = /\/\/\s*#\s*sourceMappingURL=(.*)/g;
var SourceMapError = /** @class */ (function (_super) {
tslib_1.__extends(SourceMapError, _super);
function SourceMapError(message) {
var _this = _super.call(this, message + ". Cannot analyse code coverage. Setting `coverageAnalysis: \"off\"` in your stryker.conf.js will prevent this error, but forces Stryker to run each test for each mutant.") || this;
function SourceMapError(message, innerError) {
var _this = _super.call(this, message + ". Cannot analyse code coverage. Setting `coverageAnalysis: \"off\"` in your stryker.conf.js will prevent this error, but forces Stryker to run each test for each mutant.", innerError) || this;
Error.captureStackTrace(_this, SourceMapError);

@@ -20,3 +22,3 @@ // TS recommendation: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work

return SourceMapError;
}(Error));
}(StrykerError_1.default));
exports.SourceMapError = SourceMapError;

@@ -47,5 +49,13 @@ /**

_this.transpiledFiles = transpiledFiles;
_this.log = log4js_1.getLogger(SourceMapper.name);
return _this;
}
/**
* @inheritDoc
*/
TranspiledSourceMapper.prototype.transpiledFileNameFor = function (originalFileName) {
var sourceMap = this.getSourceMap(originalFileName);
return sourceMap.transpiledFile.name;
};
/**
* @inheritdoc

@@ -55,17 +65,12 @@ */

var sourceMap = this.getSourceMap(originalLocation.fileName);
if (!sourceMap) {
throw new SourceMapError("Source map not found for \"" + originalLocation.fileName + "\"");
}
else {
var relativeSource = this.getRelativeSource(sourceMap, originalLocation);
var start = sourceMap.generatedPositionFor(originalLocation.location.start, relativeSource);
var end = sourceMap.generatedPositionFor(originalLocation.location.end, relativeSource);
return {
fileName: sourceMap.transpiledFile.name,
location: {
start: start,
end: end
}
};
}
var relativeSource = this.getRelativeSource(sourceMap, originalLocation);
var start = sourceMap.generatedPositionFor(originalLocation.location.start, relativeSource);
var end = sourceMap.generatedPositionFor(originalLocation.location.end, relativeSource);
return {
fileName: sourceMap.transpiledFile.name,
location: {
start: start,
end: end
}
};
};

@@ -83,3 +88,9 @@ TranspiledSourceMapper.prototype.getRelativeSource = function (from, to) {

}
return this.sourceMaps[path.resolve(sourceFileName)];
var sourceMap = this.sourceMaps[path.resolve(sourceFileName)];
if (sourceMap) {
return sourceMap;
}
else {
throw new SourceMapError("Source map not found for \"" + sourceFileName + "\"");
}
};

@@ -93,8 +104,8 @@ /**

this.transpiledFiles.forEach(function (transpiledFile) {
if (transpiledFile.mutated && transpiledFile.kind === core_1.FileKind.Text) {
var sourceMapFile_1 = _this.getSourceMapForFile(transpiledFile);
var rawSourceMap = JSON.parse(sourceMapFile_1.content);
var sourceMap_1 = new SourceMap(transpiledFile, sourceMapFile_1.name, rawSourceMap);
var sourceMapFile = _this.getSourceMapForFile(transpiledFile);
if (sourceMapFile) {
var rawSourceMap = _this.getRawSourceMap(sourceMapFile);
var sourceMap_1 = new SourceMap(transpiledFile, sourceMapFile.name, rawSourceMap);
rawSourceMap.sources.forEach(function (source) {
var sourceFileName = path.resolve(path.dirname(sourceMapFile_1.name), source);
var sourceFileName = path.resolve(path.dirname(sourceMapFile.name), source);
sourceMaps[sourceFileName] = sourceMap_1;

@@ -106,6 +117,18 @@ });

};
TranspiledSourceMapper.prototype.getRawSourceMap = function (sourceMapFile) {
try {
return JSON.parse(sourceMapFile.textContent);
}
catch (error) {
throw new SourceMapError("Source map file \"" + sourceMapFile.name + "\" could not be parsed as json", error);
}
};
TranspiledSourceMapper.prototype.getSourceMapForFile = function (transpiledFile) {
var sourceMappingUrl = this.getSourceMapUrl(transpiledFile);
var sourceMapFile = this.getSourceMapFileFromUrl(sourceMappingUrl, transpiledFile);
return sourceMapFile;
if (sourceMappingUrl) {
return this.getSourceMapFileFromUrl(sourceMappingUrl, transpiledFile);
}
else {
return null;
}
};

@@ -120,8 +143,3 @@ /**

this.getInlineSourceMap(sourceMapUrl, transpiledFile) : this.getExternalSourceMap(sourceMapUrl, transpiledFile);
if (sourceMapFile.kind === core_1.FileKind.Text) {
return sourceMapFile;
}
else {
throw new SourceMapError("Source map file \"" + sourceMapFile.name + "\" has the wrong file kind. \"" + core_1.FileKind[sourceMapFile.kind] + "\" instead of \"" + core_1.FileKind[core_1.FileKind.Text] + "\"");
}
return sourceMapFile;
};

@@ -138,10 +156,3 @@ TranspiledSourceMapper.prototype.isInlineUrl = function (sourceMapUrl) {

var content = objectUtils_1.base64Decode(sourceMapUrl.substr(supportedDataPrefix.length));
return {
name: transpiledFile.name,
content: content,
kind: core_1.FileKind.Text,
included: false,
mutated: false,
transpiled: false
};
return new core_1.File(transpiledFile.name, content);
}

@@ -173,10 +184,12 @@ else {

// Retrieve the final sourceMappingURL comment in the file
while (currentMatch = SOURCE_MAP_URL_REGEX.exec(transpiledFile.content)) {
while (currentMatch = SOURCE_MAP_URL_REGEX.exec(transpiledFile.textContent)) {
lastMatch = currentMatch;
}
if (lastMatch) {
this.log.debug('Source map url found in transpiled file "%s"', transpiledFile.name);
return lastMatch[1];
}
else {
throw new SourceMapError("No source map reference found in transpiled file \"" + transpiledFile.name + "\"");
this.log.debug('No source map url found in transpiled file "%s"', transpiledFile.name);
return null;
}

@@ -195,2 +208,8 @@ };

*/
PassThroughSourceMapper.prototype.transpiledFileNameFor = function (originalFileName) {
return originalFileName;
};
/**
* @inheritdoc
*/
PassThroughSourceMapper.prototype.transpiledLocationFor = function (originalLocation) {

@@ -197,0 +216,0 @@ return originalLocation;

import { File } from 'stryker-api/core';
import { Transpiler, TranspileResult, TranspilerOptions } from 'stryker-api/transpile';
import { Transpiler, TranspilerOptions } from 'stryker-api/transpile';
export default class TranspilerFacade implements Transpiler {
private innerTranspilers;
constructor(options: TranspilerOptions, additionalTranspiler?: {
name: string;
transpiler: Transpiler;
});
transpile(files: File[]): Promise<TranspileResult>;
private performTranspileChain(currentResult, remainingChain?);
private createPassThruTranspileResult(input);
constructor(options: TranspilerOptions);
transpile(files: ReadonlyArray<File>): Promise<ReadonlyArray<File>>;
private performTranspileChain(input, remainingChain?);
}

@@ -5,2 +5,3 @@ "use strict";

var transpile_1 = require("stryker-api/transpile");
var StrykerError_1 = require("../utils/StrykerError");
var NamedTranspiler = /** @class */ (function () {

@@ -14,34 +15,26 @@ function NamedTranspiler(name, transpiler) {

var TranspilerFacade = /** @class */ (function () {
function TranspilerFacade(options, additionalTranspiler) {
function TranspilerFacade(options) {
this.innerTranspilers = options.config.transpilers
.map(function (transpilerName) { return new NamedTranspiler(transpilerName, transpile_1.TranspilerFactory.instance().create(transpilerName, options)); });
if (additionalTranspiler) {
this.innerTranspilers.push(new NamedTranspiler(additionalTranspiler.name, additionalTranspiler.transpiler));
}
}
TranspilerFacade.prototype.transpile = function (files) {
return this.performTranspileChain(this.createPassThruTranspileResult(files));
return this.performTranspileChain(files);
};
TranspilerFacade.prototype.performTranspileChain = function (currentResult, remainingChain) {
TranspilerFacade.prototype.performTranspileChain = function (input, remainingChain) {
if (remainingChain === void 0) { remainingChain = this.innerTranspilers.slice(); }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var next, nextResult;
var current, output;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
next = remainingChain.shift();
if (!next) return [3 /*break*/, 2];
return [4 /*yield*/, next.transpiler.transpile(currentResult.outputFiles)];
current = remainingChain.shift();
if (!current) return [3 /*break*/, 2];
return [4 /*yield*/, current.transpiler.transpile(input)
.catch(function (error) {
throw new StrykerError_1.default("An error occurred in transpiler \"" + current.name + "\"", error);
})];
case 1:
nextResult = _a.sent();
if (nextResult.error) {
nextResult.error = "Execute " + next.name + ": " + nextResult.error;
return [2 /*return*/, nextResult];
}
else {
return [2 /*return*/, this.performTranspileChain(nextResult, remainingChain)];
}
return [3 /*break*/, 3];
case 2: return [2 /*return*/, currentResult];
case 3: return [2 /*return*/];
output = _a.sent();
return [2 /*return*/, this.performTranspileChain(output, remainingChain)];
case 2: return [2 /*return*/, input];
}

@@ -51,8 +44,2 @@ });

};
TranspilerFacade.prototype.createPassThruTranspileResult = function (input) {
return {
error: null,
outputFiles: input
};
};
return TranspilerFacade;

@@ -59,0 +46,0 @@ }());

/// <reference types="node" />
import { FileKind } from 'stryker-api/core';
export declare function glob(expression: string): Promise<string[]>;

@@ -10,3 +9,2 @@ export declare function deleteDir(dirToDelete: string): Promise<void>;

export declare function importModule(moduleName: string): void;
export declare function isOnlineFile(path: string): boolean;
/**

@@ -19,2 +17,1 @@ * Writes data to a specified file.

export declare function writeFile(fileName: string, data: string | Buffer): Promise<void>;
export declare function determineFileKind(fileName: string): FileKind;

@@ -5,7 +5,5 @@ "use strict";

var fs = require("mz/fs");
var path = require("path");
var nodeGlob = require("glob");
var mkdirp = require("mkdirp");
var rimraf = require("rimraf");
var core_1 = require("stryker-api/core");
function glob(expression) {

@@ -53,17 +51,2 @@ return new Promise(function (resolve, reject) {

exports.importModule = importModule;
function isOnlineFile(path) {
return path.indexOf('http://') === 0 || path.indexOf('https://') === 0;
}
exports.isOnlineFile = isOnlineFile;
var binaryExtensions = [
'.png',
'.jpeg',
'.jpg',
'.zip',
'.tar',
'.gif' // Still more to add
];
function isBinaryFile(name) {
return binaryExtensions.indexOf(path.extname(name)) > -1;
}
/**

@@ -84,14 +67,2 @@ * Writes data to a specified file.

exports.writeFile = writeFile;
function determineFileKind(fileName) {
if (isOnlineFile(fileName)) {
return core_1.FileKind.Web;
}
if (isBinaryFile(fileName)) {
return core_1.FileKind.Binary;
}
else {
return core_1.FileKind.Text;
}
}
exports.determineFileKind = determineFileKind;
//# sourceMappingURL=fileUtils.js.map

@@ -0,0 +0,0 @@ import { Location } from 'stryker-api/core';

@@ -0,0 +0,0 @@ "use strict";

/// <reference types="node" />
export { serialize, deserialize } from 'surrial';
export declare function freezeRecursively<T extends {

@@ -7,11 +8,2 @@ [prop: string]: any;

export declare function filterEmpty<T>(input: (T | null | void)[]): T[];
/**
* Serializes javascript without using `JSON.stringify` (directly), as it does not allow for regexes or functions, etc
*/
export declare const serialize: (obj: any) => string;
/**
* Deserialize javascript without using `JSON.parse` (directly), as it does not allow for regexes or functions, etc
* (Uses eval instead)
*/
export declare function deserialize(serializedJavascript: String): any;
export declare function isErrnoException(error: Error): error is NodeJS.ErrnoException;

@@ -30,1 +22,6 @@ export declare function errorToString(error: any): any;

export declare function base64Decode(base64EncodedString: string): string;
/**
* Consolidates multiple consecutive white spaces into a single space.
* @param str The string to be normalized
*/
export declare function normalizeWhiteSpaces(str: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _ = require("lodash");
var surrial_1 = require("surrial");
exports.serialize = surrial_1.serialize;
exports.deserialize = surrial_1.deserialize;
function freezeRecursively(target) {

@@ -22,16 +25,2 @@ Object.freeze(target);

exports.filterEmpty = filterEmpty;
/**
* Serializes javascript without using `JSON.stringify` (directly), as it does not allow for regexes or functions, etc
*/
exports.serialize = require('serialize-javascript');
/**
* Deserialize javascript without using `JSON.parse` (directly), as it does not allow for regexes or functions, etc
* (Uses eval instead)
*/
function deserialize(serializedJavascript) {
// tslint:disable
return eval("(" + serializedJavascript + ")");
// tslint:enable
}
exports.deserialize = deserialize;
function isErrnoException(error) {

@@ -93,2 +82,10 @@ return typeof error.code === 'string';

exports.base64Decode = base64Decode;
/**
* Consolidates multiple consecutive white spaces into a single space.
* @param str The string to be normalized
*/
function normalizeWhiteSpaces(str) {
return str.replace(/\s+/g, ' ').trim();
}
exports.normalizeWhiteSpaces = normalizeWhiteSpaces;
//# sourceMappingURL=objectUtils.js.map

@@ -0,0 +0,0 @@ import * as estree from 'estree';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ /**

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export default class Timer {

@@ -0,0 +0,0 @@ "use strict";

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc