-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ArrayDeclarationMutator): Add new mutator. (#229)
Add a new mutator which mutates non-empty arrays to be empty
- Loading branch information
1 parent
1a5968c
commit 9805917
Showing
5 changed files
with
136 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import {Syntax} from 'esprima'; | ||
import {Mutator} from 'stryker-api/mutant'; | ||
import * as estree from 'estree'; | ||
|
||
/** | ||
* Represents a mutator which can remove the content of an array's elements. | ||
*/ | ||
export default class ArrayDeclaratorMutator implements Mutator { | ||
name = 'ArrayDeclarator'; | ||
|
||
constructor() { } | ||
|
||
applyMutations(node: estree.Node, copy: <T>(obj: T, deep?: boolean) => T): void | estree.Node | estree.Node[] { | ||
if ((node.type === Syntax.CallExpression || node.type === Syntax.NewExpression) && node.callee.type === Syntax.Identifier && node.callee.name === 'Array' && node.arguments.length > 0) { | ||
let mutatedNode = copy(node); | ||
mutatedNode.arguments = []; | ||
return mutatedNode; | ||
} | ||
|
||
if (node.type === Syntax.ArrayExpression && node.elements.length > 0) { | ||
let mutatedNode = copy(node); | ||
mutatedNode.elements = []; | ||
return mutatedNode; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import ArrayDeclaratorMutator from '../../../src/mutators/ArrayDeclaratorMutator'; | ||
import { expect } from 'chai'; | ||
import * as parser from '../../../src/utils/parserUtils'; | ||
import { copy } from '../../../src/utils/objectUtils'; | ||
import { Syntax } from 'esprima'; | ||
import * as estree from 'estree'; | ||
|
||
describe('BlockStatementMutator', () => { | ||
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); | ||
}; | ||
|
||
const getArrayCallExpression = (program: estree.Program) => { | ||
const variableDeclaration = getVariableDeclaration(program); | ||
return (variableDeclaration.declarations[0].init as estree.SimpleCallExpression); | ||
}; | ||
|
||
const getArrayNewExpression = (program: estree.Program) => { | ||
const variableDeclaration = getVariableDeclaration(program); | ||
return (variableDeclaration.declarations[0].init as estree.NewExpression); | ||
}; | ||
|
||
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 = <estree.ArrayExpression>sut.applyMutations(arrayExpression, copy); | ||
|
||
// 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 = <estree.CallExpression>sut.applyMutations(arrayExpression, copy); | ||
|
||
// 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 = <estree.CallExpression>sut.applyMutations(arrayExpression, copy); | ||
|
||
// 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; | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var array = [1,2,3]; | ||
|
||
var array2 = Array(1,2,3); | ||
|
||
var array3 = new Array(1,2,3); |