From 242af267407ed0dc1d1fc357f57a3aa9ab12076a Mon Sep 17 00:00:00 2001 From: Ja4pp <70022125+Ja4pp@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:11:35 +0100 Subject: [PATCH] #30 restrict updateoperator mutator (#51) * updated to conform to mutationlevels * modified tests * modified config file * initial implementation of condition * Revert "initial implementation of condition" This reverts commit bcb6cc0c355534a50ca9c01c378576080c123351. * changed tests to pass CI/CD * changes nessecary for pass * small refactor * remove line added by mistake --------- Co-authored-by: Danut Copae <66919951+dvcopae@users.noreply.github.com> Co-authored-by: Danut Copae --- .../src/mutators/update-operator-mutator.ts | 34 ++++++++++++++--- .../mutators/update-operator-mutator.spec.ts | 38 ++++++++++++++++++- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/packages/instrumenter/src/mutators/update-operator-mutator.ts b/packages/instrumenter/src/mutators/update-operator-mutator.ts index 970c83cae5..19b8cc0602 100644 --- a/packages/instrumenter/src/mutators/update-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/update-operator-mutator.ts @@ -6,17 +6,39 @@ import { NodeMutator } from './index.js'; const { types } = babel; -enum UpdateOperators { - '++' = '--', - '--' = '++', -} +const operators = Object.assign({ + 'Post++To--': { replacementOperator: '--', mutatorName: 'Post++To--' }, + 'Post--To++': { replacementOperator: '++', mutatorName: 'Post--To++' }, + 'Pre++To--': { replacementOperator: '--', mutatorName: 'Pre++To--' }, + 'Pre--To++': { replacementOperator: '++', mutatorName: 'Pre--To++' }, + '++': { replacementOperator: '--', mutatorName: '++all' }, + '--': { replacementOperator: '++', mutatorName: '--all' }, +} as const); export const updateOperatorMutator: NodeMutator = { name: 'UpdateOperator', - *mutate(path) { + *mutate(path, operations) { if (path.isUpdateExpression()) { - yield types.updateExpression(UpdateOperators[path.node.operator], deepCloneNode(path.node.argument), path.node.prefix); + if (operations === undefined) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + yield types.updateExpression(operators[path.node.operator].replacementOperator, deepCloneNode(path.node.argument), path.node.prefix); + } else { + let replacement = undefined; + if (path.node.prefix && path.node.operator == '++' && operations.includes(operators['Pre++To--'].mutatorName as string)) { + replacement = operators['Pre++To--'].replacementOperator; + } else if (path.node.prefix && path.node.operator == '--' && operations.includes(operators['Pre--To++'].mutatorName as string)) { + replacement = operators['Pre--To++'].replacementOperator; + } else if (!path.node.prefix && path.node.operator == '++' && operations.includes(operators['Post++To--'].mutatorName as string)) { + replacement = operators['Post++To--'].replacementOperator; + } else if (!path.node.prefix && path.node.operator == '--' && operations.includes(operators['Post--To++'].mutatorName as string)) { + replacement = operators['Post--To++'].replacementOperator; + } + if (replacement !== undefined) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + yield types.updateExpression(replacement, deepCloneNode(path.node.argument), path.node.prefix); + } + } } }, }; diff --git a/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts index 9c5ac0c0b8..1269d25c46 100644 --- a/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts @@ -1,7 +1,11 @@ import { expect } from 'chai'; import { updateOperatorMutator as sut } from '../../../src/mutators/update-operator-mutator.js'; -import { expectJSMutation } from '../../helpers/expect-mutation.js'; +import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; + +const updateLevel: string[] = ['Pre--To++', 'Pre++To--']; +const updateLevel2: string[] = ['Post++To--', 'Post--To++']; +const updateLevel3 = undefined; describe(sut.name, () => { it('should have name "UpdateOperator"', () => { @@ -23,4 +27,36 @@ describe(sut.name, () => { it('should mutate --a to ++a', () => { expectJSMutation(sut, '--a', '++a'); }); + + it('should only mutate --a and ++a', () => { + expectJSMutationWithLevel( + sut, + updateLevel, + '--a; ++a; a--; a++', + '++a; ++a; a--; a++', //mutates --a + '--a; --a; a--; a++', //mutates ++a + ); + }); + + it('should only mutate a-- and a++', () => { + expectJSMutationWithLevel( + sut, + updateLevel2, + '--a; ++a; a--; a++', + '--a; ++a; a--; a--', //mutates a++ + '--a; ++a; a++; a++', //mutates a-- + ); + }); + + it('should mutate all', () => { + expectJSMutationWithLevel( + sut, + updateLevel3, + '--a; ++a; a--; a++', + '++a; ++a; a--; a++', //mutates --a + '--a; --a; a--; a++', //mutates ++a + '--a; ++a; a--; a--', //mutates a++ + '--a; ++a; a++; a++', //mutates a-- + ); + }); });