Skip to content

Commit

Permalink
implement MutationLevel construct for Regex (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ja4pp committed Jan 14, 2024
1 parent e74fe75 commit 6aac475
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
10 changes: 7 additions & 3 deletions packages/instrumenter/src/mutators/regex-mutator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ const weaponRegexOptions: weaponRegex.MutationOptions = { mutationLevels: [1] };
export const regexMutator: NodeMutator = {
name: 'Regex',

*mutate(path) {
if (path.isRegExpLiteral()) {
*mutate(path, options) {
if (path.isRegExpLiteral() && isInMutationLevel(options)) {
for (const replacementPattern of mutatePattern(path.node.pattern, path.node.flags)) {
const replacement = types.regExpLiteral(replacementPattern, path.node.flags);
yield replacement;
}
} else if (path.isStringLiteral() && isObviousRegexString(path)) {
} else if (path.isStringLiteral() && isObviousRegexString(path) && isInMutationLevel(options)) {
const flags = getFlags(path.parentPath as NodePath<t.NewExpression>);
for (const replacementPattern of mutatePattern(path.node.value, flags)) {
yield types.stringLiteral(replacementPattern);
Expand All @@ -59,3 +59,7 @@ function mutatePattern(pattern: string, flags: string | undefined): string[] {
}
return [];
}

function isInMutationLevel(operations: string[] | undefined): boolean {
return operations === undefined || operations.length > 0;
}
18 changes: 17 additions & 1 deletion packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { expect } from 'chai';
import sinon from 'sinon';

import { regexMutator as sut } from '../../../src/mutators/regex-mutator.js';
import { expectJSMutation } from '../../helpers/expect-mutation.js';
import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js';
import { MutationLevel } from '../../../src/mutation-level/mutation-level.js';

const regexLevel: MutationLevel = { name: 'RegexLevel', Regex: ['Regex'] };
const regexUndefinedLevel: MutationLevel = { name: 'RegexLevel' };

describe(sut.name, () => {
it('should have name "Regex"', () => {
Expand Down Expand Up @@ -53,4 +57,16 @@ describe(sut.name, () => {
it('should only pass flags in new RegExp constructors if it is a string literal', () => {
expectJSMutation(sut, 'new RegExp("\\\\u{20}", foo)', 'new RegExp("\\\\u", foo)');
});

it('should only mutate what is defined in the mutator level', () => {
expectJSMutationWithLevel(sut, regexLevel.Regex, 'new RegExp("\\\\u{20}", foo)', 'new RegExp("\\\\u", foo)');
});

it('should not mutate anything if there are no values in the mutation level', () => {
expectJSMutationWithLevel(sut, [], 'new RegExp("\\\\u{20}", foo)');
});

it('should mutate everything if the mutation level is undefined', () => {
expectJSMutationWithLevel(sut, regexUndefinedLevel.Regex, 'new RegExp("\\\\u{20}", foo)', 'new RegExp("\\\\u", foo)');
});
});

0 comments on commit 6aac475

Please sign in to comment.