diff --git a/package.json b/package.json index ba9bf162cc..98b4be32f6 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,6 @@ "devDependencies": { "@types/chai": "4.1.7", "@types/chai-as-promised": "7.1.0", - "@types/escodegen": "0.0.6", - "@types/esprima": "^2.1.31", - "@types/estree": "0.0.38", "@types/execa": "^0.9.0", "@types/glob": "^7.1.0", "@types/istanbul": "^0.4.29", diff --git a/packages/stryker-api/src/config/Config.ts b/packages/stryker-api/src/config/Config.ts index b7a6e9ad0a..b853cb4a60 100644 --- a/packages/stryker-api/src/config/Config.ts +++ b/packages/stryker-api/src/config/Config.ts @@ -22,7 +22,7 @@ export default class Config implements StrykerOptions { public coverageAnalysis: 'perTest' | 'all' | 'off' = 'off'; public testRunner: string = 'command'; public testFramework: string; - public mutator: string | MutatorDescriptor = 'es5'; + public mutator: string | MutatorDescriptor = 'javascript'; public transpilers: string[] = []; public maxConcurrentTestRunners: number = Infinity; public symlinkNodeModules: boolean = true; diff --git a/packages/stryker-vue-mutator/src/helpers/MutatorHelpers.ts b/packages/stryker-vue-mutator/src/helpers/MutatorHelpers.ts index ba0c664959..d87d8f1760 100644 --- a/packages/stryker-vue-mutator/src/helpers/MutatorHelpers.ts +++ b/packages/stryker-vue-mutator/src/helpers/MutatorHelpers.ts @@ -8,7 +8,7 @@ export function mutatorsFactory(pluginResolver: PluginResolver, injector: Inject const mutators: { [name: string]: Mutator; } = {}; const mutatorPlugins = pluginResolver.resolveAll(PluginKind.Mutator); mutatorPlugins.forEach(plugin => { - if (plugin.name !== 'es5' && plugin.name !== 'vue') { + if (plugin.name !== 'vue') { mutators[plugin.name] = createPlugin(injector, plugin); } }); diff --git a/packages/stryker/README.md b/packages/stryker/README.md index f5c241eaea..ab0b7c76c4 100644 --- a/packages/stryker/README.md +++ b/packages/stryker/README.md @@ -152,13 +152,13 @@ In addition to requiring your test runner to be able to report the code coverage (`Mocha` is not yet supported). ### `mutator` [`object` | `string`] -Default: `es5` -Command line: `--mutator es5` -Config file: `mutator: 'es5'` or `mutator: { name: 'es5', excludedMutations: ['BooleanSubstitution', 'StringLiteral'] }` +Default: `javascript` +Command line: `--mutator javascript` +Config file: `mutator: 'javascript'` or `mutator: { name: 'javascript', excludedMutations: ['BooleanSubstitution', 'StringLiteral'] }` With `mutator` you configure which mutator plugin you want to use, and optionally, which mutation types to exclude from the test run. -The mutator plugin name defaults to `es5` if not specified. The list of excluded mutation types defaults to an empty array, meaning all mutation types will be included in the test. -The full list of mutation types varies slightly between mutators (for example, the `es5` mutator will not use the same mutation types as the `typescript` mutator). Mutation type names are case-sensitive, and can be found either in the source code or in a generated Stryker report. +The mutator plugin name defaults to `javascript` if not specified. Note: this requires you to have the `@stryker-mutator/javascript-mutator` plugin installed. The list of excluded mutation types defaults to an empty array, meaning all mutation types will be included in the test. +The full list of mutation types varies slightly between mutators (for example, the `javascript` mutator will not use the same mutation types as the `typescript` mutator). Mutation type names are case-sensitive, and can be found either in the source code or in a generated Stryker report. When using the command line, only the mutator name as a string may be provided. When using the config file, you can provide either a string representing the mutator name, or a `MutatorDescriptor` object, like so: diff --git a/packages/stryker/package.json b/packages/stryker/package.json index 0dbe7649c1..9c7e8ccbb8 100644 --- a/packages/stryker/package.json +++ b/packages/stryker/package.json @@ -55,8 +55,6 @@ "@stryker-mutator/util": "^0.1.0", "chalk": "~2.4.1", "commander": "~2.19.0", - "escodegen": "~1.8.0", - "esprima": "~2.7.0", "get-port": "~4.1.0", "glob": "~7.1.2", "inquirer": "~6.2.0", diff --git a/packages/stryker/src/di/buildMainInjector.ts b/packages/stryker/src/di/buildMainInjector.ts index 93b06e2d0f..0d73563cf5 100644 --- a/packages/stryker/src/di/buildMainInjector.ts +++ b/packages/stryker/src/di/buildMainInjector.ts @@ -45,8 +45,7 @@ export function buildMainInjector(cliOptions: Partial): Injector function pluginDescriptorsFactory(config: Config): ReadonlyArray { config.plugins.push( - require.resolve('../reporters'), - require.resolve('../mutators') + require.resolve('../reporters') ); return config.plugins; } diff --git a/packages/stryker/src/mutators/ArrayDeclaratorMutator.ts b/packages/stryker/src/mutators/ArrayDeclaratorMutator.ts deleted file mode 100644 index 51756dfcff..0000000000 --- a/packages/stryker/src/mutators/ArrayDeclaratorMutator.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Syntax } from 'esprima'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -/** - * Represents a mutator which can remove the content of an array's elements. - */ -export default class ArrayDeclaratorMutator implements NodeMutator { - public name = 'ArrayDeclarator'; - - constructor() { } - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): void | IdentifiedNode { - if ((node.type === Syntax.CallExpression || node.type === Syntax.NewExpression) && node.callee.type === Syntax.Identifier && node.callee.name === 'Array' && node.arguments.length > 0) { - const mutatedNode = copy(node); - mutatedNode.arguments = []; - return mutatedNode; - } - - if (node.type === Syntax.ArrayExpression && node.elements.length > 0) { - const mutatedNode = copy(node); - mutatedNode.elements = []; - return mutatedNode; - } - } -} diff --git a/packages/stryker/src/mutators/BinaryOperatorMutator.ts b/packages/stryker/src/mutators/BinaryOperatorMutator.ts deleted file mode 100644 index b1ac7e966a..0000000000 --- a/packages/stryker/src/mutators/BinaryOperatorMutator.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -export default class BinaryOperatorMutator implements NodeMutator { - public name = 'BinaryOperator'; - private readonly type = Syntax.BinaryExpression; - private readonly operators: { [targetedOperator: string]: estree.BinaryOperator | estree.BinaryOperator[] } = { - '!=': '==', - '!==': '===', - '%': '*', - '*': '/', - '+': '-', - '-': '+', - '/': '*', - '<': ['<=', '>='], - '<=': ['<', '>'], - '==': '!=', - '===': '!==', - '>': ['>=', '<='], - '>=': ['>', '<'] - }; - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): IdentifiedNode[] { - const nodes: IdentifiedNode[] = []; - - if (node.type === this.type && this.operators[node.operator]) { - const binaryNode = node; - let mutatedOperators = this.operators[node.operator]; - if (typeof mutatedOperators === 'string') { - mutatedOperators = [mutatedOperators]; - } - mutatedOperators.forEach(operator => { - const mutatedNode = copy(binaryNode); - mutatedNode.operator = operator; - nodes.push(mutatedNode); - }); - } - return nodes; - } -} diff --git a/packages/stryker/src/mutators/BlockStatementMutator.ts b/packages/stryker/src/mutators/BlockStatementMutator.ts deleted file mode 100644 index a81ff038e9..0000000000 --- a/packages/stryker/src/mutators/BlockStatementMutator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Syntax } from 'esprima'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -/** - * Represents a mutator which can remove the content of a BlockStatement. - */ -export default class BlockStatementMutator implements NodeMutator { - public name = 'BlockStatement'; - private readonly type = Syntax.BlockStatement; - - constructor() { } - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): void | IdentifiedNode { - if (node.type === this.type && node.body.length > 0) { - const mutatedNode = copy(node); - mutatedNode.body = []; - return mutatedNode; - } - } -} diff --git a/packages/stryker/src/mutators/BooleanSubstitutionMutator.ts b/packages/stryker/src/mutators/BooleanSubstitutionMutator.ts deleted file mode 100644 index 868c8c948d..0000000000 --- a/packages/stryker/src/mutators/BooleanSubstitutionMutator.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Syntax } from 'esprima'; -import { Expression } from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode, Identified } from './IdentifiedNode'; - -export default class BooleanSubstitutionMutator implements NodeMutator { - public name = 'BooleanSubstitution'; - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): IdentifiedNode[] { - const nodes: IdentifiedNode[] = []; - - // !a -> a - if (node.type === Syntax.UnaryExpression && node.operator === '!') { - const mutatedNode = copy(node.argument as Expression & Identified) as IdentifiedNode; - mutatedNode.nodeID = node.nodeID; - nodes.push(mutatedNode); - } - - // true -> false or false -> true - if (node.type === Syntax.Literal && typeof node.value === 'boolean') { - const mutatedNode = copy(node); - mutatedNode.value = !mutatedNode.value; - nodes.push(mutatedNode); - } - return nodes; - } - -} diff --git a/packages/stryker/src/mutators/ES5Mutator.ts b/packages/stryker/src/mutators/ES5Mutator.ts deleted file mode 100644 index f0bc4eadc6..0000000000 --- a/packages/stryker/src/mutators/ES5Mutator.ts +++ /dev/null @@ -1,80 +0,0 @@ -import * as _ from 'lodash'; -import { Logger } from 'stryker-api/logging'; -import { File } from 'stryker-api/core'; -import { Mutator, Mutant } from 'stryker-api/mutant'; -import * as parserUtils from '../utils/parserUtils'; -import { copy } from '../utils/objectUtils'; -import NodeMutator from './NodeMutator'; -import BinaryOperatorMutator from './BinaryOperatorMutator'; -import BlockStatementMutator from './BlockStatementMutator'; -import LogicalOperatorMutator from './LogicalOperatorMutator'; -import RemoveConditionalsMutator from './RemoveConditionalsMutator'; -import UnaryOperatorMutator from './UnaryOperatorMutator'; -import UpdateOperatorMutator from './UpdateOperatorMutator'; -import ArrayDeclaratorMutator from './ArrayDeclaratorMutator'; -import BooleanSubstitutionMutator from './BooleanSubstitutionMutator'; -import { tokens } from 'typed-inject'; -import { commonTokens } from 'stryker-api/plugin'; - -export default class ES5Mutator implements Mutator { - - public static inject = tokens(commonTokens.logger); - constructor( - private readonly log: Logger, - private readonly mutators: NodeMutator[] = [ - new BinaryOperatorMutator(), - new BlockStatementMutator(), - new LogicalOperatorMutator(), - new RemoveConditionalsMutator(), - new UnaryOperatorMutator(), - new UpdateOperatorMutator(), - new ArrayDeclaratorMutator(), - new BooleanSubstitutionMutator() - ]) { - this.log.warn(`DEPRECATED: The es5 mutator is deprecated and will be removed in the future. Please upgrade to the stryker-javascript-mutator (npm install --save-dev stryker-javascript-mutator) and set "mutator: 'javascript'" in your stryker.conf.js! If you have a plugins array in your stryker.conf.js, be sure to add 'stryker-javascript-mutator'.`); - } - - public mutate(files: File[]): Mutant[] { - return _.flatMap(files, file => this.mutateForFile(file)); - } - - private mutateForFile(file: File): Mutant[] { - const abstractSyntaxTree = parserUtils.parse(file.textContent); - const nodes = new parserUtils.NodeIdentifier().identifyAndFreeze(abstractSyntaxTree); - return this.mutateForNodes(file, nodes); - } - - private mutateForNodes(file: File, nodes: any[]): Mutant[] { - return _.flatMap(nodes, astNode => { - if (astNode.type) { - Object.freeze(astNode); - return _.flatMap(this.mutators, mutator => { - try { - let mutatedNodes = mutator.applyMutations(astNode, copy); - if (mutatedNodes) { - if (!Array.isArray(mutatedNodes)) { - mutatedNodes = [mutatedNodes]; - } - 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 ${file.name}`); - } - return mutatedNodes.map(mutatedNode => { - const replacement = parserUtils.generate(mutatedNode); - const originalNode = nodes[mutatedNode.nodeID]; - const mutant: Mutant = { mutatorName: mutator.name, fileName: file.name, replacement, range: originalNode.range }; - return mutant; - }); - } else { - return []; - } - } catch (error) { - throw new Error(`The mutator named '${mutator.name}' caused an error: ${error}`); - } - }); - } else { - return []; - } - }); - } - -} diff --git a/packages/stryker/src/mutators/IdentifiedNode.ts b/packages/stryker/src/mutators/IdentifiedNode.ts deleted file mode 100644 index 8af296c604..0000000000 --- a/packages/stryker/src/mutators/IdentifiedNode.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Node } from 'estree'; - -export interface Identified { - nodeID: number; -} - -export type IdentifiedNode = Node & Identified; diff --git a/packages/stryker/src/mutators/LogicalOperatorMutator.ts b/packages/stryker/src/mutators/LogicalOperatorMutator.ts deleted file mode 100644 index 2a1ce0c74a..0000000000 --- a/packages/stryker/src/mutators/LogicalOperatorMutator.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -export default class LogicalOperatorMutator implements NodeMutator { - public name = 'LogicalOperator'; - private readonly type = Syntax.LogicalExpression; - private readonly operators: { [targetedOperator: string]: estree.LogicalOperator } = { - '&&': '||', - '||': '&&' - }; - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): IdentifiedNode[] { - const nodes: IdentifiedNode[] = []; - - if (node.type === this.type && this.operators[node.operator]) { - const mutatedNode = copy(node); - mutatedNode.operator = this.operators[node.operator]; - nodes.push(mutatedNode); - } - - return nodes; - } - -} diff --git a/packages/stryker/src/mutators/NodeMutator.ts b/packages/stryker/src/mutators/NodeMutator.ts deleted file mode 100644 index 6348e534e4..0000000000 --- a/packages/stryker/src/mutators/NodeMutator.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IdentifiedNode } from './IdentifiedNode'; - -export default interface NodeMutator { - applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): void | IdentifiedNode | IdentifiedNode[]; - name: string; -} diff --git a/packages/stryker/src/mutators/RemoveConditionalsMutator.ts b/packages/stryker/src/mutators/RemoveConditionalsMutator.ts deleted file mode 100644 index 8039a9481c..0000000000 --- a/packages/stryker/src/mutators/RemoveConditionalsMutator.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode, Identified } from './IdentifiedNode'; - -type ConditionExpression = estree.DoWhileStatement | estree.IfStatement | estree.ForStatement | estree.WhileStatement | estree.ConditionalExpression; - -/** - * Represents a mutator which can remove the conditional clause from statements. - */ -export default class RemoveConditionalsMutator implements NodeMutator { - public name = 'RemoveConditionals'; - private readonly types: string[] = [Syntax.DoWhileStatement, Syntax.IfStatement, Syntax.ForStatement, Syntax.WhileStatement, Syntax.ConditionalExpression]; - - constructor() { } - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): IdentifiedNode[] | void { - if (this.canMutate(node)) { - const nodes: IdentifiedNode[] = []; - - if (node.test) { - nodes.push(this.booleanLiteralNode((node.test as IdentifiedNode).nodeID, false)); - } else { - const mutatedNode = copy(node); - mutatedNode.test = this.booleanLiteralNode(-1, false); - nodes.push(mutatedNode); - } - - if (node.type === Syntax.IfStatement || node.type === Syntax.ConditionalExpression) { - nodes.push(this.booleanLiteralNode((node.test as IdentifiedNode).nodeID, true)); - } - return nodes; - } - } - - private booleanLiteralNode(nodeID: number, value: boolean): estree.SimpleLiteral & Identified { - return { - nodeID, - raw: value.toString(), - type: Syntax.Literal, - value - }; - } - - private canMutate(node: estree.Node): node is ConditionExpression { - return this.types.indexOf(node.type) >= 0; - } - -} diff --git a/packages/stryker/src/mutators/UnaryOperatorMutator.ts b/packages/stryker/src/mutators/UnaryOperatorMutator.ts deleted file mode 100644 index ea324b5c33..0000000000 --- a/packages/stryker/src/mutators/UnaryOperatorMutator.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -export default class UnaryOperatorMutator implements NodeMutator { - public name = 'UnaryOperator'; - private readonly type = Syntax.UnaryExpression; - private readonly operators: { [targetedOperator: string]: estree.UnaryOperator } = { - '+': '-', - '-': '+' - }; - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): IdentifiedNode[] { - const nodes: IdentifiedNode[] = []; - - if (node.type === this.type && this.operators[node.operator]) { - const mutatedNode = copy(node); - mutatedNode.operator = this.operators[node.operator]; - nodes.push(mutatedNode); - } - - return nodes; - } -} diff --git a/packages/stryker/src/mutators/UpdateOperatorMutator.ts b/packages/stryker/src/mutators/UpdateOperatorMutator.ts deleted file mode 100644 index 94985bbc37..0000000000 --- a/packages/stryker/src/mutators/UpdateOperatorMutator.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import NodeMutator from './NodeMutator'; -import { IdentifiedNode } from './IdentifiedNode'; - -export default class UpdateOperatorMutator implements NodeMutator { - public name = 'UpdateOperator'; - private readonly type = Syntax.UpdateExpression; - private readonly operators: { [targetedOperator: string]: estree.UpdateOperator } = { - '++': '--', - '--': '++' - }; - - public applyMutations(node: IdentifiedNode, copy: (obj: T, deep?: boolean) => T): void | IdentifiedNode { - if (node.type === this.type && this.operators[node.operator]) { - const mutatedNode = copy(node); - mutatedNode.operator = this.operators[node.operator]; - return mutatedNode; - } - } -} diff --git a/packages/stryker/src/mutators/index.ts b/packages/stryker/src/mutators/index.ts deleted file mode 100644 index f1d09b8c12..0000000000 --- a/packages/stryker/src/mutators/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import ES5Mutator from './ES5Mutator'; -import { declareClassPlugin, PluginKind } from 'stryker-api/plugin'; - -export const strykerPlugins = [ - declareClassPlugin(PluginKind.Mutator, 'es5', ES5Mutator) -]; diff --git a/packages/stryker/src/utils/parserUtils.ts b/packages/stryker/src/utils/parserUtils.ts deleted file mode 100644 index 0a6a540ec5..0000000000 --- a/packages/stryker/src/utils/parserUtils.ts +++ /dev/null @@ -1,96 +0,0 @@ -import * as _ from 'lodash'; -import * as esprima from 'esprima'; -import * as estree from 'estree'; -import { Identified, IdentifiedNode } from '../mutators/IdentifiedNode'; -import * as escodegen from 'escodegen'; - -/** - * Utility class for parsing and generating code. - * @constructor - */ -const esprimaOptions = { - comment: true, - loc: true, - range: true, - tokens: true, -}; - -/** - * Parses code to generate an Abstract Syntax Tree. - * @function - * @param code - The code which has to be parsed. - * @returns {Object} The generated Abstract Syntax Tree. - */ -export function parse(code: string): estree.Program { - if (code === undefined) { - throw new Error('Code parameter cannot be undefined'); - } - - const abstractSyntaxTree = esprima.parse(code, esprimaOptions); - - return abstractSyntaxTree; -} - -/** - * Parses a Node to generate code. - * @param The Node which has to be transformed into code. - * @returns The generated code. - */ -export function generate(node: estree.Node): string { - return escodegen.generate(node); -} - -/** - * Returns n as T & Identified, purely syntactic. - * @param n The estree node which is identified - */ -export function identified(n: T) { - return n as T & Identified; -} - -/** - * Represents an object responsible to identify estree nodes (estree.Node). - * Labels all nodes with a `nodeID` recursively. - */ -export class NodeIdentifier { - - private identifiedNodes: Readonly[] = []; - - public identifyAndFreeze(program: estree.Program): Readonly[] { - this.identifiedNodes = []; - this.identifyAndFreezeRecursively(program); - return this.identifiedNodes; - } - - private identifyAndFreezeRecursively(maybeNode: any) { - if (this.isNode(maybeNode)) { - if (!this.isIdentified(maybeNode)) { - this.identify(maybeNode); - } - Object.freeze(maybeNode); - - _.forOwn(maybeNode, childNode => { - this.identifyAndFreezeRecursively(childNode); - }); - } else if (Array.isArray(maybeNode)) { - maybeNode.forEach(grandChild => { - this.identifyAndFreezeRecursively(grandChild); - }); - } - } - - private isNode(maybeNode: any): estree.Node { - return !_.isArray(maybeNode) && _.isObject(maybeNode) && maybeNode.type; - } - - private isIdentified(node: estree.Node): node is IdentifiedNode { - const n = node as IdentifiedNode; - return _.isNumber(n.nodeID); - } - - private identify(node: estree.Node) { - const n = node as IdentifiedNode; - n.nodeID = this.identifiedNodes.length; - this.identifiedNodes.push(n); - } -} diff --git a/packages/stryker/stryker.conf.js b/packages/stryker/stryker.conf.js index b1826a2c29..bd5cf731c9 100644 --- a/packages/stryker/stryker.conf.js +++ b/packages/stryker/stryker.conf.js @@ -1,6 +1,5 @@ module.exports = function (config) { - var typescript = true; - var es6 = true; + var typescript = true; if (typescript) { config.set({ files: [ @@ -35,7 +34,7 @@ module.exports = function (config) { { pattern: 'node_modules/stryker-api/src/**/*.js', included: false, mutated: false } ], coverageAnalysis: 'perTest', - mutator: es6 ? 'javascript' : 'es5' + mutator: 'javascript' }); } config.set({ diff --git a/packages/stryker/test/unit/config/ConfigValidatorSpec.ts b/packages/stryker/test/unit/config/ConfigValidatorSpec.ts index 342b859e1e..378b69801d 100644 --- a/packages/stryker/test/unit/config/ConfigValidatorSpec.ts +++ b/packages/stryker/test/unit/config/ConfigValidatorSpec.ts @@ -115,7 +115,7 @@ describe('ConfigValidator', () => { it('should be valid with string mutator name and string array excluded mutations', () => { breakConfig('mutator', { excludedMutations: ['BooleanSubstitution'], - name: 'es5' + name: 'javascript' }); sut.validate(); expect(testInjector.logger.fatal).not.called; @@ -133,7 +133,7 @@ describe('ConfigValidator', () => { it('should be invalid with non-array excluded mutations', () => { breakConfig('mutator', { excludedMutations: 'BooleanSubstitution', - name: 'es5' + name: 'javascript' }); actValidationError(); expect(testInjector.logger.fatal).calledWith('Value "BooleanSubstitution" is invalid for `mutator.excludedMutations`. Expected an array'); @@ -142,7 +142,7 @@ describe('ConfigValidator', () => { it('should be invalid with non-string excluded mutation array elements', () => { breakConfig('mutator', { excludedMutations: ['BooleanSubstitution', 0], - name: 'es5' + name: 'javascript' }); actValidationError(); expect(testInjector.logger.fatal).calledWith('Value "0" is an invalid element of `mutator.excludedMutations`. Expected a string'); diff --git a/packages/stryker/test/unit/di/buildMainInjector.spec.ts b/packages/stryker/test/unit/di/buildMainInjector.spec.ts index a4fe16e8bb..970c324f54 100644 --- a/packages/stryker/test/unit/di/buildMainInjector.spec.ts +++ b/packages/stryker/test/unit/di/buildMainInjector.spec.ts @@ -65,7 +65,7 @@ describe(buildMainInjector.name, () => { it('should load default plugins', () => { buildMainInjector({}).resolve(commonTokens.config); expect(di.PluginLoader).calledWithNew; - expect(di.PluginLoader).calledWith(currentLogMock(), ['stryker-*', require.resolve('../../../src/reporters'), require.resolve('../../../src/mutators')]); + expect(di.PluginLoader).calledWith(currentLogMock(), ['stryker-*', require.resolve('../../../src/reporters')]); }); it('should load plugins', () => { diff --git a/packages/stryker/test/unit/mutants/MutatorFacadeSpec.ts b/packages/stryker/test/unit/mutants/MutatorFacadeSpec.ts index bff63c8db2..f0a01f99bb 100644 --- a/packages/stryker/test/unit/mutants/MutatorFacadeSpec.ts +++ b/packages/stryker/test/unit/mutants/MutatorFacadeSpec.ts @@ -57,7 +57,7 @@ describe('MutatorFacade', () => { ]); testInjector.options.mutator = { excludedMutations: ['foo'], - name: 'es5' + name: 'javascript' }; createSut().mutate([]); expect(testInjector.logger.info).calledWith('2 Mutant(s) generated (1 Mutant(s) excluded)'); @@ -71,7 +71,7 @@ describe('MutatorFacade', () => { ]); testInjector.options.mutator = { excludedMutations: ['foo', 'bar', 'baz'], - name: 'es5' + name: 'javascript' }; createSut().mutate([]); expect(testInjector.logger.info).calledWith('It\'s a mutant-free world, nothing to test. (3 Mutant(s) excluded)'); diff --git a/packages/stryker/test/unit/mutators/ArrayDeclaratorMutatorSpec.ts b/packages/stryker/test/unit/mutators/ArrayDeclaratorMutatorSpec.ts deleted file mode 100644 index 989096440c..0000000000 --- a/packages/stryker/test/unit/mutators/ArrayDeclaratorMutatorSpec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { expect } from 'chai'; -import * as estree from 'estree'; -import { Identified } from '../../../src/mutators/IdentifiedNode'; -import ArrayDeclaratorMutator from '../../../src/mutators/ArrayDeclaratorMutator'; -import * as parser from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; - -describe('ArrayDeclaratorMutator', () => { - let sut: ArrayDeclaratorMutator; - - beforeEach(() => sut = new ArrayDeclaratorMutator()); - - const getVariableDeclaration = (program: estree.Program) => (program.body[0] as estree.VariableDeclaration); - - const getArrayExpression = (program: estree.Program) => { - const variableDeclaration = getVariableDeclaration(program); - return (variableDeclaration.declarations[0].init as estree.ArrayExpression & Identified); - }; - - const getArrayCallExpression = (program: estree.Program) => { - const variableDeclaration = getVariableDeclaration(program); - return (variableDeclaration.declarations[0].init as estree.SimpleCallExpression & Identified); - }; - - const getArrayNewExpression = (program: estree.Program) => { - const variableDeclaration = getVariableDeclaration(program); - return (variableDeclaration.declarations[0].init as estree.NewExpression & Identified); - }; - - it('should mutate when supplied with an array expression', () => { - // Arrange - const program = parser.parse(`var array = [1,2,3];`); - const arrayExpression = getArrayExpression(program); - - // Act - const actual = sut.applyMutations(arrayExpression, copy) as estree.ArrayExpression & Identified; - - // Assert - expect(actual).to.be.ok; - expect(actual.nodeID).to.eq(arrayExpression.nodeID); - expect(actual.elements).to.have.length(0); - }); - - it('should mutate when supplied with an array `call` expression', () => { - // Arrange - const program = parser.parse(`var array = Array(1,2,3);`); - const arrayExpression = getArrayCallExpression(program); - - // Act - const actual = sut.applyMutations(arrayExpression, copy) as estree.CallExpression & Identified; - - // Assert - expect(actual).to.be.ok; - expect(actual.nodeID).to.eq(arrayExpression.nodeID); - expect(actual.arguments).to.have.length(0); - }); - - it('should mutate when supplied with an array `new` expression', () => { - // Arrange - const program = parser.parse(`var array = new Array(1,2,3);`); - const arrayExpression = getArrayNewExpression(program); - - // Act - const actual = sut.applyMutations(arrayExpression, copy) as estree.CallExpression & Identified; - - // Assert - expect(actual).to.be.ok; - expect(actual.nodeID).to.eq(arrayExpression.nodeID); - expect(actual.arguments).to.have.length(0); - }); - - it('should not mutate an empty expression', () => { - // Arrange - const program = parser.parse(`var array = []`); - const emptyArrayExpression = getArrayExpression(program); - - // Act - const actual = sut.applyMutations(emptyArrayExpression, copy); - expect(actual).to.be.undefined; - }); - - it('should not mutate an empty `call` expression', () => { - // Arrange - const program = parser.parse(`var array = Array()`); - const emptyCallExpression = getArrayExpression(program); - - // Act - const actual = sut.applyMutations(emptyCallExpression, copy); - expect(actual).to.be.undefined; - }); - - it('should not mutate an empty `new` expression', () => { - // Arrange - const program = parser.parse(`var array = new Array()`); - const emptyNewExpression = getArrayExpression(program); - - // Act - const actual = sut.applyMutations(emptyNewExpression, copy); - expect(actual).to.be.undefined; - }); -}); diff --git a/packages/stryker/test/unit/mutators/BinaryOperatorMutatorSpec.ts b/packages/stryker/test/unit/mutators/BinaryOperatorMutatorSpec.ts deleted file mode 100644 index 6b6069c228..0000000000 --- a/packages/stryker/test/unit/mutators/BinaryOperatorMutatorSpec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { expect } from 'chai'; -import * as estree from 'estree'; -import * as _ from 'lodash'; -import BinaryOperatorMutator from '../../../src/mutators/BinaryOperatorMutator'; -import { Identified, IdentifiedNode } from '../../../src/mutators/IdentifiedNode'; - -describe('BinaryOperatorMutator', () => { - let mutator: BinaryOperatorMutator; - let invalidNode: IdentifiedNode; - let validNode: IdentifiedNode; - - beforeEach(() => { - mutator = new BinaryOperatorMutator(); - invalidNode = { - type: 'Identifier', - } as estree.Node & Identified; - validNode = { - left: { - nodeID: -1, - raw: '6', - type: 'Literal', - value: typeof 6 - } as estree.SimpleLiteral, - nodeID: 23, - operator: '+', - right: { - nodeID: -2, - raw: '7', - type: 'Literal', - value: typeof 7 - }, - type: 'BinaryExpression' - } as estree.BinaryExpression & Identified; - }); - - describe('should mutate', () => { - it('a valid Node', () => { - const mutatedNodes = mutator.applyMutations(validNode, _.cloneDeep); - - expect(mutatedNodes).to.have.lengthOf(1); - }); - }); - - describe('should not mutate', () => { - it('an invalid Node', () => { - const mutatedNodes = mutator.applyMutations(invalidNode, _.cloneDeep); - - expect(mutatedNodes).to.have.lengthOf(0); - }); - }); -}); diff --git a/packages/stryker/test/unit/mutators/BlockStatementMutatorSpec.ts b/packages/stryker/test/unit/mutators/BlockStatementMutatorSpec.ts deleted file mode 100644 index 0b9d28f5f5..0000000000 --- a/packages/stryker/test/unit/mutators/BlockStatementMutatorSpec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai'; -import * as estree from 'estree'; -import { Identified } from '../../../src/mutators/IdentifiedNode'; -import BlockStatementMutator from '../../../src/mutators/BlockStatementMutator'; -import { parse, identified } from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; - -describe('BlockStatementMutator', () => { - let sut: BlockStatementMutator; - - beforeEach(() => sut = new BlockStatementMutator()); - - it('should mutate when supplied a block statement', () => { - // Arrange - const program = parse(`function a () { - 'use strict'; - }`); - const useStrictBlockStatement = identified((program.body[0] as estree.FunctionDeclaration).body); - - // Act - const actual = sut.applyMutations(useStrictBlockStatement, copy) as estree.BlockStatement & Identified; - - // Assert - expect(actual).to.be.ok; - expect(actual.nodeID).to.eq(useStrictBlockStatement.nodeID); - expect(actual.body).to.have.length(0); - }); - - it('should not mutate an empty expression', () => { - // Arrange - const program = parse(`function a () { - - }`); - const emptyBlockStatement = identified((program.body[0] as estree.FunctionDeclaration).body); - - // Act - const actual = sut.applyMutations(emptyBlockStatement, copy); - expect(actual).to.not.be.ok; - }); -}); diff --git a/packages/stryker/test/unit/mutators/BooleanSubstitutionMutatorSpec.ts b/packages/stryker/test/unit/mutators/BooleanSubstitutionMutatorSpec.ts deleted file mode 100644 index 507c44a2a9..0000000000 --- a/packages/stryker/test/unit/mutators/BooleanSubstitutionMutatorSpec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { expect } from 'chai'; -import * as estree from 'estree'; -import { Identified, IdentifiedNode } from '../../../src/mutators/IdentifiedNode'; -import BooleanSubstitutionMutator from '../../../src/mutators/BooleanSubstitutionMutator'; -import { parse, generate } from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; - -describe('BooleanSubstitutionMutator', () => { - let sut: BooleanSubstitutionMutator; - - beforeEach(() => { - sut = new BooleanSubstitutionMutator(); - }); - - it('should mutate when supplied a expression with !', () => { - // Arrange - const program = parse(`!a.a()`); - const nodeUnaryExpression = ((program.body[0] as estree.ExpressionStatement).expression as estree.UnaryExpression & Identified); - - // Act - const result = sut.applyMutations(nodeUnaryExpression, copy)[0] as estree.Expression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.type).to.be.eq(nodeUnaryExpression.argument.type); - expect(result.nodeID).to.be.eq(nodeUnaryExpression.nodeID); - expect(generate(result)).to.be.eq('a.a()'); - }); - - it('should mutate true -> false', () => { - // Arrange - const program = parse(`true`); - const nodeLiteral = ((program.body[0] as estree.ExpressionStatement).expression as estree.Literal & Identified); - - // Act - const result = sut.applyMutations(nodeLiteral, copy)[0] as estree.Literal & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.value).to.be.false; - expect(result.nodeID).to.be.eq(nodeLiteral.nodeID); - expect(generate(result)).to.be.eq('false'); - }); - - it('should mutate false -> true', () => { - // Arrange - const program = parse(`false`); - const nodeLiteral = ((program.body[0] as estree.ExpressionStatement).expression as estree.Literal & Identified); - - // Act - const result = sut.applyMutations(nodeLiteral, copy)[0] as estree.Literal & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.value).to.be.true; - expect(result.nodeID).to.be.eq(nodeLiteral.nodeID); - expect(generate(result)).to.be.eq('true'); - }); - - it('should not mutate other nodes', () => { - // Arrange - const invalidNode: IdentifiedNode = { - type: 'Identifier', - } as estree.Node & Identified; - - // Act - const result = sut.applyMutations(invalidNode, copy); - - // Assert - expect(result).to.have.lengthOf(0); - }); - -}); diff --git a/packages/stryker/test/unit/mutators/ES5MutantGeneratorSpec.ts b/packages/stryker/test/unit/mutators/ES5MutantGeneratorSpec.ts deleted file mode 100644 index 38189a6ced..0000000000 --- a/packages/stryker/test/unit/mutators/ES5MutantGeneratorSpec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { expect } from 'chai'; -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import { Mutant } from 'stryker-api/mutant'; -import ES5Mutator from '../../../src/mutators/ES5Mutator'; -import NodeMutator from '../../../src/mutators/NodeMutator'; -import { Identified, IdentifiedNode } from '../../../src/mutators/IdentifiedNode'; -import { File } from 'stryker-api/core'; -import * as sinon from 'sinon'; -import { testInjector } from '@stryker-mutator/test-helpers'; - -describe('ES5Mutator', () => { - let sut: ES5Mutator; - - beforeEach(() => { - sut = testInjector.injector.injectClass(ES5Mutator); - }); - - afterEach(() => { - sinon.restore(); - }); - - describe('with single input file with a one possible mutation', () => { - let mutants: Mutant[]; - - beforeEach(() => { - mutants = sut.mutate([new File('', 'var i = 1 + 2;')]); - }); - - it('should return an array with a single mutant', () => { - expect(mutants.length).to.equal(1); - }); - - it('should be able to mutate code', () => { - expect(mutants[0].replacement).eq('1 - 2'); - }); - - it('should set the range', () => { - const originalCode = '\n\nvar i = 1 + 2;'; - mutants = sut.mutate([new File('', originalCode)]); - expect(mutants[0].range[0]).to.equal(10); - expect(mutants[0].range[1]).to.equal(15); - }); - }); - - describe('should be able to handle a Mutator that returns', () => { - - class StubMutator implements NodeMutator { - public name: 'stub'; - public applyMutations(node: IdentifiedNode): IdentifiedNode[] { - const nodes: IdentifiedNode[] = []; - if (node.type === Syntax.BinaryExpression) { - // eg: '1 * 2': push child node - nodes.push((node as estree.BinaryExpression).left as estree.Expression & Identified); - } else if (node.type === Syntax.IfStatement) { - // eg: 'if(true);': push original node - nodes.push(node); - } - return nodes; - } - } - - beforeEach(() => { - sut = new ES5Mutator(testInjector.logger, [new StubMutator()]); - }); - - it('the same nodeID', () => { - const mutants = sut.mutate([new File('some file', 'if (true);')]); - expect(mutants[0].fileName).eq('some file'); - expect(mutants[0].replacement).eq('if (true);'); - }); - - it('a different nodeID', () => { - const mutants = sut.mutate([new File('src.js', '1 * 2')]); - expect(mutants[0].fileName).eq('src.js'); - expect(mutants[0].replacement).eq('1'); - }); - }); - -}); diff --git a/packages/stryker/test/unit/mutators/LogicalOperatorMutatorSpec.ts b/packages/stryker/test/unit/mutators/LogicalOperatorMutatorSpec.ts deleted file mode 100644 index a4e3a7be6c..0000000000 --- a/packages/stryker/test/unit/mutators/LogicalOperatorMutatorSpec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai'; -import * as estree from 'estree'; -import { Identified } from '../../../src/mutators/IdentifiedNode'; -import LogicalOperatorMutator from '../../../src/mutators/LogicalOperatorMutator'; -import * as parser from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; - -describe('LogicalOperatorMutator', () => { - let sut: LogicalOperatorMutator; - - beforeEach(() => sut = new LogicalOperatorMutator()); - - it('should mutate \'||\' to \'&&\'', () => { - // Arrange - const program = parser.parse(`true || false`); - const logicalOperator = ((program.body[0] as estree.ExpressionStatement).expression as estree.LogicalExpression & Identified); - - // Act - const result = sut.applyMutations(logicalOperator, copy)[0] as estree.LogicalExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(logicalOperator.nodeID); - expect(result.operator).to.be.eq('&&'); - }); - - it('should mutate \'&&\' to \'||\'', () => { - // Arrange - const program = parser.parse(`false && false`); - const logicalOperator = ((program.body[0] as estree.ExpressionStatement).expression as estree.LogicalExpression & Identified); - - // Act - const result = sut.applyMutations(logicalOperator, copy)[0] as estree.LogicalExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(logicalOperator.nodeID); - expect(result.operator).to.be.eq('||'); - }); -}); diff --git a/packages/stryker/test/unit/mutators/RemoveConditionalsMutatorSpec.ts b/packages/stryker/test/unit/mutators/RemoveConditionalsMutatorSpec.ts deleted file mode 100644 index 2875a2a9ca..0000000000 --- a/packages/stryker/test/unit/mutators/RemoveConditionalsMutatorSpec.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as chai from 'chai'; -import { Syntax } from 'esprima'; -import * as estree from 'estree'; -import { Identified, IdentifiedNode } from '../../../src/mutators/IdentifiedNode'; -import RemoveConditionalsMutator from '../../../src/mutators/RemoveConditionalsMutator'; -import { NodeIdentifier, parse, identified } from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; - -const expect = chai.expect; - -describe('RemoveConditionalsMutator', () => { - let sut: RemoveConditionalsMutator; - let doWhileLoop: estree.DoWhileStatement & Identified; - let forLoop: estree.ForStatement & Identified; - let infiniteForLoop: estree.ForStatement & Identified; - let whileLoop: estree.WhileStatement & Identified; - let ifStatement: estree.IfStatement & Identified; - let ternaryExpression: estree.ConditionalExpression & Identified; - - beforeEach(() => { - sut = new RemoveConditionalsMutator(); - const code = - `var price = 99.95; - if(price > 25){ - console.log("Too expensive"); - } - while(price > 50){ - price = price * 0.25; - } - do { - console.log("I\'m sorry. The price is still too high"); - price = price - 5; - } while(price > 30); - for(var i = 0; i < 10; i++) { - console.log("I would like to buy the item"); - } - for(var j = 0; ; j++) { - console.log("Infinite loop"); - } - price < 20? 40 : 10; - `; - - const ast = parse(code); - new NodeIdentifier().identifyAndFreeze(ast); - ifStatement = ast.body[1] as estree.IfStatement & Identified; - whileLoop = ast.body[2] as estree.WhileStatement & Identified; - doWhileLoop = ast.body[3] as estree.DoWhileStatement & Identified; - forLoop = ast.body[4] as estree.ForStatement & Identified; - infiniteForLoop = ast.body[5] as estree.ForStatement & Identified; - ternaryExpression = (ast.body[6] as estree.ExpressionStatement).expression as estree.ConditionalExpression & Identified; - }); - - function actMutator(node: IdentifiedNode) { - const mutants = sut.applyMutations(node, copy); - if (Array.isArray(mutants)) { - return mutants; - } else { - return []; - } - } - - describe('should not generate an infinite loop', () => { - - it('when given a do-while loop', () => { - const mutatedNodes = actMutator(doWhileLoop); - - const testValue = (mutatedNodes[0] as estree.Literal).value; - expect(testValue).to.be.false; - expect(mutatedNodes[0].nodeID).to.not.eq(doWhileLoop.nodeID); - expect(mutatedNodes[0].nodeID).to.eq(identified(doWhileLoop.test).nodeID); - }); - - it('when given a while loop', () => { - const mutatedNodes = actMutator(whileLoop); - - const testValue = (mutatedNodes[0] as estree.Literal).value; - expect(testValue).to.be.false; - expect(mutatedNodes[0].nodeID).to.not.eq(whileLoop.nodeID); - expect(mutatedNodes[0].nodeID).to.eq(identified(whileLoop.test).nodeID); - }); - - it('when given a for loop', () => { - const mutatedNodes = actMutator(forLoop); - - const testValue = (mutatedNodes[0] as estree.Literal).value; - expect(testValue).to.be.false; - expect(mutatedNodes[0].nodeID).to.not.eq(forLoop.nodeID); - if (forLoop.test) { - expect(mutatedNodes[0].nodeID).to.eq(identified(forLoop.test).nodeID); - } else { - expect.fail('test.nodeID was expected to be not undefined'); - } - }); - - it('when given an infinite-for loop', () => { - const forStatementNode = actMutator(infiniteForLoop)[0]; - if (forStatementNode.type === Syntax.ForStatement && forStatementNode.test && forStatementNode.test.type === Syntax.Literal) { - const testValue = forStatementNode.test.value; - expect(testValue).to.be.false; - expect(forStatementNode.nodeID).to.eq(infiniteForLoop.nodeID); - } else { - expect.fail(`Node ${forStatementNode} unexpected.`); - } - }); - }); - - describe('should generate a single mutant', () => { - it('when given a do-while loop', () => { - const mutatedNodes = actMutator(doWhileLoop); - - expect(mutatedNodes).to.have.lengthOf(1); - }); - - it('when given a while loop', () => { - const mutatedNodes = actMutator(whileLoop); - - expect(mutatedNodes).to.have.lengthOf(1); - }); - - it('when given a for loop', () => { - const mutatedNodes = actMutator(forLoop); - - expect(mutatedNodes).to.have.lengthOf(1); - }); - }); - - describe('should generate multiple mutants', () => { - it('when given an if-statement', () => { - const mutatedNodes = actMutator(ifStatement) as (estree.SimpleLiteral & Identified)[]; - - expect(mutatedNodes).to.have.length(2); - expect(mutatedNodes[0].nodeID).not.to.eq(ifStatement.nodeID); - expect(mutatedNodes[1].nodeID).not.to.eq(ifStatement.nodeID); - expect(mutatedNodes[0].nodeID).to.eq(identified(ifStatement.test).nodeID); - expect(mutatedNodes[1].nodeID).to.eq(identified(ifStatement.test).nodeID); - expect(mutatedNodes[0].value).to.be.false; - expect(mutatedNodes[1].value).to.be.true; - }); - - it('when given a ternary-statement', () => { - const mutatedNodes = actMutator(ternaryExpression) as (estree.SimpleLiteral & Identified)[]; - - expect(mutatedNodes).to.have.length(2); - expect(mutatedNodes[0].nodeID).not.to.eq(ternaryExpression.nodeID); - expect(mutatedNodes[1].nodeID).not.to.eq(ternaryExpression.nodeID); - expect(mutatedNodes[1].nodeID).to.eq(identified(ternaryExpression.test).nodeID); - expect(mutatedNodes[1].nodeID).to.eq(identified(ternaryExpression.test).nodeID); - expect(mutatedNodes[0].value).to.be.false; - expect(mutatedNodes[1].value).to.be.true; - }); - }); - - describe('should not crash', () => { - it('when given an for-loop', () => { - const mutatedNodes = actMutator(infiniteForLoop); - - expect(mutatedNodes).to.have.length(1); - expect(mutatedNodes[0].nodeID).eq(infiniteForLoop.nodeID); - }); - }); -}); diff --git a/packages/stryker/test/unit/mutators/UpdateOperatorMutatorSpec.ts b/packages/stryker/test/unit/mutators/UpdateOperatorMutatorSpec.ts deleted file mode 100644 index f5fb427816..0000000000 --- a/packages/stryker/test/unit/mutators/UpdateOperatorMutatorSpec.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Identified } from '../../../src/mutators/IdentifiedNode'; -import UpdateOperatorMutator from '../../../src/mutators/UpdateOperatorMutator'; -import { expect } from 'chai'; -import * as parser from '../../../src/utils/parserUtils'; -import { copy } from '../../../src/utils/objectUtils'; -import * as estree from 'estree'; - -describe('UpdateOperatorMutator', () => { - let sut: UpdateOperatorMutator; - - beforeEach(() => sut = new UpdateOperatorMutator()); - - describe('should mutate', () => { - it('"i++" to "i--"', () => { - // Arrange - const program = parser.parse(`i++`); - const expression = (program.body[0] as estree.ExpressionStatement).expression as estree.Expression & Identified; - - // Act - const result = sut.applyMutations(expression, copy) as estree.UpdateExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(expression.nodeID); - expect(result.operator).to.be.eq('--'); - }); - - it('"i--" to "i++"', () => { - // Arrange - const program = parser.parse(`i--`); - const expression = (program.body[0] as estree.ExpressionStatement).expression as estree.Expression & Identified; - - // Act - const result = sut.applyMutations(expression, copy) as estree.UpdateExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(expression.nodeID); - expect(result.operator).to.be.eq('++'); - }); - - it('"++i" to "--i"', () => { - // Arrange - const program = parser.parse(`++i`); - const expression = (program.body[0] as estree.ExpressionStatement).expression as estree.Expression & Identified; - - // Act - const result = sut.applyMutations(expression, copy) as estree.UpdateExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(expression.nodeID); - expect(result.operator).to.be.eq('--'); - }); - - it('"--i" to "++i"', () => { - // Arrange - const program = parser.parse(`--i`); - const expression = (program.body[0] as estree.ExpressionStatement).expression as estree.Expression & Identified; - - // Act - const result = sut.applyMutations(expression, copy) as estree.UpdateExpression & Identified; - - // Assert - expect(result).to.be.ok; - expect(result.nodeID).to.eq(expression.nodeID); - expect(result.operator).to.be.eq('++'); - }); - }); - - describe('should not mutate', () => { - it('"+i" to "-i"', () => { - // Arrange - const program = parser.parse(`-i`); - const expression = (program.body[0] as estree.ExpressionStatement).expression as estree.Expression & Identified; - - // Act - const result = sut.applyMutations(expression, copy); - - // Assert - expect(result).to.be.undefined; - }); - }); - -}); diff --git a/packages/stryker/test/unit/utils/parserUtilsSpec.ts b/packages/stryker/test/unit/utils/parserUtilsSpec.ts deleted file mode 100644 index 718c472a86..0000000000 --- a/packages/stryker/test/unit/utils/parserUtilsSpec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { expect } from 'chai'; -import * as parserUtils from '../../../src/utils/parserUtils'; - -describe('parserUtils', () => { - describe('collectFrozenNodes', () => { - it('when provided a try catch block', () => { - // A try catch block has recursion. See - // http://esprima.org/demo/parse.html?code=try%20%7B%0D%0A%20%20%20%20%20%20%20%20configModule(config)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20catch%20(e)%20%7B%0D%0A%20%20%20%20%20%20%20%20process.exit(1)%3B%0D%0A%20%20%20%20%20%20%7D - const parsedTryCatch = parserUtils.parse(`try { - configModule(config); - } - catch (e) { - process.exit(1); - }`); - new parserUtils.NodeIdentifier().identifyAndFreeze(parsedTryCatch); - }); - }); - - describe('parse', () => { - describe('should throw an error', () => { - it('if no code is provided when parsing', () => { - expect(parserUtils.parse).to.throw(Error); - }); - }); - }); -});