From 9db053c2dd07d53c43fdd9eeef970f811890e43b Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 14:18:03 +0100 Subject: [PATCH 01/13] Rename mutators in the schema --- packages/api/schema/stryker-core.json | 346 +++++++++++++------------- 1 file changed, 173 insertions(+), 173 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index ba767d4807..7221c27606 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -302,28 +302,28 @@ "title": "ArithmeticOperator", "anyOf": [ { - "const" : "%To*", - "title": "PercentToMultiplyMutator", + "const" : "ArithmeticOperator_RemainderOperator_ToMultiplicationOperator", + "title": "RemainderOperatorToMultiplicationOperator", "description": "Replace ```a % b``` with ```a * b```." }, { - "const" : "*To/", - "title": "MultiplyToDivideMutator", + "const" : "ArithmeticOperator_MultiplicationOperator_ToDivisionOperator", + "title": "MultiplicationOperatorToDivisionOperator", "description": "Replace ```a * b``` with ```a / b```." }, { - "const" : "/To*", - "title": "DivideToMultiplyMutator", + "const" : "ArithmeticOperator_DivisionOperator_ToMultiplicationOperator", + "title": "DivisionOperatorToMultiplicationOperator", "description": "Replace ```a / b``` with ```a * b```." }, { - "const" : "+To-", - "title": "PlusToMinusMutator", + "const" : "ArithmeticOperator_AdditionOperator_ToNegationOperator", + "title": "AdditionOperatorToNegationOperator", "description": "Replace ```a + b``` with ```a - b```." }, { - "const" : "-To+", - "title": "MinusToPlusMutator", + "const" : "ArithmeticOperator_NegationOperator_ToAdditionOperator", + "title": "NegationOperatorToAdditionOperator", "description": "Replace ```a - b``` with ```a + b```." } ] @@ -332,23 +332,23 @@ "title": "ArrayDeclaration", "anyOf": [ { - "const": "EmptyArray", - "title": "EmptyArrayMutator", + "const": "ArrayDeclaration_ArrayLiteral_Fill", + "title": "ArrayLiteralFill", "description": "Replace ```[ ]``` with ```[Stryker was here]```." }, { - "const": "EmptyArrayConstructor", - "title": "EmptyConstructorMutator", + "const": "ArrayDeclaration_ArrayConstructor_Fill", + "title": "ArrayConstructorFill", "description": "Replace ```new Array()``` with ```new Array(Stryker was here)```." }, { - "const": "FilledArray", - "title": "FilledArrayMutator", + "const": "ArrayDeclaration_ArrayLiteral_ItemsRemoval", + "title": "ArrayLiteralItemsRemoval", "description": "Replace ```[1, 2, 3, 4]``` with ```[ ]```." }, { - "const": "FilledArrayConstructor", - "title": "FilledArrayConstructorMutator", + "const": "ArrayDeclaration_ArrayConstructor_ItemsRemoval", + "title": "ArrayConstructorItemsRemoval", "description": "Replace ```new Array([1, 2, 3, 4])``` with ```new Array()```." } ] @@ -357,91 +357,91 @@ "title": "AssignmentOperator", "anyOf": [ { - "const" : "+=To-=", - "title": "PlusAssignmentToMinusAssignmentMutator", + "const" : "AssignmentOperator_AdditionAssignment_ToSubstractionAssignment", + "title": "AdditionAssignmentToSubstractionAssignment", "description": "Replace ```a += b``` with ```a -= b```." }, { - "const" : "-=To+=", - "title": "MinusAssignmentToPlusAssignmentMutator", + "const" : "AssignmentOperator_SubstractionAssignment_ToAdditionAssignment", + "title": "SubstractionAssignmentToAdditionAssignment", "description": "Replace ```a -= b``` with ```a += b```." }, { - "const" : "*=To/=", - "title": "MultiplyAssignmentToDivideAssignmentMutator", + "const" : "AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment", + "title": "MultiplicationAssignmentToDivisionAssignment", "description": "Replace ```a *= b``` with ```a /= b```." }, { - "const" : "/=To*=", - "title": "DivideAssignmentToMultiplyAssignmentMutator", + "const" : "AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment", + "title": "DivisionAssignmentToMultiplicationAssignment", "description": "Replace ```a /= b``` with ```a *= b```." }, { - "const" : "%=To*=", - "title": "ModuloAssignmentToMultiplyAssignmentMutator", + "const" : "AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment", + "title": "RemainderAssignmentToMultiplicationAssignment", "description": "Replace ```a %= b``` with ```a *= b```." }, { - "const" : "<<=To>>=", - "title": "LeftShiftAssignmentToRightShiftAssignmentMutator", + "const" : "AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment", + "title": "LeftShiftAssignmentToRightShiftAssignment", "description": "Replace ```a <<= b``` with ```a >>= b```." }, { - "const" : ">>=To<<=", - "title": "RightShiftAssignmentToLeftShiftAssignmentMutator", + "const" : "AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment", + "title": "RightShiftAssignmentToLeftShiftAssignment", "description": "Replace ```a >>= b``` with ```a <<= b```." }, { - "const" : "&=To|=", - "title": "BitAndAssignmentToBitOrAssignmentMutator", + "const" : "AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment", + "title": "BitwiseAndAssignmentToBitwiseOrAssignment", "description": "Replace ```a &= b``` with ```a |= b```." }, { - "const" : "|=To&=", - "title": "BitOrAssignmentToBitAndAssignmentMutator", + "const" : "AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment", + "title": "BitwiseOrAssignmentToBitwiseAndAssignment", "description": "Replace ```a |= b``` with ```a &= b```." }, { - "const" : "&&=To||=", - "title": "LogicalAndAssignmentToLogicalOrAssignmentMutator", + "const" : "AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment", + "title": "LogicalAndAssignmentToLogicalOrAssignment", "description": "Replace ```a &&= b``` with ```a ||= b```." }, { - "const" : "||=To&&=", - "title": "LogicalOrAssignmentToLogicalAndAssignmentMutator", + "const" : "AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment", + "title": "LogicalOrAssignmentToLogicalAndAssignment", "description": "Replace ```a ||= b``` with ```a &&= b```." }, { - "const" : "??=To&&=", - "title": "NullishCoalescingAssignmentToLogicalAndAssignmentMutator", + "const" : "AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment", + "title": "NullishCoalescingAssignmentToLogicalAndAssignment", "description": "Replace ```a ??= b``` with ```a &&= b```." } ] }, "ArrowFunction": { - "const": "ArrowFunction", + "const": "ArrowFunction_Removal", "description": "Mutates bodies of arrow functions to undefined" }, "BlockStatement": { - "const": "BlockStatement", + "const": "BlockStatement_Removal", "description": "Removes the content of every block statement." }, "BooleanLiteral": { "title": "BooleanLiteral", "anyOf": [ { - "const" : "FalseToTrue", - "title": "FalseToTrueMutator", + "const" : "BooleanLiteral_TrueLiteral_ToFalseLiteral", + "title": "TrueLiteralToFalseLiteral", "description": "Replace ```true``` with ```false```." }, { - "const" : "TrueToFalse", - "title": "TrueToFalseMutator", - "description": "Replace ```true``` with ```false```." + "const" : "BooleanLiteral_FalseLiteral_ToTrueLiteral", + "title": "FalseLiteralToTrueLiteral", + "description": "Replace ```false``` with ```true```." }, { - "const" : "RemoveNegation", - "title": "RemoveNegationMutator", + "const" : "BooleanLiteral_LogicalNot_Removal", + "title": "LogicalNotRemoval", "description": "Replace ```!(a == b)``` with ```a == b```." } ] @@ -450,43 +450,43 @@ "title": "ConditionalExpression", "anyOf": [ { - "const" : "ForLoopToFalse", - "title": "ForLoopToFalseMutator", + "const" : "ConditionalExpression_ForLoopCondition_ToFalseLiteral", + "title": "ForLoopConditionToFalseLiteral", "description": "Replace ```for (var i = 0; i < 10; i++) { }``` with ```for (var i = 0; false; i++) { }```." }, { - "const" : "WhileLoopToFalse", - "title": "WhileLoopToFalseMutator", + "const" : "ConditionalExpression_WhileLoopCondition_ToFalseLiteral", + "title": "WhileLoopConditionToFalseLiteral", "description": "Replace ```while (a > b) { }``` with ```while (false) { }```." }, { - "const" : "DoWhileLoopToFalse", - "title": "DoWhileLoopToFalseMutator", + "const" : "ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral", + "title": "DoWhileLoopConditionToFalseLiteral", "description": "Replace ```do { } while (a > b);``` with ```do { } while (false);```." }, { - "const" : "IfToTrue", - "title": "IfToTrueMutator", + "const" : "ConditionalExpression_IfCondition_ToTrueLiteral", + "title": "IfConditionToTrueLiteral", "description": "Replace ```if (a > b) { }``` with ```if (true) { }```." }, { - "const" : "IfToFalse", - "title": "IfToFalseMutator", + "const" : "ConditionalExpression_IfCondition_ToFalseLiteral", + "title": "IfConditionToFalseLiteral", "description": "Replace ```if (a > b) { }``` with ```if (false) { }```." }, { - "const" : "BooleanExpressionToTrue", - "title": "BooleanExpressionToTrueMutator", + "const" : "ConditionalExpression_TernaryCondition_ToTrueLiteral", + "title": "TernaryConditionToTrueLiteral", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = true ? 1 : 2;```." }, { - "const" : "BooleanExpressionToFalse", - "title": "BooleanExpressionToFalseMutator", + "const" : "ConditionalExpression_TernaryCondition_ToFalseLiteral", + "title": "ConditionalExpressionTernaryCondition_ToFalseLiteral", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = false ? 1 : 2;```." }, { - "const" : "SwitchToEmpty", - "title": "SwitchToEmptyMutator", + "const" : "ConditionalExpression_SwitchStatementBody_Removal", + "title": "SwitchStatementBodyRemoval", "description": "Replace ```switch(x) with switch()```." } ] @@ -495,63 +495,63 @@ "title": "EqualityOperator", "anyOf": [ { - "const" : "!==To===", - "title": "StrictDiffersToStrictEqualsMutator", + "const" : "EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator", + "title": "StrictInequalityOperatorToStrictEqualityOperator", "description": "Replace ```a !== b``` with ```a === b```." }, { - "const" : "!=To==", - "title": "DifferentToEqualsMutator", + "const" : "EqualityOperator_InequalityOperator_ToEqualityOperator", + "title": "InequalityOperatorToEqualityOperator", "description": "Replace ```a != b``` with ```a == b```." }, { - "const" : "<=To<", - "title": "SmallerOrEqualToSmallerMutator", + "const" : "EqualityOperator_LessThanEqualOperator_Boundary", + "title": "LessThanEqualOperatorBoundary", "description": "Replace ```a <= b``` with ```a < b```." }, { - "const" : "<=To>", - "title": "SmallerOrEqualToBiggerMutator", + "const" : "EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator", + "title": "LessThanEqualOperatorToGreatherThanOperator", "description": "Replace ```a <= b``` with ```a > b```." }, { - "const" : "=", - "title": "SmallerToBiggerOrEqualMutator", + "const" : "EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator", + "title": "LessThanOperatorToGreatherThanEqualOperator", "description": "Replace ```a < b``` with ```a >= b```." }, { - "const" : "===To!==", - "title": "StrictEqualsToStrictDiffersMutator", + "const" : "EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator", + "title": "StrictEqualityOperatorToStrictInequalityOperator", "description": "Replace ```a === b``` with ```a !== b```." }, { - "const" : "==To!=", - "title": "EqualsToDiffersMutator", + "const" : "EqualityOperator_EqualityOperator_ToInequalityOperator", + "title": "EqualityOperatorToInequalityOperator", "description": "Replace ```a == b``` with ```a != b```." }, { - "const" : ">=To<", - "title": "BiggerOrEqualToSmallerMutator", + "const" : "EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator", + "title": "GreatherThanEqualOperatorToLessThanOperator", "description": "Replace ```a >= b``` with ```a < b```." }, { - "const" : ">=To>", - "title": "BiggerOrEqualToBiggerMutator", + "const" : "EqualityOperator_GreatherThanEqualOperator_Boundary", + "title": "GreatherThanEqualOperatorBoundary", "description": "Replace ```a >= b``` with ```a > b```." }, { - "const" : ">To<=", - "title": "BiggerToSmallerOrEqualMutator", + "const" : "EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator", + "title": "GreaterThanOperatorToLessThanEqualOperator", "description": "Replace ```a > b``` with ```a <= b```." }, { - "const" : ">To>=", - "title": "BiggerToBiggerOrEqualMutator", + "const" : "EqualityOperator_GreaterThanOperator_Boundary", + "title": "GreaterThanOperatorBoundary", "description": "Replace ```a > b``` with ```a >= b```." } ] @@ -560,18 +560,18 @@ "title": "LogicalOperator", "anyOf": [ { - "const" : "&&To||", - "title": "AndToOrMutator", + "const" : "LogicalOperator_LogicalAndOperator_ToLogicalOrOperator", + "title": "LogicalAndOperatorToLogicalOrOperator", "description": "Replace ```a && b``` with ```a || b```." }, { - "const" : "||To&&", - "title": "OrToAndMutator", + "const" : "LogicalOperator_LogicalOrOperator_ToLogicalAndOperator", + "title": "LogicalOrOperatorToLogicalAndOperator", "description": "Replace ```a || b``` with ```a && b```." }, { - "const" : "??To&&", - "title": "CoalescingToAndMutator", + "const" : "LogicalOperator_NullishCoalescingOperator_ToLogicalAnd", + "title": "NullishCoalescingOperatorToLogicalAnd", "description": "Replace ```a ?? b``` with ```a && b```." } ] @@ -580,150 +580,150 @@ "title": "MethodExpression", "anyOf": [ { - "const": "removeCharAt", - "title": "removeCharAtMutator", + "const": "MethodExpression_charAtMethodCall_Removal", + "title": "charAtMethodCallRemoval", "description": "Remove ```charAt()``` call." }, { - "const": "endsWithToStartsWith", - "title": "endsWithToStartsWithMutator", + "const": "MethodExpression_endsWithMethodCall_TostartsWithMethodCall", + "title": "endsWithMethodCallTostartsWithMethodCall", "description": "Replace ```endsWith()``` with ```startsWith()```." }, { - "const": "startsWithToEndsWith", - "title": "startsWithToEndsWithMutator", - "description": "Replace ```endsWith()``` with ```startsWith()```." + "const": "MethodExpression_startsWithMethodCall_ToendsWithMethodCall", + "title": "startsWithMethodCallToendsWithMethodCall", + "description": "Replace ```startsWith()``` with ```endsWith()```." }, { - "const": "everyToSome", - "title": "everyToSomeMutator", + "const": "MethodExpression_everyMethodCall_TosomeMethodCall", + "title": "everyMethodCallTosomeMethodCall", "description": "Replace ```every()``` with ```some()```." }, { - "const": "someToEvery", - "title": "someToEveryMutator", - "description": "Replace ```every()``` with ```some()```." + "const": "MethodExpression_someMethodCall_ToeveryMethodCall", + "title": "someMethodCallToeveryMethodCall", + "description": "Replace ```some()``` with ```every()```." }, { - "const": "removeFilter", - "title": "removeFilterMutator", + "const": "MethodExpression_filterMethodCall_Removal", + "title": "filterMethodCallRemoval", "description": "Remove ```filter()``` call." }, { - "const": "removeReverse", - "title": "removeReverseMutator", + "const": "MethodExpression_reverseMethodCall_Removal", + "title": "reverseMethodCallRemoval", "description": "Remove ```reverse()``` call" }, { - "const": "removeSlice", - "title": "removeSliceMutator", + "const": "MethodExpression_sliceMethodCall_Removal", + "title": "sliceMethodCallRemoval", "description": "Remove ```slice()``` call." }, { - "const": "removeSort", - "title": "removeSortMutator", + "const": "MethodExpression_sortMethodCall_Removal", + "title": "sortMethodCallRemoval", "description": "Remove ```sort()``` call." }, { - "const": "removeSubstr", - "title": "removeSubstrMutator", + "const": "MethodExpression_substrMethodCall_Removal", + "title": "substrMethodCallRemoval", "description": "Remove ```substr()``` call." }, { - "const": "removeSubstring", - "title": "removeSubstringMutator", + "const": "MethodExpression_substringMethodCall_Removal", + "title": "substringMethodCallRemoval", "description": "Remove ```substring()``` call." }, { - "const": "toLocaleLowerCaseTotoLocaleUpperCase", - "title": "toLocaleLowerCaseTotoLocaleUpperCaseMutator", - "description": "Replace ```toLocalLowerCase()``` with ```toLocalUpperCase()```." + "const": "MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall", + "title": "toLocaleLowerCaseMethodCallTotoLocaleUpperCaseMethodCall", + "description": "Replace ```toLocaleLowerCase()``` with ```toLocaleUpperCase()```." }, { - "const": "toLocaleUpperCaseToToLocaleLowerCase", - "title": "toLocaleUpperCaseToToLocaleLowerCaseMutator", - "description": "Replace ```toLocalLowerCase()``` with ```toLocalUpperCase()```." + "const": "MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall", + "title": "toLocaleUpperCaseMethodCallTotoLocaleLowerCaseMethodCall", + "description": "Replace ```toLocaleUpperCase()``` with ```toLocaleLowerCase()```." }, { - "const": "toLowerCaseTotoUpperCase", - "title": "toLowerCaseTotoUpperCaseMutator", - "description": "Replace ```toLocalLowerCase()``` with ```toLocalUpperCase()```." + "const": "MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall", + "title": "toLowerCaseMethodCallTotoUpperCaseMethodCall", + "description": "Replace ```toLowerCase()``` with ```toUpperCase()```." }, { - "const": "toUpperCaseToToLowerCase", - "title": "toUpperCaseToToLowerCaseMutator", - "description": "Replace ```toLocalLowerCase()``` with ```toLocalUpperCase()```." + "const": "MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall", + "title": "toUpperCaseMethodCallTotoLowerCaseMethodCall", + "description": "Replace ```toUpperCase()``` with ```toLowerCase()```." }, { - "const": "removeTrim", - "title": "removeTrimMutator", + "const": "MethodExpression_trimMethodCall_Removal", + "title": "trimMethodCallRemoval", "description": "Remove ```trim()``` call." }, { - "const": "trimEndTotrimStart", - "title": "trimEndTotrimStartMutator", + "const": "MethodExpression_trimEndMethodCall_TotrimStartMethodCall", + "title": "trimEndMethodCallTotrimStartMethodCall", "description": "Replace ```trimEnd()``` with ```trimStart()```." }, { - "const": "trimStartToTrimEnd", - "title": "trimStartToTrimEndMutator", - "description": "Replace ```trimEnd()``` with ```trimStart()```." + "const": "MethodExpression_trimStartMethodCall_TotrimEndMutator", + "title": "trimStartMethodCallTotrimEndMutator", + "description": "Replace ```trimStart()``` with ```trimEnd()```." }, { - "const": "minToMax", - "title": "minToMaxMutator", + "const": "MethodExpression_minMethodCall_TomaxMethodCall", + "title": "minMethodCallTomaxMethodCall", "description": "Replace ```min()``` with ```max()```." }, { - "const": "maxToMin", - "title": "maxToMinMutator", - "description": "Replace ```min()``` with ```max()```." + "const": "MethodExpression_maxMethodCall_toMinMethodCall", + "title": "maxMethodCalltoMinMethodCall", + "description": "Replace ```max()``` with ```min()```." } ] }, "ObjectLiteral": { - "const": "ObjectLiteral", + "const": "ObjectLiteralPropertiesRemoval", "description": "Replace ```{ foo: 'bar' }``` with ```{ }```." }, "OptionalChaining": { "title": "OptionalChaining", "anyOf": [ { - "const": "OptionalMemberExpression", - "title": "OptionalMemberExpressionMutator", + "const": "OptionalChaining_OptionalMemberExpression_OptionRemoval", + "title": "OptionalMemberExpressionOptionRemoval", "description": "Replace ```foo?.bar``` with ```foo.bar```." }, { - "const": "OptionalCallExpression", - "title": "OptionalCallExpressionMutator", + "const": "OptionalChaining_OptionalCallExpression_OptionRemoval", + "title": "OptionalCallExpressionOptionRemoval", "description": "Replace ```foo?.()``` with ```foo()```." } ] }, "Regex": { - "const": "Regex" + "const": "Regex_Removal" }, "StringLiteral": { "title": "StringLiteral", "anyOf": [ { - "const": "EmptyString", - "title": "EmptyStringMutator", + "const": "StringLiteral_FilledStringLiteral_ToEmptyStringLiteral", + "title": "FilledStringLiteralToEmptyStringLiteral", "description": "Replace ```\"foo\"``` with ```\"\"```." }, { - "const": "FillString", - "title": "FillStringMutator", + "const": "StringLiteral_EmptyStringLiteral_ToFilledStringLiteral", + "title": "EmptyStringLiteralToFilledStringLiteral", "description": "Replace ```\"\"``` with ```\"Stryker was here!\"```." }, { - "const": "EmptyInterpolation", - "title": "EmptyInterpolation", + "const": "StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString", + "title": "FilledInterpolatedStringToEmptyInterpolatedString", "description": "Replace ```s\"foo ${bar}\"``` with ```s\"\"```." }, { - "const": "FillInterpolation", - "title": "FillInterpolation", + "const": "StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString", + "title": "EmptyInterpolatedStringToFilledInterpolatedString", "description": "Replace ```s\"\"``` with ```s\"Stryker was here!\"```." } ] @@ -732,18 +732,18 @@ "title": "UnaryOperator", "anyOf": [ { - "const": "+To-", - "title": "UnaryPlusToUnaryMinusMutator", + "const": "UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator", + "title": "UnaryPlusOperatorToUnaryMinusOperator", "description": "Replace ```+a``` with ```-a```." }, { - "const": "-To+", - "title": "UnaryMinusToUnaryPlusMutator", + "const": "UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator", + "title": "UnaryMinusOperatorToUnaryPlusOperator", "description": "Replace ```-a``` with ```+a.```" }, { - "const": "Remove~", - "title": "RemoveTildeMutator", + "const": "UnaryOperator_BitwiseOrOperator_Removal", + "title": "BitwiseOrOperatorRemoval", "description": "" } ] @@ -752,23 +752,23 @@ "title": "UpdateOperator", "anyOf": [ { - "const": "Post++To--", - "title": "PostPlusToMinusMutator", + "const": "PostfixIncrementOperatorToPostfixDecrementOperator", + "title": "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator", "description": "Replace ```a++``` with ```a--```." }, { - "const": "Post--To++", - "title": "PostMinusToPlusMutator", + "const": "PostfixDecrementOperatorToPostfixIncrementOperator", + "title": "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", "description": "Replace ```a--``` with ```a++```." }, { - "const": "Pre++To--", - "title": "PrePlusToMinusMutator", + "const": "PrefixIncrementOperatorToPrefixDecrementOperator", + "title": "UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator", "description": "Replace ```++a``` with ```--a```." }, { - "const": "Pre--To++", - "title": "PreMinusToPlusMutator", + "const": "PrefixDecrementOperatorToPrefixIncrementOperator", + "title": "UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator", "description": "Replace ```--a``` with ```++a```." } ] From 07cd3cd2910b137c81bdad6ef57800bf1e586a3b Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 15:38:47 +0100 Subject: [PATCH 02/13] Change negation to substraction in arhitmeticop --- packages/api/schema/stryker-core.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index 7221c27606..0058abc03d 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -317,13 +317,13 @@ "description": "Replace ```a / b``` with ```a * b```." }, { - "const" : "ArithmeticOperator_AdditionOperator_ToNegationOperator", - "title": "AdditionOperatorToNegationOperator", + "const" : "ArithmeticOperator_AdditionOperator_ToSubtractionOperator", + "title": "AdditionOperatorToSubtractionOperator", "description": "Replace ```a + b``` with ```a - b```." }, { - "const" : "ArithmeticOperator_NegationOperator_ToAdditionOperator", - "title": "NegationOperatorToAdditionOperator", + "const" : "ArithmeticOperator_SubtractionOperator_ToAdditionOperator", + "title": "SubtractionOperatorToAdditionOperator", "description": "Replace ```a - b``` with ```a + b```." } ] From 4bd9bb3953568b54afe4f1f8c09884cfb56b62d3 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 19:53:00 +0100 Subject: [PATCH 03/13] Rename mutators, stable --- packages/api/schema/stryker-core.json | 23 +-- .../default-mutation-levels.json | 184 ++++++++++++++---- .../src/mutation-level/mutation-level.ts | 2 + .../mutators/arithmetic-operator-mutator.ts | 10 +- .../src/mutators/array-declaration-mutator.ts | 23 ++- .../src/mutators/arrow-function-mutator.ts | 2 +- .../mutators/assignment-operator-mutator.ts | 24 +-- .../src/mutators/block-statement-mutator.ts | 2 +- .../src/mutators/boolean-literal-mutator.ts | 6 +- .../conditional-expression-mutator.ts | 16 +- .../src/mutators/equality-operator-mutator.ts | 24 +-- .../src/mutators/logical-operator-mutator.ts | 8 +- .../src/mutators/method-expression-mutator.ts | 40 ++-- .../src/mutators/object-literal-mutator.ts | 2 +- .../src/mutators/optional-chaining-mutator.ts | 4 +- .../src/mutators/regex-mutator.ts | 2 +- .../src/mutators/string-literal-mutator.ts | 11 +- .../src/mutators/unary-operator-mutator.ts | 6 +- .../src/mutators/update-operator-mutator.ts | 28 ++- .../arithmatic-operator-mutator.spec.ts | 9 +- .../array-declaration-mutator.spec.ts | 13 +- .../mutators/arrow-function-mutator.spec.ts | 2 +- .../assignment-operator-mutator.spec.ts | 33 ++-- .../mutators/block-statement-mutator.spec.ts | 2 +- .../mutators/boolean-literal-mutator.spec.ts | 4 +- .../conditional-expression-mutator.spec.ts | 35 +++- .../equality-operator-mutator.spec.ts | 20 +- .../mutators/logical-operator-mutator.spec.ts | 9 +- .../method-expression-mutator.spec.ts | 15 +- .../mutators/object-literal-mutator.spec.ts | 2 +- .../optional-chaining-mutator.spec.ts | 8 +- .../test/unit/mutators/regex-mutator.spec.ts | 2 +- .../mutators/string-literal-mutator.spec.ts | 8 +- .../mutators/unary-operator-mutator.spec.ts | 9 +- .../mutators/update-operator-mutator.spec.ts | 29 ++- 35 files changed, 426 insertions(+), 191 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index 0058abc03d..85d0c13df4 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -271,6 +271,7 @@ { "$ref": "#/definitions/BooleanLiteral" }, { "$ref": "#/definitions/ConditionalExpression" }, { "$ref": "#/definitions/EqualityOperator" }, + { "$ref": "#/definitions/LogicalOperator"}, { "$ref": "#/definitions/MethodExpression" }, { "$ref": "#/definitions/ObjectLiteral" }, { "$ref": "#/definitions/OptionalChaining" }, @@ -475,12 +476,12 @@ "description": "Replace ```if (a > b) { }``` with ```if (false) { }```." }, { - "const" : "ConditionalExpression_TernaryCondition_ToTrueLiteral", + "const" : "ConditionalExpression_BooleanExpression_ToTrueLiteral", "title": "TernaryConditionToTrueLiteral", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = true ? 1 : 2;```." }, { - "const" : "ConditionalExpression_TernaryCondition_ToFalseLiteral", + "const" : "ConditionalExpression_BooleanExpression_ToFalseLiteral", "title": "ConditionalExpressionTernaryCondition_ToFalseLiteral", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = false ? 1 : 2;```." }, @@ -682,7 +683,7 @@ ] }, "ObjectLiteral": { - "const": "ObjectLiteralPropertiesRemoval", + "const": "ObjectLiteral_PropertiesRemoval", "description": "Replace ```{ foo: 'bar' }``` with ```{ }```." }, "OptionalChaining": { @@ -752,23 +753,23 @@ "title": "UpdateOperator", "anyOf": [ { - "const": "PostfixIncrementOperatorToPostfixDecrementOperator", - "title": "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator", + "const": "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator", + "title": "PostfixIncrementOperatorToPostfixDecrementOperator", "description": "Replace ```a++``` with ```a--```." }, { - "const": "PostfixDecrementOperatorToPostfixIncrementOperator", - "title": "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", + "const": "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", + "title": "PostfixDecrementOperatorToPostfixIncrementOperator", "description": "Replace ```a--``` with ```a++```." }, { - "const": "PrefixIncrementOperatorToPrefixDecrementOperator", - "title": "UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator", + "const": "UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator", + "title": "PrefixIncrementOperatorToPrefixDecrementOperator", "description": "Replace ```++a``` with ```--a```." }, { - "const": "PrefixDecrementOperatorToPrefixIncrementOperator", - "title": "UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator", + "const": "UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator", + "title": "PrefixDecrementOperatorToPrefixIncrementOperator", "description": "Replace ```--a``` with ```++a```." } ] diff --git a/packages/instrumenter/src/mutation-level/default-mutation-levels.json b/packages/instrumenter/src/mutation-level/default-mutation-levels.json index a4b9f743a0..1323464177 100644 --- a/packages/instrumenter/src/mutation-level/default-mutation-levels.json +++ b/packages/instrumenter/src/mutation-level/default-mutation-levels.json @@ -1,44 +1,152 @@ { - "mutationLevels": [ - { - "name": "level1", - "UpdateOperator": ["Post--To++"], - "EqualityOperator": ["<=To>","<=To<", "==To!=", "!=To==",">=To<"], - "ArrayDeclaration": ["EmptyArrayConstructor"], - "ConditionalExpression": ["BooleanExpressionToFalse", "BooleanExpressionToTrue"], - "UnaryOperator": ["+To-"], - "AssignmentOperator": ["??=To&&="], - "ArithmeticOperator": ["/To*","%To*","*To/"], - "OptionalChaining": ["OptionalCallExpression","OptionalMemberExpression"] + "mutationLevels":[ + { + "name":"level1", + "UpdateOperator":[ + "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator" + ], + "EqualityOperator":[ + "EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator", + "EqualityOperator_LessThanEqualOperator_Boundary", + "EqualityOperator_EqualityOperator_ToInequalityOperator", + "EqualityOperator_InequalityOperator_ToEqualityOperator", + "EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator" + ], + "ArrayDeclaration":[ + "ArrayDeclaration_ArrayConstructor_ItemsRemoval" + ], + "ConditionalExpression":[ + "ConditionalExpression_BooleanExpression_ToFalseLiteral", + "ConditionalExpression_BooleanExpression_ToTrueLiteral" + ], + "UnaryOperator":[ + "UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator" + ], + "AssignmentOperator":[ + "AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment" + ], + "ArithmeticOperator":[ + "ArithmeticOperator_DivisionOperator_ToMultiplicationOperator", + "ArithmeticOperator_RemainderOperator_ToMultiplicationOperator", + "ArithmeticOperator_MultiplicationOperator_ToDivisionOperator" + ], + "OptionalChaining":[ + "OptionalChaining_OptionalCallExpression_OptionRemoval", + "OptionalChaining_OptionalMemberExpression_OptionRemoval" + ] }, { - "name": "level2", - "UpdateOperator": ["Post--To++", "Post++To--"], - "EqualityOperator": ["<=To>","<=To<", "==To!=", "!=To==",">=To<","=",">=To>", "!==To===", ">To>="], - "ArrayDeclaration": ["EmptyArrayConstructor"], - "ConditionalExpression": ["BooleanExpressionToFalse", "BooleanExpressionToTrue","SwitchToEmpty" ], - "UnaryOperator": ["+To-"], - "AssignmentOperator": ["??=To&&="], - "ArithmeticOperator": ["/To*","%To*","*To/", "+To-","-To+"], - "OptionalChaining": ["OptionalCallExpression","OptionalMemberExpression"], - "StringLiteral": ["FillString", "FillInterpolation"], - "Regex": true, - "BooleanLiteral": ["TrueToFalse"] + "name":"level2", + "UpdateOperator":[ + "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", + "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator" + ], + "EqualityOperator":[ + "EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator", + "EqualityOperator_LessThanEqualOperator_Boundary", + "EqualityOperator_EqualityOperator_ToInequalityOperator", + "EqualityOperator_InequalityOperator_ToEqualityOperator", + "EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator", + "EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator", + "EqualityOperator_GreatherThanEqualOperator_Boundary", + "EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator", + "EqualityOperator_GreaterThanOperator_Boundary" + ], + "ArrayDeclaration":[ + "ArrayDeclaration_ArrayConstructor_ItemsRemoval" + ], + "ConditionalExpression":[ + "ConditionalExpression_BooleanExpression_ToFalseLiteral", + "ConditionalExpression_BooleanExpression_ToTrueLiteral", + "ConditionalExpression_SwitchStatementBody_Removal" + ], + "UnaryOperator":[ + "UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator" + ], + "AssignmentOperator":[ + "AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment" + ], + "ArithmeticOperator":[ + "ArithmeticOperator_DivisionOperator_ToMultiplicationOperator", + "ArithmeticOperator_RemainderOperator_ToMultiplicationOperator", + "ArithmeticOperator_MultiplicationOperator_ToDivisionOperator", + "ArithmeticOperator_AdditionOperator_ToSubtractionOperator", + "ArithmeticOperator_SubtractionOperator_ToAdditionOperator" + ], + "OptionalChaining":[ + "OptionalChaining_OptionalCallExpression_OptionRemoval", + "OptionalChaining_OptionalMemberExpression_OptionRemoval" + ], + "StringLiteral":[ + "StringLiteral_EmptyStringLiteral_ToFilledStringLiteral", + "StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString" + ], + "Regex":[ + "Regex_Removal" + ], + "BooleanLiteral":[ + "BooleanLiteral_TrueLiteral_ToFalseLiteral" + ] }, { - "name": "level3", - "UpdateOperator": ["Post--To++", "Post++To--"], - "EqualityOperator": ["<=To>","<=To<", "==To!=", "!=To==",">=To<","=",">=To>", "!==To===", ">To>=", "To<="], - "ArrayDeclaration": ["EmptyArrayConstructor","EmptyArray", "FilledArray"], - "ConditionalExpression": ["BooleanExpressionToFalse", "BooleanExpressionToTrue","SwitchToEmpty" ], - "UnaryOperator": ["+To-", "-To+"], - "AssignmentOperator": ["??=To&&="], - "ArithmeticOperator": ["/To*","%To*","*To/", "+To-","-To+"], - "OptionalChaining": ["OptionalCallExpression","OptionalMemberExpression"], - "StringLiteral": ["FillString", "FillInterpolation"], - "Regex": true, - "BooleanLiteral": ["TrueToFalse", "FalseToTrue", "RemoveNegation"] + "name":"level3", + "UpdateOperator":[ + "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", + "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator" + ], + "EqualityOperator":[ + "EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator", + "EqualityOperator_LessThanEqualOperator_Boundary", + "EqualityOperator_EqualityOperator_ToInequalityOperator", + "EqualityOperator_InequalityOperator_ToEqualityOperator", + "EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator", + "EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator", + "EqualityOperator_GreatherThanEqualOperator_Boundary", + "EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator", + "EqualityOperator_GreaterThanOperator_Boundary", + "EqualityOperator_LessThanOperator_Boundary", + "EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator" + ], + "ArrayDeclaration":[ + "ArrayDeclaration_ArrayConstructor_ItemsRemoval", + "EmptyArray", + "FilledArray" + ], + "ConditionalExpression":[ + "ConditionalExpression_BooleanExpression_ToFalseLiteral", + "ConditionalExpression_BooleanExpression_ToTrueLiteral", + "ConditionalExpression_SwitchStatementBody_Removal" + ], + "UnaryOperator":[ + "UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator", + "ArithmeticOperator_SubtractionOperator_ToAdditionOperator" + ], + "AssignmentOperator":[ + "AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment" + ], + "ArithmeticOperator":[ + "ArithmeticOperator_DivisionOperator_ToMultiplicationOperator", + "ArithmeticOperator_RemainderOperator_ToMultiplicationOperator", + "ArithmeticOperator_MultiplicationOperator_ToDivisionOperator", + "ArithmeticOperator_AdditionOperator_ToSubtractionOperator", + "ArithmeticOperator_SubtractionOperator_ToAdditionOperator" + ], + "OptionalChaining":[ + "OptionalChaining_OptionalCallExpression_OptionRemoval", + "OptionalChaining_OptionalMemberExpression_OptionRemoval" + ], + "StringLiteral":[ + "StringLiteral_EmptyStringLiteral_ToFilledStringLiteral", + "StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString" + ], + "Regex":[ + "Regex_Removal" + ], + "BooleanLiteral":[ + "BooleanLiteral_TrueLiteral_ToFalseLiteral", + "BooleanLiteral_FalseLiteral_ToTrueLiteral", + "BooleanLiteral_LogicalNot_Removal" + ] } - ] - } - \ No newline at end of file + ] +} diff --git a/packages/instrumenter/src/mutation-level/mutation-level.ts b/packages/instrumenter/src/mutation-level/mutation-level.ts index 24aa991c21..0dad6606b2 100644 --- a/packages/instrumenter/src/mutation-level/mutation-level.ts +++ b/packages/instrumenter/src/mutation-level/mutation-level.ts @@ -9,6 +9,7 @@ import { BooleanLiteral, ConditionalExpression, EqualityOperator, + LogicalOperator, MethodExpression, ObjectLiteral, OptionalChaining, @@ -39,6 +40,7 @@ export interface MutationLevel { BooleanLiteral?: BooleanLiteral[]; ConditionalExpression?: ConditionalExpression[]; EqualityOperator?: EqualityOperator[]; + LogicalOperator?: LogicalOperator[]; MethodExpression?: MethodExpression[]; ObjectLiteral?: ObjectLiteral[]; OptionalChaining?: OptionalChaining[]; diff --git a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts index cbe6a11fb5..1ff89f819a 100644 --- a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts @@ -7,11 +7,11 @@ import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; const operators: NodeMutatorConfiguration = { - '+': { replacement: '-', mutationName: '+To-' }, - '-': { replacement: '+', mutationName: '-To+' }, - '*': { replacement: '/', mutationName: '*To/' }, - '/': { replacement: '*', mutationName: '/To*' }, - '%': { replacement: '*', mutationName: '%To*' }, + '+': { replacement: '-', mutationName: 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator' }, + '-': { replacement: '+', mutationName: 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator' }, + '*': { replacement: '/', mutationName: 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator' }, + '/': { replacement: '*', mutationName: 'ArithmeticOperator_DivisionOperator_ToMultiplicationOperator' }, + '%': { replacement: '*', mutationName: 'ArithmeticOperator_RemainderOperator_ToMultiplicationOperator' }, }; export const arithmeticOperatorMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/array-declaration-mutator.ts b/packages/instrumenter/src/mutators/array-declaration-mutator.ts index c29e2110e7..bef49be984 100644 --- a/packages/instrumenter/src/mutators/array-declaration-mutator.ts +++ b/packages/instrumenter/src/mutators/array-declaration-mutator.ts @@ -8,10 +8,13 @@ import { NodeMutator } from './node-mutator.js'; const { types } = babel; const operators: NodeMutatorConfiguration = { - EmptyArray: { replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), mutationName: 'EmptyArray' }, - EmptyArrayConstructor: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'EmptyArrayConstructor' }, - FilledArray: { replacement: types.arrayExpression(), mutationName: 'FilledArray' }, - FilledArrayConstructor: { replacement: [], mutationName: 'FilledArrayConstructor' }, + FilledArray: { + replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), + mutationName: 'ArrayDeclaration_ArrayLiteral_Fill', + }, + FilledArrayConstructor: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'ArrayDeclaration_ArrayConstructor_Fill' }, + EmptyArray: { replacement: types.arrayExpression(), mutationName: 'ArrayDeclaration_ArrayLiteral_ItemsRemoval' }, + EmptyArrayConstructor: { replacement: [], mutationName: 'ArrayDeclaration_ArrayConstructor_ItemsRemoval' }, }; export const arrayDeclarationMutator: NodeMutator = { @@ -20,7 +23,7 @@ export const arrayDeclarationMutator: NodeMutator = { *mutate(path, levelMutations) { // The check of the [] construct in code if (path.isArrayExpression() && isArrayInLevel(path.node, levelMutations)) { - const replacement = path.node.elements.length > 0 ? operators.FilledArray.replacement : operators.EmptyArray.replacement; + const replacement = path.node.elements.length > 0 ? operators.EmptyArray.replacement : operators.FilledArray.replacement; yield replacement; } // Check for the new Array() construct in code @@ -31,7 +34,7 @@ export const arrayDeclarationMutator: NodeMutator = { isArrayConstructorInLevel(path.node, levelMutations) ) { const mutatedCallArgs: babel.types.Expression[] = - path.node.arguments.length > 0 ? operators.FilledArrayConstructor.replacement : operators.EmptyArrayConstructor.replacement; + path.node.arguments.length > 0 ? operators.EmptyArrayConstructor.replacement : operators.FilledArrayConstructor.replacement; const replacement = types.isNewExpression(path.node) ? types.newExpression(deepCloneNode(path.node.callee), mutatedCallArgs) @@ -48,8 +51,8 @@ function isArrayInLevel(node: babel.types.ArrayExpression, levelMutations: strin } return ( - (levelMutations.includes(operators.FilledArray.mutationName) && node.elements.length > 0) || - (levelMutations.includes(operators.EmptyArray.mutationName) && node.elements.length === 0) + (levelMutations.includes(operators.EmptyArray.mutationName) && node.elements.length > 0) || + (levelMutations.includes(operators.FilledArray.mutationName) && node.elements.length === 0) ); } @@ -60,7 +63,7 @@ function isArrayConstructorInLevel(node: babel.types.CallExpression | babel.type } return ( - (levelMutations.includes(operators.FilledArrayConstructor.mutationName) && node.arguments.length > 0) || - (levelMutations.includes(operators.EmptyArrayConstructor.mutationName) && node.arguments.length === 0) + (levelMutations.includes(operators.EmptyArrayConstructor.mutationName) && node.arguments.length > 0) || + (levelMutations.includes(operators.FilledArrayConstructor.mutationName) && node.arguments.length === 0) ); } diff --git a/packages/instrumenter/src/mutators/arrow-function-mutator.ts b/packages/instrumenter/src/mutators/arrow-function-mutator.ts index 541a2ee89c..b2736f2941 100644 --- a/packages/instrumenter/src/mutators/arrow-function-mutator.ts +++ b/packages/instrumenter/src/mutators/arrow-function-mutator.ts @@ -20,5 +20,5 @@ export const arrowFunctionMutator: NodeMutator = { }; function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.length > 0; + return operations === undefined || operations.includes('ArrowFunction_Removal'); } diff --git a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts index 8cc98d78ea..77bd98ee3c 100644 --- a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts @@ -7,18 +7,18 @@ import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './index.js'; const operators: NodeMutatorConfiguration = { - '+=': { replacement: '-=', mutationName: '+=To-=' }, - '-=': { replacement: '+=', mutationName: '-=To+=' }, - '*=': { replacement: '/=', mutationName: '*=To/=' }, - '/=': { replacement: '*=', mutationName: '/=To*=' }, - '%=': { replacement: '*=', mutationName: '%=To*=' }, - '<<=': { replacement: '>>=', mutationName: '<<=To>>=' }, - '>>=': { replacement: '<<=', mutationName: '>>=To<<=' }, - '&=': { replacement: '|=', mutationName: '&=To|=' }, - '|=': { replacement: '&=', mutationName: '|=To&=' }, - '&&=': { replacement: '||=', mutationName: '&&=To||=' }, - '||=': { replacement: '&&=', mutationName: '||=To&&=' }, - '??=': { replacement: '&&=', mutationName: '??=To&&=' }, + '+=': { replacement: '-=', mutationName: 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment' }, + '-=': { replacement: '+=', mutationName: 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment' }, + '*=': { replacement: '/=', mutationName: 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment' }, + '/=': { replacement: '*=', mutationName: 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment' }, + '%=': { replacement: '*=', mutationName: 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment' }, + '<<=': { replacement: '>>=', mutationName: 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment' }, + '>>=': { replacement: '<<=', mutationName: 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment' }, + '&=': { replacement: '|=', mutationName: 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment' }, + '|=': { replacement: '&=', mutationName: 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment' }, + '&&=': { replacement: '||=', mutationName: 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment' }, + '||=': { replacement: '&&=', mutationName: 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment' }, + '??=': { replacement: '&&=', mutationName: 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment' }, }; const stringTypes = Object.freeze(['StringLiteral', 'TemplateLiteral']); diff --git a/packages/instrumenter/src/mutators/block-statement-mutator.ts b/packages/instrumenter/src/mutators/block-statement-mutator.ts index a7a7153cf4..c95ca03ab5 100644 --- a/packages/instrumenter/src/mutators/block-statement-mutator.ts +++ b/packages/instrumenter/src/mutators/block-statement-mutator.ts @@ -71,5 +71,5 @@ function hasSuperExpressionOnFirstLine(constructor: NodePath 0; + return operations === undefined || operations.includes('BlockStatement_Removal'); } diff --git a/packages/instrumenter/src/mutators/boolean-literal-mutator.ts b/packages/instrumenter/src/mutators/boolean-literal-mutator.ts index 61a1c82f34..bf227f8755 100644 --- a/packages/instrumenter/src/mutators/boolean-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/boolean-literal-mutator.ts @@ -9,9 +9,9 @@ import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './index.js'; const operators: NodeMutatorConfiguration = { - true: { replacement: false, mutationName: 'TrueToFalse' }, - false: { replacement: true, mutationName: 'FalseToTrue' }, - '!': { replacement: '', mutationName: 'RemoveNegation' }, + true: { replacement: false, mutationName: 'BooleanLiteral_TrueLiteral_ToFalseLiteral' }, + false: { replacement: true, mutationName: 'BooleanLiteral_FalseLiteral_ToTrueLiteral' }, + '!': { replacement: '', mutationName: 'BooleanLiteral_LogicalNot_Removal' }, }; export const booleanLiteralMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts index a0c795d985..306444baab 100644 --- a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts @@ -11,14 +11,14 @@ const booleanOperators = Object.freeze(['!=', '!==', '&&', '<', '<=', '==', '=== const { types } = babel; const operators: NodeMutatorConfiguration = { - BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'BooleanExpressionToFalse' }, - BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'BooleanExpressionToTrue' }, - DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'DoWhileLoopToFalse' }, - ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ForLoopToFalse' }, - IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'IfToFalse' }, - IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'IfToTrue' }, - WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'WhileLoopToFalse' }, - SwitchToEmpty: { replacement: [], mutationName: 'SwitchToEmpty' }, + BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_BooleanExpression_ToFalseLiteral' }, + BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_BooleanExpression_ToTrueLiteral' }, + DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral' }, + ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_ForLoopCondition_ToFalseLiteral' }, + IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_IfCondition_ToFalseLiteral' }, + IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_IfCondition_ToTrueLiteral' }, + WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral' }, + SwitchToEmpty: { replacement: [], mutationName: 'ConditionalExpression_SwitchStatementBody_Removal' }, }; export const conditionalExpressionMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/equality-operator-mutator.ts b/packages/instrumenter/src/mutators/equality-operator-mutator.ts index 3fa6247132..f89d64e822 100644 --- a/packages/instrumenter/src/mutators/equality-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/equality-operator-mutator.ts @@ -8,25 +8,25 @@ const { types: t } = babel; const operators: NodeMutatorMultiConfiguration = { '<': [ - { replacement: '<=', mutationName: '=', mutationName: '=' }, + { replacement: '<=', mutationName: 'EqualityOperator_LessThanOperator_Boundary' }, + { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, ], '<=': [ - { replacement: '<', mutationName: '<=To<' }, - { replacement: '>', mutationName: '<=To>' }, + { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, + { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, ], '>': [ - { replacement: '>=', mutationName: '>To>=' }, - { replacement: '<=', mutationName: '>To<=' }, + { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, + { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, ], '>=': [ - { replacement: '>', mutationName: '>=To>' }, - { replacement: '<', mutationName: '>=To<' }, + { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, + { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, ], - '==': [{ replacement: '!=', mutationName: '==To!=' }], - '!=': [{ replacement: '==', mutationName: '!=To==' }], - '===': [{ replacement: '!==', mutationName: '===To!==' }], - '!==': [{ replacement: '===', mutationName: '!==To===' }], + '==': [{ replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }], + '!=': [{ replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }], + '===': [{ replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }], + '!==': [{ replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }], }; function isEqualityOperator(operator: string): operator is keyof typeof operators { diff --git a/packages/instrumenter/src/mutators/logical-operator-mutator.ts b/packages/instrumenter/src/mutators/logical-operator-mutator.ts index a7ff18f273..32a59a6413 100644 --- a/packages/instrumenter/src/mutators/logical-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/logical-operator-mutator.ts @@ -4,9 +4,9 @@ import { deepCloneNode } from '../util/index.js'; import { NodeMutator } from './index.js'; const operators: NodeMutatorConfiguration = { - '&&': { replacement: '||', mutationName: '&&To||' }, - '||': { replacement: '&&', mutationName: '||To&&' }, - '??': { replacement: '&&', mutationName: '??To&&' }, + '&&': { replacement: '||', mutationName: 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator' }, + '||': { replacement: '&&', mutationName: 'LogicalOperator_LogicalOrOperator_ToLogicalAndOperator' }, + '??': { replacement: '&&', mutationName: 'LogicalOperator_NullishCoalescingOperator_ToLogicalAnd' }, }; export const logicalOperatorMutator: NodeMutator = { @@ -28,5 +28,5 @@ function isSupported(operator: string): operator is keyof typeof operators { } function isInMutationLevel(operator: string, levelMutations: string[] | undefined): operator is keyof typeof operators { - return levelMutations === undefined || levelMutations.some((op) => op.startsWith(operator)); + return levelMutations === undefined || levelMutations.includes(operators[operator].mutationName); } diff --git a/packages/instrumenter/src/mutators/method-expression-mutator.ts b/packages/instrumenter/src/mutators/method-expression-mutator.ts index d43847919b..2daf0df307 100644 --- a/packages/instrumenter/src/mutators/method-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/method-expression-mutator.ts @@ -10,26 +10,26 @@ const { types } = babel; // prettier-ignore const operators: NodeMutatorConfiguration = { - 'charAt': { replacement: null, mutationName: 'removeCharAt' }, - 'endsWith': { replacement: 'startsWith', mutationName: 'endsWithToStartsWith' }, - 'startsWith': { replacement: 'endsWith', mutationName: 'startsWithToEndsWith' }, - 'every': { replacement: 'some', mutationName: 'everyToSome' }, - 'some': { replacement: 'every', mutationName: 'someToEvery' }, - 'filter': { replacement: null, mutationName: 'removeFilter' }, - 'reverse': { replacement: null, mutationName: 'removeReverse' }, - 'slice': { replacement: null, mutationName: 'removeSlice' }, - 'sort': { replacement: null, mutationName: 'removeSort' }, - 'substr': { replacement: null, mutationName: 'removeSubstr' }, - 'substring': { replacement: null, mutationName: 'removeSubstring' }, - 'toLocaleLowerCase': { replacement: 'toLocaleUpperCase', mutationName: 'toLocaleLowerCaseToToLocaleUpperCase' }, - 'toLocaleUpperCase': { replacement: 'toLocaleLowerCase', mutationName: 'toLocaleUpperCaseToToLocaleLowerCase' }, - 'toLowerCase': { replacement: 'toUpperCase', mutationName: 'toLowerCaseToToUpperCase' }, - 'toUpperCase': { replacement: 'toLowerCase', mutationName: 'toUpperCaseToToLowerCase' }, - 'trim': { replacement: null, mutationName: 'removeTrim' }, - 'trimEnd': { replacement: 'trimStart', mutationName: 'trimEndToTrimStart' }, - 'trimStart': { replacement: 'trimEnd', mutationName: 'trimStartToTrimEnd' }, - 'min': { replacement: 'max', mutationName: 'minToMax' }, - 'max': { replacement: 'min', mutationName: 'maxToMin' }, + 'charAt': { replacement: null, mutationName: 'MethodExpression_charAtMethodCall_Removal' }, + 'endsWith': { replacement: 'startsWith', mutationName: 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall' }, + 'startsWith': { replacement: 'endsWith', mutationName: 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall' }, + 'every': { replacement: 'some', mutationName: 'MethodExpression_everyMethodCall_TosomeMethodCall' }, + 'some': { replacement: 'every', mutationName: 'MethodExpression_someMethodCall_ToeveryMethodCall' }, + 'filter': { replacement: null, mutationName: 'MethodExpression_filterMethodCall_Removal' }, + 'reverse': { replacement: null, mutationName: 'MethodExpression_reverseMethodCall_Removal' }, + 'slice': { replacement: null, mutationName: 'MethodExpression_sliceMethodCall_Removal' }, + 'sort': { replacement: null, mutationName: 'MethodExpression_sortMethodCall_Removal' }, + 'substr': { replacement: null, mutationName: 'MethodExpression_substrMethodCall_Removal' }, + 'substring': { replacement: null, mutationName: 'MethodExpression_substringMethodCall_Removal' }, + 'toLocaleLowerCase': { replacement: 'toLocaleUpperCase', mutationName: 'MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall' }, + 'toLocaleUpperCase': { replacement: 'toLocaleLowerCase', mutationName: 'MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall' }, + 'toLowerCase': { replacement: 'toUpperCase', mutationName: 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall' }, + 'toUpperCase': { replacement: 'toLowerCase', mutationName: 'MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall' }, + 'trim': { replacement: null, mutationName: 'MethodExpression_trimMethodCall_Removal' }, + 'trimEnd': { replacement: 'trimStart', mutationName: 'MethodExpression_trimEndMethodCall_TotrimStartMethodCall' }, + 'trimStart': { replacement: 'trimEnd', mutationName: 'MethodExpression_trimStartMethodCall_TotrimEndMutator' }, + 'min': { replacement: 'max', mutationName: 'MethodExpression_minMethodCall_TomaxMethodCall' }, + 'max': { replacement: 'min', mutationName: 'MethodExpression_maxMethodCall_toMinMethodCall' }, }; export const methodExpressionMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/object-literal-mutator.ts b/packages/instrumenter/src/mutators/object-literal-mutator.ts index 8660fca0e0..badb9490b4 100644 --- a/packages/instrumenter/src/mutators/object-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/object-literal-mutator.ts @@ -15,5 +15,5 @@ export const objectLiteralMutator: NodeMutator = { }; function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.length > 0; + return operations === undefined || operations.includes('ObjectLiteral_PropertiesRemoval'); } diff --git a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts index baa392e0dd..885d1aaa82 100644 --- a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts +++ b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts @@ -20,8 +20,8 @@ const { types: t } = babel; */ const operators: NodeMutatorConfiguration = { - OptionalCallExpression: { mutationName: 'OptionalCallExpression' }, - OptionalMemberExpression: { mutationName: 'OptionalMemberExpression' }, + OptionalCallExpression: { mutationName: 'OptionalChaining_OptionalCallExpression_OptionRemoval' }, + OptionalMemberExpression: { mutationName: 'OptionalChaining_OptionalMemberExpression_OptionRemoval' }, }; export const optionalChainingMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/regex-mutator.ts b/packages/instrumenter/src/mutators/regex-mutator.ts index 310d7edd28..8eccda4dd5 100644 --- a/packages/instrumenter/src/mutators/regex-mutator.ts +++ b/packages/instrumenter/src/mutators/regex-mutator.ts @@ -61,5 +61,5 @@ function mutatePattern(pattern: string, flags: string | undefined): string[] { } function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.length > 0; + return operations === undefined || operations.includes('Regex_Removal'); } diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index d76a043d78..fbc706e30c 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -7,12 +7,15 @@ import { NodeMutator } from './node-mutator.js'; const { types } = babel; const operators: NodeMutatorConfiguration = { - FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'FillString' }, - EmptyString: { replacement: types.stringLiteral(''), mutationName: 'EmptyString' }, - EmptyInterpolation: { replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), mutationName: 'EmptyInterpolation' }, + FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'StringLiteral_EmptyStringLiteral_ToFilledStringLiteral' }, + EmptyString: { replacement: types.stringLiteral(''), mutationName: 'StringLiteral_FilledStringLiteral_ToEmptyStringLiteral' }, + EmptyInterpolation: { + replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), + mutationName: 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString', + }, FillInterpolation: { replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), - mutationName: 'FillInterpolation', + mutationName: 'StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString', }, }; diff --git a/packages/instrumenter/src/mutators/unary-operator-mutator.ts b/packages/instrumenter/src/mutators/unary-operator-mutator.ts index a5fd612402..68c416bc7a 100644 --- a/packages/instrumenter/src/mutators/unary-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/unary-operator-mutator.ts @@ -9,9 +9,9 @@ import { NodeMutator } from './index.js'; const { types } = babel; const operators: NodeMutatorConfiguration = { - '+': { replacement: '-', mutationName: '+To-' }, - '-': { replacement: '+', mutationName: '-To+' }, - '~': { replacement: '', mutationName: 'remove~' }, + '+': { replacement: '-', mutationName: 'UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator' }, + '-': { replacement: '+', mutationName: 'UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator' }, + '~': { replacement: '', mutationName: 'UnaryOperator_BitwiseOrOperator_Removal' }, }; export const unaryOperatorMutator: NodeMutator = { diff --git a/packages/instrumenter/src/mutators/update-operator-mutator.ts b/packages/instrumenter/src/mutators/update-operator-mutator.ts index ab7abedd9e..b59748bf2a 100644 --- a/packages/instrumenter/src/mutators/update-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/update-operator-mutator.ts @@ -9,10 +9,22 @@ import { NodeMutator } from './index.js'; const { types } = babel; const operators: NodeMutatorConfiguration = { - 'Post++To--': { replacement: '--', mutationName: 'Post++To--' }, - 'Post--To++': { replacement: '++', mutationName: 'Post--To++' }, - 'Pre++To--': { replacement: '--', mutationName: 'Pre++To--' }, - 'Pre--To++': { replacement: '++', mutationName: 'Pre--To++' }, + UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator: { + replacement: '--', + mutationName: 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', + }, + UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator: { + replacement: '++', + mutationName: 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', + }, + UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator: { + replacement: '--', + mutationName: 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', + }, + UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator: { + replacement: '++', + mutationName: 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', + }, '++': { replacement: '--', mutationName: '++all' }, '--': { replacement: '++', mutationName: '--all' }, }; @@ -28,13 +40,13 @@ export const updateOperatorMutator: NodeMutator = { } else { let replacement = undefined; if (path.node.prefix && path.node.operator == '++') { - replacement = getReplacement(levelMutations, operators['Pre++To--'].mutationName); + replacement = getReplacement(levelMutations, operators.UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator.mutationName); } else if (path.node.prefix && path.node.operator == '--') { - replacement = getReplacement(levelMutations, operators['Pre--To++'].mutationName); + replacement = getReplacement(levelMutations, operators.UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator.mutationName); } else if (!path.node.prefix && path.node.operator == '++') { - replacement = getReplacement(levelMutations, operators['Post++To--'].mutationName); + replacement = getReplacement(levelMutations, operators.UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator.mutationName); } else if (!path.node.prefix && path.node.operator == '--') { - replacement = getReplacement(levelMutations, operators['Post--To++'].mutationName); + replacement = getReplacement(levelMutations, operators.UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator.mutationName); } if (replacement !== undefined) { yield types.updateExpression(replacement, deepCloneNode(path.node.argument), path.node.prefix); diff --git a/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts index 52e8b5f76f..7f440023cb 100644 --- a/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts @@ -4,7 +4,14 @@ import { arithmeticOperatorMutator as sut } from '../../../src/mutators/arithmet import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const arithmeticLevel: MutationLevel = { name: 'ArithemticLevel', ArithmeticOperator: ['+To-', '-To+', '*To/'] }; +const arithmeticLevel: MutationLevel = { + name: 'ArithemticLevel', + ArithmeticOperator: [ + 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator', + 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator', + 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator', + ], +}; describe(sut.name, () => { it('should have name "ArithmeticOperator"', () => { diff --git a/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts index 33a2df8226..e0f4b5114d 100644 --- a/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts @@ -2,8 +2,17 @@ import { expect } from 'chai'; import { arrayDeclarationMutator as sut } from '../../../src/mutators/array-declaration-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const arrayDeclarationLevel: string[] = ['EmptyArray', 'EmptyArrayConstructor', 'FilledArray', 'FilledArrayConstructor']; +const arrayDeclarationLevel: MutationLevel = { + name: 'ArrayDeclarationLevel', + ArrayDeclaration: [ + 'ArrayDeclaration_ArrayLiteral_Fill', + 'ArrayDeclaration_ArrayConstructor_Fill', + 'ArrayDeclaration_ArrayLiteral_ItemsRemoval', + 'ArrayDeclaration_ArrayConstructor_ItemsRemoval', + ], +}; describe(sut.name, () => { it('should have name "ArrayDeclaration"', () => { @@ -44,7 +53,7 @@ describe(sut.name, () => { it('should only mutate [], new Array(), new Array(x,y) and [x,y] from all possible mutators', () => { expectJSMutationWithLevel( sut, - arrayDeclarationLevel, + arrayDeclarationLevel.ArrayDeclaration, '[]; new Array(); new Array({x:"", y:""}); [{x:"", y:""}]', '["Stryker was here"]; new Array(); new Array({x:"", y:""}); [{x:"", y:""}]', // mutates [] '[]; new Array("Stryker was here"); new Array({x:"", y:""}); [{x:"", y:""}]', // mutates new Array() diff --git a/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts index 152b207fba..c54b991bd2 100644 --- a/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts @@ -4,7 +4,7 @@ import { arrowFunctionMutator as sut } from '../../../src/mutators/arrow-functio import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const arrowFunctionLevel: MutationLevel = { name: 'ArrowFunctionLevel', ArrowFunction: ['ArrowFunction'] }; +const arrowFunctionLevel: MutationLevel = { name: 'ArrowFunctionLevel', ArrowFunction: ['ArrowFunction_Removal'] }; const arrowFunctionUndefinedLevel: MutationLevel = { name: 'ArrowFunctionLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts index 45f137ebb7..1075ea1e41 100644 --- a/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts @@ -4,22 +4,29 @@ import { assignmentOperatorMutator as sut } from '../../../src/mutators/assignme import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const assignmentOperatorLevel: MutationLevel = { name: 'AssignmentOperatorLevel', AssignmentOperator: ['-=To+=', '<<=To>>=', '&&=To||='] }; +const assignmentOperatorLevel: MutationLevel = { + name: 'AssignmentOperatorLevel', + AssignmentOperator: [ + 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment', + 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment', + 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment', + ], +}; const assignmentOperatorAllLevel: MutationLevel = { name: 'AssignmentOperatorLevel', AssignmentOperator: [ - '+=To-=', - '-=To+=', - '*=To/=', - '/=To*=', - '%=To*=', - '<<=To>>=', - '>>=To<<=', - '&=To|=', - '|=To&=', - '&&=To||=', - '||=To&&=', - '??=To&&=', + 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment', + 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment', + 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment', + 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment', + 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment', + 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment', + 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment', + 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment', + 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment', + 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment', + 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment', + 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment', ], }; const assignmentOperatorUndefinedLevel: MutationLevel = { name: 'AssignmentOperatorLevel' }; diff --git a/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts index e986433eb3..f46e743f15 100644 --- a/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts @@ -4,7 +4,7 @@ import { blockStatementMutator as sut } from '../../../src/mutators/block-statem import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const blockStatementLevel: MutationLevel = { name: 'BlockStatementLevel', BlockStatement: ['BlockStatement'] }; +const blockStatementLevel: MutationLevel = { name: 'BlockStatementLevel', BlockStatement: ['BlockStatement_Removal'] }; const blockStatementUndefinedLevel: MutationLevel = { name: 'BlockStatementLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts index d6504b28c5..274f260aed 100644 --- a/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts @@ -6,12 +6,12 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const booleanLiteralLevel: MutationLevel = { name: 'BooleanLiteralLevel', - BooleanLiteral: ['TrueToFalse', 'RemoveNegation'], + BooleanLiteral: ['BooleanLiteral_TrueLiteral_ToFalseLiteral', 'BooleanLiteral_LogicalNot_Removal'], }; const booleanLiteralAllLevel: MutationLevel = { name: 'BooleanLiteralLevel', - BooleanLiteral: ['TrueToFalse', 'FalseToTrue', 'RemoveNegation'], + BooleanLiteral: ['BooleanLiteral_TrueLiteral_ToFalseLiteral', 'BooleanLiteral_FalseLiteral_ToTrueLiteral', 'BooleanLiteral_LogicalNot_Removal'], }; const booleanLiteralUndefinedLevel: MutationLevel = { diff --git a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts index edc7a7e6fe..1812a564ef 100644 --- a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts @@ -2,10 +2,31 @@ import { expect } from 'chai'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { conditionalExpressionMutator as sut } from '../../../src/mutators/conditional-expression-mutator.js'; - -const conditionLevel: string[] = ['ForLoopToFalse', 'IfToFalse', 'IfToTrue', 'SwitchToEmpty']; -const conditionLevel2: string[] = ['WhileLoopToFalse', 'BooleanExpressionToFalse', 'DoWhileLoopToFalse', 'BooleanExpressionToTrue']; -const conditionLevel3 = undefined; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const conditionLevel: MutationLevel = { + name: 'conditionLevel', + ConditionalExpression: [ + 'ConditionalExpression_ForLoopCondition_ToFalseLiteral', + 'ConditionalExpression_IfCondition_ToFalseLiteral', + 'ConditionalExpression_IfCondition_ToTrueLiteral', + 'ConditionalExpression_SwitchStatementBody_Removal', + ], +}; + +const conditionLevel2: MutationLevel = { + name: 'conditionLevel2', + ConditionalExpression: [ + 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral', + 'ConditionalExpression_BooleanExpression_ToFalseLiteral', + 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral', + 'ConditionalExpression_BooleanExpression_ToTrueLiteral', + ], +}; + +const conditionLevel3: MutationLevel = { + name: 'conditionLevel2', +}; describe(sut.name, () => { it('should have name "ConditionalExpression"', () => { @@ -148,7 +169,7 @@ describe(sut.name, () => { it('should only mutate for, if and switch statement', () => { expectJSMutationWithLevel( sut, - conditionLevel, + conditionLevel.ConditionalExpression, 'for (var i = 0; i < 10; i++) { };if(x > 2); switch (x) {case 0: 2}', 'for (var i = 0; false; i++) { };if(x > 2); switch (x) {case 0: 2}', // mutates for loop 'for (var i = 0; i < 10; i++) { };if(false); switch (x) {case 0: 2}', // mutates if statement to false @@ -160,7 +181,7 @@ describe(sut.name, () => { it('should only mutate while, while do and boolean expression', () => { expectJSMutationWithLevel( sut, - conditionLevel2, + conditionLevel2.ConditionalExpression, 'while (a > b) { }; do { } while (a > b); var x = a > b ? 1 : 2', 'while (false) { }; do { } while (a > b); var x = a > b ? 1 : 2', // mutates while loop 'while (a > b) { }; do { } while (a > b); var x = false ? 1 : 2', // mutates boolean to false @@ -172,7 +193,7 @@ describe(sut.name, () => { it('should only mutate all', () => { expectJSMutationWithLevel( sut, - conditionLevel3, + conditionLevel3.ConditionalExpression, 'for (var i = 0; i < 10; i++) { };if(x > 2); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', 'for (var i = 0; false; i++) { };if(x > 2); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', // mutates for loop 'for (var i = 0; i < 10; i++) { };if(false); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', // mutates if statement to false diff --git a/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts index 577e737e36..97b15581e2 100644 --- a/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts @@ -4,9 +4,25 @@ import { equalityOperatorMutator as sut } from '../../../src/mutators/equality-o import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const equalityLevelA: MutationLevel = { name: 'EqualityLevelA', EqualityOperator: ['=', '>=To>', '>=To<', '==To!='] }; +const equalityLevelA: MutationLevel = { + name: 'EqualityLevelA', + EqualityOperator: [ + 'EqualityOperator_LessThanOperator_Boundary', + 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator', + 'EqualityOperator_GreatherThanEqualOperator_Boundary', + 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator', + 'EqualityOperator_EqualityOperator_ToInequalityOperator', + ], +}; -const equalityLevelB: MutationLevel = { name: 'EqualityLevelB', EqualityOperator: ['<=To>', '>To<=', '===To!=='] }; +const equalityLevelB: MutationLevel = { + name: 'EqualityLevelB', + EqualityOperator: [ + 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator', + 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator', + 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator', + ], +}; describe(sut.name, () => { it('should have name "EqualityOperator"', () => { diff --git a/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts index 7afc4fa073..88c3b0456b 100644 --- a/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts @@ -2,6 +2,12 @@ import { expect } from 'chai'; import { logicalOperatorMutator as sut } from '../../../src/mutators/logical-operator-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const logicalOpLevel: MutationLevel = { + name: 'EqualityLevelB', + LogicalOperator: ['LogicalOperator_LogicalOrOperator_ToLogicalAndOperator', 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator'], +}; describe(sut.name, () => { it('should have name "LogicalOperator"', () => { @@ -26,8 +32,7 @@ describe(sut.name, () => { }); it('should only mutate || and &&', () => { - const level = ['||To&&', '&&To||']; - expectJSMutationWithLevel(sut, level, 'a || b; a && b; a ?? b', 'a && b; a && b; a ?? b', 'a || b; a || b; a ?? b'); + expectJSMutationWithLevel(sut, logicalOpLevel.LogicalOperator, 'a || b; a && b; a ?? b', 'a && b; a && b; a ?? b', 'a || b; a || b; a ?? b'); }); it('should mutate all three', () => { diff --git a/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts index a74a27268a..1570a7beb1 100644 --- a/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts @@ -2,6 +2,17 @@ import { expect } from 'chai'; import { methodExpressionMutator as sut } from '../../../src/mutators/method-expression-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const methodExpressionLevel: MutationLevel = { + name: 'methodExpressionLevel', + MethodExpression: [ + 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall', + 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall', + 'MethodExpression_substringMethodCall_Removal', + 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall', + ], +}; describe(sut.name, () => { it('should have name "MethodExpression"', () => { @@ -149,10 +160,6 @@ describe(sut.name, () => { }); it('should only mutate methods that are allowed by a MutationLevel and ignore others', () => { - const methodExpressionLevel = { - name: 'methodExpressionLevel', - MethodExpression: ['endsWithToStartsWith', 'startsWithToEndsWith', 'removeSubstring', 'toLowerCaseToToUpperCase'], - }; // The below should be swapped expectJSMutationWithLevel(sut, methodExpressionLevel.MethodExpression, 'text.startsWith();', 'text.endsWith();'); expectJSMutationWithLevel(sut, methodExpressionLevel.MethodExpression, 'text.endsWith();', 'text.startsWith();'); diff --git a/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts index 06c645bd98..e9bbf1a8f0 100644 --- a/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts @@ -4,7 +4,7 @@ import { objectLiteralMutator as sut } from '../../../src/mutators/object-litera import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const objectLiteralLevel: MutationLevel = { name: 'ObjectLiteralLevel', ObjectLiteral: ['ObjectLiteral'] }; +const objectLiteralLevel: MutationLevel = { name: 'ObjectLiteralLevel', ObjectLiteral: ['ObjectLiteral_PropertiesRemoval'] }; const objectLiteralUndefinedLevel: MutationLevel = { name: 'ObjectLiteralLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts index 541ff6fda8..abbee3bd0f 100644 --- a/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts @@ -3,6 +3,12 @@ import { expect } from 'chai'; import { optionalChainingMutator as sut } from '../../../src/mutators/optional-chaining-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const optionalChainingLevel: MutationLevel = { + name: 'OptionalChainingLevel', + OptionalChaining: ['OptionalChaining_OptionalMemberExpression_OptionRemoval'], +}; describe(sut.name, () => { it('should have name "OptionalChaining"', () => { @@ -34,7 +40,7 @@ describe(sut.name, () => { it('should only mutate OptionalMemberExpression from all possible mutators', () => { expectJSMutationWithLevel( sut, - ['OptionalMemberExpression'], + optionalChainingLevel.OptionalChaining, 'foo?.bar; foo?.[0]; foo?.()', 'foo.bar; foo?.[0]; foo?.()', // removes .bar optional 'foo?.bar; foo[0]; foo?.()', // removes [0] optional diff --git a/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts index d0d74c0846..0b8b9c5432 100644 --- a/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts @@ -5,7 +5,7 @@ import { regexMutator as sut } from '../../../src/mutators/regex-mutator.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 regexLevel: MutationLevel = { name: 'RegexLevel', Regex: ['Regex_Removal'] }; const regexUndefinedLevel: MutationLevel = { name: 'RegexLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts index af720fc834..938209df41 100644 --- a/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts @@ -2,6 +2,12 @@ import { expect } from 'chai'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { stringLiteralMutator as sut } from '../../../src/mutators/string-literal-mutator.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const stringLiteralLevel: MutationLevel = { + name: 'ObjectLiteralLevel', + StringLiteral: ['StringLiteral_FilledStringLiteral_ToEmptyStringLiteral', 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString'], +}; describe(sut.name, () => { it('should have name "StringLiteral"', () => { @@ -117,7 +123,7 @@ describe(sut.name, () => { it('should only mutate EmptyString and EmptyInterpolation from all possible mutations', () => { expectJSMutationWithLevel( sut, - ['EmptyString', 'EmptyInterpolation'], + stringLiteralLevel.StringLiteral, 'const bar = "bar"; const foo = `name: ${level_name}`; const emptyString=""; const emptyInterp=``', 'const bar = ""; const foo = `name: ${level_name}`; const emptyString=""; const emptyInterp=``', // empties string 'const bar = "bar"; const foo = ``; const emptyString=""; const emptyInterp=``', // empties interpolation diff --git a/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts index 6d40318b6a..0cbb1c35ce 100644 --- a/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts @@ -2,6 +2,13 @@ import { expect } from 'chai'; import { unaryOperatorMutator as sut } from '../../../src/mutators/unary-operator-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; + +const unaryOperatorLevelA: MutationLevel = { + name: 'unaryOperatorA', + UnaryOperator: ['UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator', 'UnaryOperator_BitwiseOrOperator_Removal'], +}; +const unaryOperatorLevelB: MutationLevel = { name: 'unaryOperatorB', UnaryOperator: ['UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator'] }; describe(sut.name, () => { it('should have name "UnaryOperator"', () => { @@ -29,12 +36,10 @@ describe(sut.name, () => { }); it('should not mutate -b to +b', () => { - const unaryOperatorLevelA = { name: 'unaryOperatorA', UnaryOperator: ['+To-', 'remove~'] }; expectJSMutationWithLevel(sut, unaryOperatorLevelA.UnaryOperator, '+a; -b; ~c;', '-a; -b; ~c;', '+a; -b; c;'); }); it('should only mutate -b to +b', () => { - const unaryOperatorLevelB = { name: 'unaryOperatorB', UnaryOperator: ['-To+'] }; expectJSMutationWithLevel(sut, unaryOperatorLevelB.UnaryOperator, '+a; -b; ~c;', '+a; +b; ~c;'); }); }); 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 1269d25c46..ac9831cf52 100644 --- a/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts @@ -2,10 +2,27 @@ import { expect } from 'chai'; import { updateOperatorMutator as sut } from '../../../src/mutators/update-operator-mutator.js'; import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const updateLevel: string[] = ['Pre--To++', 'Pre++To--']; -const updateLevel2: string[] = ['Post++To--', 'Post--To++']; -const updateLevel3 = undefined; +const updateLevel: MutationLevel = { + name: 'UpdateLevel', + UpdateOperator: [ + 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', + 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', + ], +}; + +const updateLevel2: MutationLevel = { + name: 'UpdateLevel2', + UpdateOperator: [ + 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', + 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', + ], +}; + +const updateUndefinedLevel: MutationLevel = { + name: 'UpdateLevel3', +}; describe(sut.name, () => { it('should have name "UpdateOperator"', () => { @@ -31,7 +48,7 @@ describe(sut.name, () => { it('should only mutate --a and ++a', () => { expectJSMutationWithLevel( sut, - updateLevel, + updateLevel.UpdateOperator, '--a; ++a; a--; a++', '++a; ++a; a--; a++', //mutates --a '--a; --a; a--; a++', //mutates ++a @@ -41,7 +58,7 @@ describe(sut.name, () => { it('should only mutate a-- and a++', () => { expectJSMutationWithLevel( sut, - updateLevel2, + updateLevel2.UpdateOperator, '--a; ++a; a--; a++', '--a; ++a; a--; a--', //mutates a++ '--a; ++a; a++; a++', //mutates a-- @@ -51,7 +68,7 @@ describe(sut.name, () => { it('should mutate all', () => { expectJSMutationWithLevel( sut, - updateLevel3, + updateUndefinedLevel.UpdateOperator, '--a; ++a; a--; a++', '++a; ++a; a--; a++', //mutates --a '--a; --a; a--; a++', //mutates ++a From dc500d0b8f31b82862f7eb97dcf5e50e43af7df4 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 20:42:02 +0100 Subject: [PATCH 04/13] Enforce type with a generic NodeMutatorConfiguration --- .../src/mutation-level/mutation-level.ts | 8 ++++---- .../src/mutators/arithmetic-operator-mutator.ts | 4 +++- .../src/mutators/array-declaration-mutator.ts | 4 +++- .../src/mutators/arrow-function-mutator.ts | 12 ++++++++++-- .../src/mutators/assignment-operator-mutator.ts | 4 +++- .../src/mutators/block-statement-mutator.ts | 16 ++++++++++++---- .../src/mutators/boolean-literal-mutator.ts | 4 +++- .../mutators/conditional-expression-mutator.ts | 4 +++- .../src/mutators/equality-operator-mutator.ts | 4 +++- .../src/mutators/logical-operator-mutator.ts | 6 ++++-- .../src/mutators/method-expression-mutator.ts | 4 +++- .../instrumenter/src/mutators/node-mutator.ts | 1 - .../src/mutators/object-literal-mutator.ts | 16 ++++++++++++---- .../src/mutators/optional-chaining-mutator.ts | 4 +++- .../instrumenter/src/mutators/regex-mutator.ts | 12 ++++++++++-- .../src/mutators/string-literal-mutator.ts | 4 +++- .../src/mutators/unary-operator-mutator.ts | 4 +++- .../src/mutators/update-operator-mutator.ts | 10 +++++----- 18 files changed, 87 insertions(+), 34 deletions(-) diff --git a/packages/instrumenter/src/mutation-level/mutation-level.ts b/packages/instrumenter/src/mutation-level/mutation-level.ts index 0dad6606b2..4bc33915d9 100644 --- a/packages/instrumenter/src/mutation-level/mutation-level.ts +++ b/packages/instrumenter/src/mutation-level/mutation-level.ts @@ -19,12 +19,12 @@ import { UpdateOperator, } from '@stryker-mutator/api/core'; -export type NodeMutatorConfiguration = Record; +export type NodeMutatorConfiguration = Record>; -export type NodeMutatorMultiConfiguration = Record; -interface ReplacementConfiguration { +export type NodeMutatorMultiConfiguration = Record>>; +interface ReplacementConfiguration { replacement?: any; - mutationName: string; + mutationName: T; } export interface MutationLevel { diff --git a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts index 1ff89f819a..9c3774d09b 100644 --- a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts @@ -1,12 +1,14 @@ import type { types } from '@babel/core'; +import { ArithmeticOperator } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { '+': { replacement: '-', mutationName: 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator' }, '-': { replacement: '+', mutationName: 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator' }, '*': { replacement: '/', mutationName: 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator' }, diff --git a/packages/instrumenter/src/mutators/array-declaration-mutator.ts b/packages/instrumenter/src/mutators/array-declaration-mutator.ts index bef49be984..bae5c72448 100644 --- a/packages/instrumenter/src/mutators/array-declaration-mutator.ts +++ b/packages/instrumenter/src/mutators/array-declaration-mutator.ts @@ -1,5 +1,7 @@ import babel from '@babel/core'; +import { ArrayDeclaration } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; @@ -7,7 +9,7 @@ import { NodeMutator } from './node-mutator.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { FilledArray: { replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), mutationName: 'ArrayDeclaration_ArrayLiteral_Fill', diff --git a/packages/instrumenter/src/mutators/arrow-function-mutator.ts b/packages/instrumenter/src/mutators/arrow-function-mutator.ts index b2736f2941..1bce644150 100644 --- a/packages/instrumenter/src/mutators/arrow-function-mutator.ts +++ b/packages/instrumenter/src/mutators/arrow-function-mutator.ts @@ -2,8 +2,16 @@ import babel from '@babel/core'; const { types } = babel; +import { ArrowFunction } from '@stryker-mutator/api/core'; + +import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; + import { NodeMutator } from './index.js'; +const operators: NodeMutatorConfiguration = { + ArrowFunction: { mutationName: 'ArrowFunction_Removal' }, +}; + export const arrowFunctionMutator: NodeMutator = { name: 'ArrowFunction', @@ -19,6 +27,6 @@ export const arrowFunctionMutator: NodeMutator = { }, }; -function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.includes('ArrowFunction_Removal'); +function isInMutationLevel(levelMutations: string[] | undefined): boolean { + return levelMutations === undefined || levelMutations.includes(operators.ArrowFunction.mutationName); } diff --git a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts index 77bd98ee3c..70cf33ef19 100644 --- a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts @@ -1,12 +1,14 @@ import type { types } from '@babel/core'; +import { AssignmentOperator } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './index.js'; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { '+=': { replacement: '-=', mutationName: 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment' }, '-=': { replacement: '+=', mutationName: 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment' }, '*=': { replacement: '/=', mutationName: 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment' }, diff --git a/packages/instrumenter/src/mutators/block-statement-mutator.ts b/packages/instrumenter/src/mutators/block-statement-mutator.ts index c95ca03ab5..6b150ec99b 100644 --- a/packages/instrumenter/src/mutators/block-statement-mutator.ts +++ b/packages/instrumenter/src/mutators/block-statement-mutator.ts @@ -1,14 +1,22 @@ import babel, { type NodePath } from '@babel/core'; +import { BlockStatement } from '@stryker-mutator/api/core'; + +import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; + import { NodeMutator } from './node-mutator.js'; const { types } = babel; +const operators: NodeMutatorConfiguration = { + BlockStatement: { mutationName: 'BlockStatement_Removal' }, +}; + export const blockStatementMutator: NodeMutator = { name: 'BlockStatement', - *mutate(path, options) { - if (path.isBlockStatement() && isValid(path) && isInMutationLevel(options)) { + *mutate(path, levelMutations) { + if (path.isBlockStatement() && isValid(path) && isInMutationLevel(levelMutations)) { yield types.blockStatement([]); } }, @@ -70,6 +78,6 @@ function hasSuperExpressionOnFirstLine(constructor: NodePath = { true: { replacement: false, mutationName: 'BooleanLiteral_TrueLiteral_ToFalseLiteral' }, false: { replacement: true, mutationName: 'BooleanLiteral_FalseLiteral_ToTrueLiteral' }, '!': { replacement: '', mutationName: 'BooleanLiteral_LogicalNot_Removal' }, diff --git a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts index 306444baab..052f8c2183 100644 --- a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts @@ -1,5 +1,7 @@ import babel, { type NodePath } from '@babel/core'; +import { ConditionalExpression } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; @@ -10,7 +12,7 @@ const booleanOperators = Object.freeze(['!=', '!==', '&&', '<', '<=', '==', '=== const { types } = babel; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_BooleanExpression_ToFalseLiteral' }, BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_BooleanExpression_ToTrueLiteral' }, DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral' }, diff --git a/packages/instrumenter/src/mutators/equality-operator-mutator.ts b/packages/instrumenter/src/mutators/equality-operator-mutator.ts index f89d64e822..f148436323 100644 --- a/packages/instrumenter/src/mutators/equality-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/equality-operator-mutator.ts @@ -1,12 +1,14 @@ import babel, { types } from '@babel/core'; +import { EqualityOperator } from '@stryker-mutator/api/core'; + import { NodeMutatorMultiConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; const { types: t } = babel; -const operators: NodeMutatorMultiConfiguration = { +const operators: NodeMutatorMultiConfiguration = { '<': [ { replacement: '<=', mutationName: 'EqualityOperator_LessThanOperator_Boundary' }, { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, diff --git a/packages/instrumenter/src/mutators/logical-operator-mutator.ts b/packages/instrumenter/src/mutators/logical-operator-mutator.ts index 32a59a6413..75e769d489 100644 --- a/packages/instrumenter/src/mutators/logical-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/logical-operator-mutator.ts @@ -1,9 +1,11 @@ +import { LogicalOperator } from '@stryker-mutator/api/core'; + import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { deepCloneNode } from '../util/index.js'; import { NodeMutator } from './index.js'; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { '&&': { replacement: '||', mutationName: 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator' }, '||': { replacement: '&&', mutationName: 'LogicalOperator_LogicalOrOperator_ToLogicalAndOperator' }, '??': { replacement: '&&', mutationName: 'LogicalOperator_NullishCoalescingOperator_ToLogicalAnd' }, @@ -28,5 +30,5 @@ function isSupported(operator: string): operator is keyof typeof operators { } function isInMutationLevel(operator: string, levelMutations: string[] | undefined): operator is keyof typeof operators { - return levelMutations === undefined || levelMutations.includes(operators[operator].mutationName); + return levelMutations === undefined || levelMutations.includes(operators[operator].mutationName as string); } diff --git a/packages/instrumenter/src/mutators/method-expression-mutator.ts b/packages/instrumenter/src/mutators/method-expression-mutator.ts index 2daf0df307..4a40d5cc78 100644 --- a/packages/instrumenter/src/mutators/method-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/method-expression-mutator.ts @@ -1,5 +1,7 @@ import babel from '@babel/core'; +import { MethodExpression } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; @@ -9,7 +11,7 @@ import { NodeMutator } from './node-mutator.js'; const { types } = babel; // prettier-ignore -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { 'charAt': { replacement: null, mutationName: 'MethodExpression_charAtMethodCall_Removal' }, 'endsWith': { replacement: 'startsWith', mutationName: 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall' }, 'startsWith': { replacement: 'endsWith', mutationName: 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall' }, diff --git a/packages/instrumenter/src/mutators/node-mutator.ts b/packages/instrumenter/src/mutators/node-mutator.ts index e1b5f2d039..86bea517e9 100644 --- a/packages/instrumenter/src/mutators/node-mutator.ts +++ b/packages/instrumenter/src/mutators/node-mutator.ts @@ -5,5 +5,4 @@ import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; export interface NodeMutator { mutate(path: NodePath, levelMutations: string[] | undefined): Iterable; readonly name: string; - readonly operators?: NodeMutatorConfiguration; } diff --git a/packages/instrumenter/src/mutators/object-literal-mutator.ts b/packages/instrumenter/src/mutators/object-literal-mutator.ts index badb9490b4..33c2efe300 100644 --- a/packages/instrumenter/src/mutators/object-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/object-literal-mutator.ts @@ -1,19 +1,27 @@ import babel from '@babel/core'; +import { ObjectLiteral } from '@stryker-mutator/api/core'; + +import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; + import { NodeMutator } from './index.js'; const { types } = babel; +const operators: NodeMutatorConfiguration = { + ObjectLiteral: { mutationName: 'ObjectLiteral_PropertiesRemoval' }, +}; + export const objectLiteralMutator: NodeMutator = { name: 'ObjectLiteral', - *mutate(path, options) { - if (path.isObjectExpression() && path.node.properties.length > 0 && isInMutationLevel(options)) { + *mutate(path, levelMutations) { + if (path.isObjectExpression() && path.node.properties.length > 0 && isInMutationLevel(levelMutations)) { yield types.objectExpression([]); } }, }; -function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.includes('ObjectLiteral_PropertiesRemoval'); +function isInMutationLevel(levelMutations: string[] | undefined): boolean { + return levelMutations === undefined || levelMutations.includes(operators.ObjectLiteral.mutationName as string); } diff --git a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts index 885d1aaa82..4a14e48559 100644 --- a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts +++ b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts @@ -1,5 +1,7 @@ import babel from '@babel/core'; +import { OptionalChaining } from '@stryker-mutator/api/core'; + import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './index.js'; @@ -19,7 +21,7 @@ const { types: t } = babel; * foo?.() -> foo() */ -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { OptionalCallExpression: { mutationName: 'OptionalChaining_OptionalCallExpression_OptionRemoval' }, OptionalMemberExpression: { mutationName: 'OptionalChaining_OptionalMemberExpression_OptionRemoval' }, }; diff --git a/packages/instrumenter/src/mutators/regex-mutator.ts b/packages/instrumenter/src/mutators/regex-mutator.ts index 8eccda4dd5..937f364613 100644 --- a/packages/instrumenter/src/mutators/regex-mutator.ts +++ b/packages/instrumenter/src/mutators/regex-mutator.ts @@ -1,10 +1,18 @@ import babel, { NodePath, type types as t } from '@babel/core'; import * as weaponRegex from 'weapon-regex'; +import { Regex } from '@stryker-mutator/api/core'; + +import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; + import { NodeMutator } from './index.js'; const { types } = babel; +const operators: NodeMutatorConfiguration = { + Regex: { mutationName: 'Regex_Removal' }, +}; + /** * Checks that a string literal is an obvious regex string literal * @param path The string literal to checks @@ -60,6 +68,6 @@ function mutatePattern(pattern: string, flags: string | undefined): string[] { return []; } -function isInMutationLevel(operations: string[] | undefined): boolean { - return operations === undefined || operations.includes('Regex_Removal'); +function isInMutationLevel(levelMutations: string[] | undefined): boolean { + return levelMutations === undefined || levelMutations.includes(operators.Regex.mutationName); } diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index fbc706e30c..87553d6aeb 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -1,12 +1,14 @@ import babel, { type NodePath } from '@babel/core'; +import { StringLiteral } from '@stryker-mutator/api/core'; + import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'StringLiteral_EmptyStringLiteral_ToFilledStringLiteral' }, EmptyString: { replacement: types.stringLiteral(''), mutationName: 'StringLiteral_FilledStringLiteral_ToEmptyStringLiteral' }, EmptyInterpolation: { diff --git a/packages/instrumenter/src/mutators/unary-operator-mutator.ts b/packages/instrumenter/src/mutators/unary-operator-mutator.ts index 68c416bc7a..da66bee3ac 100644 --- a/packages/instrumenter/src/mutators/unary-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/unary-operator-mutator.ts @@ -1,5 +1,7 @@ import babel from '@babel/core'; +import { UnaryOperator } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; @@ -8,7 +10,7 @@ import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { '+': { replacement: '-', mutationName: 'UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator' }, '-': { replacement: '+', mutationName: 'UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator' }, '~': { replacement: '', mutationName: 'UnaryOperator_BitwiseOrOperator_Removal' }, diff --git a/packages/instrumenter/src/mutators/update-operator-mutator.ts b/packages/instrumenter/src/mutators/update-operator-mutator.ts index b59748bf2a..cf1e2cbf46 100644 --- a/packages/instrumenter/src/mutators/update-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/update-operator-mutator.ts @@ -1,5 +1,7 @@ import babel from '@babel/core'; +import { UpdateOperator } from '@stryker-mutator/api/core'; + import { deepCloneNode } from '../util/index.js'; import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; @@ -8,7 +10,7 @@ import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { +const operators: NodeMutatorConfiguration = { UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator: { replacement: '--', mutationName: 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', @@ -25,8 +27,6 @@ const operators: NodeMutatorConfiguration = { replacement: '++', mutationName: 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', }, - '++': { replacement: '--', mutationName: '++all' }, - '--': { replacement: '++', mutationName: '--all' }, }; export const updateOperatorMutator: NodeMutator = { @@ -35,8 +35,8 @@ export const updateOperatorMutator: NodeMutator = { *mutate(path, levelMutations) { if (path.isUpdateExpression()) { if (levelMutations === undefined) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - yield types.updateExpression(operators[path.node.operator].replacement, deepCloneNode(path.node.argument), path.node.prefix); + const replacement = path.node.operator === '++' ? '--' : '++'; + yield types.updateExpression(replacement, deepCloneNode(path.node.argument), path.node.prefix); } else { let replacement = undefined; if (path.node.prefix && path.node.operator == '++') { From 404a58ed218a27d71b8d9086484fc504fe260281 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 21:13:56 +0100 Subject: [PATCH 05/13] Get rid of NodeMutatorMultiConfiguration --- .../src/mutation-level/mutation-level.ts | 1 - .../src/mutators/equality-operator-mutator.ts | 48 +++++++++---------- .../instrumenter/src/mutators/node-mutator.ts | 2 - 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/packages/instrumenter/src/mutation-level/mutation-level.ts b/packages/instrumenter/src/mutation-level/mutation-level.ts index 4bc33915d9..b9d6f6a156 100644 --- a/packages/instrumenter/src/mutation-level/mutation-level.ts +++ b/packages/instrumenter/src/mutation-level/mutation-level.ts @@ -21,7 +21,6 @@ import { export type NodeMutatorConfiguration = Record>; -export type NodeMutatorMultiConfiguration = Record>>; interface ReplacementConfiguration { replacement?: any; mutationName: T; diff --git a/packages/instrumenter/src/mutators/equality-operator-mutator.ts b/packages/instrumenter/src/mutators/equality-operator-mutator.ts index f148436323..1f611950f2 100644 --- a/packages/instrumenter/src/mutators/equality-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/equality-operator-mutator.ts @@ -2,33 +2,29 @@ import babel, { types } from '@babel/core'; import { EqualityOperator } from '@stryker-mutator/api/core'; -import { NodeMutatorMultiConfiguration } from '../mutation-level/mutation-level.js'; +import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; const { types: t } = babel; -const operators: NodeMutatorMultiConfiguration = { - '<': [ - { replacement: '<=', mutationName: 'EqualityOperator_LessThanOperator_Boundary' }, - { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, - ], - '<=': [ - { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, - { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, - ], - '>': [ - { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, - { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, - ], - '>=': [ - { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, - { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, - ], - '==': [{ replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }], - '!=': [{ replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }], - '===': [{ replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }], - '!==': [{ replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }], +const operators: NodeMutatorConfiguration = { + '=': { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, + + '<=To<': { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, + '<=To>': { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, + + '>To>=': { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, + '>To<=': { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, + + '>=To>': { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, + '>=To<': { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, + + '==': { replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }, + '!=': { replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }, + '===': { replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }, + '!==': { replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }, }; function isEqualityOperator(operator: string): operator is keyof typeof operators { @@ -51,12 +47,14 @@ export const equalityOperatorMutator: NodeMutator = { }; function filterMutationLevel(node: types.BinaryExpression, levelMutations: string[] | undefined) { - const allMutations = operators[node.operator as keyof typeof operators]; - // Nothing allowed, so return an empty array if (levelMutations === undefined) { - return allMutations; + return []; } + const allMutations = Object.keys(operators) + .filter((k) => k.startsWith(node.operator)) + .map((k) => operators[k]); + return allMutations.filter((mut) => levelMutations.some((op) => op === mut.mutationName)); } diff --git a/packages/instrumenter/src/mutators/node-mutator.ts b/packages/instrumenter/src/mutators/node-mutator.ts index 86bea517e9..33c8755e5e 100644 --- a/packages/instrumenter/src/mutators/node-mutator.ts +++ b/packages/instrumenter/src/mutators/node-mutator.ts @@ -1,7 +1,5 @@ import type { types, NodePath } from '@babel/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - export interface NodeMutator { mutate(path: NodePath, levelMutations: string[] | undefined): Iterable; readonly name: string; From 41f02a5c762e496d6893f61fd04b8a7002145a48 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Thu, 7 Dec 2023 22:19:54 +0100 Subject: [PATCH 06/13] Move operators inside nodemutator interface --- .../mutators/arithmetic-operator-mutator.ts | 28 ++++---- .../src/mutators/array-declaration-mutator.ts | 35 +++++----- .../src/mutators/arrow-function-mutator.ts | 14 ++-- .../mutators/assignment-operator-mutator.ts | 42 ++++++----- .../src/mutators/block-statement-mutator.ts | 14 ++-- .../src/mutators/boolean-literal-mutator.ts | 20 +++--- .../conditional-expression-mutator.ts | 70 +++++++++---------- .../src/mutators/equality-operator-mutator.ts | 56 +++++++-------- .../src/mutators/logical-operator-mutator.ts | 25 ++++--- .../src/mutators/method-expression-mutator.ts | 59 ++++++++-------- packages/instrumenter/src/mutators/mutate.ts | 4 +- .../instrumenter/src/mutators/node-mutator.ts | 5 +- .../src/mutators/object-literal-mutator.ts | 14 ++-- .../src/mutators/optional-chaining-mutator.ts | 18 +++-- .../src/mutators/regex-mutator.ts | 14 ++-- .../src/mutators/string-literal-mutator.ts | 42 ++++++----- .../src/mutators/unary-operator-mutator.ts | 22 +++--- .../src/mutators/update-operator-mutator.ts | 58 ++++++++------- .../src/transformers/directive-bookkeeper.ts | 3 +- .../test/helpers/expect-mutation.ts | 5 +- .../test/unit/mutators/mutate.spec.ts | 3 +- .../transformers/babel-transformer.spec.ts | 22 +++--- 22 files changed, 283 insertions(+), 290 deletions(-) diff --git a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts index 9c3774d09b..19844cc8e4 100644 --- a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts @@ -4,24 +4,22 @@ import { ArithmeticOperator } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; -const operators: NodeMutatorConfiguration = { - '+': { replacement: '-', mutationName: 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator' }, - '-': { replacement: '+', mutationName: 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator' }, - '*': { replacement: '/', mutationName: 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator' }, - '/': { replacement: '*', mutationName: 'ArithmeticOperator_DivisionOperator_ToMultiplicationOperator' }, - '%': { replacement: '*', mutationName: 'ArithmeticOperator_RemainderOperator_ToMultiplicationOperator' }, -}; - -export const arithmeticOperatorMutator: NodeMutator = { +export const arithmeticOperatorMutator: NodeMutator = { name: 'ArithmeticOperator', + operators: { + '+': { replacement: '-', mutationName: 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator' }, + '-': { replacement: '+', mutationName: 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator' }, + '*': { replacement: '/', mutationName: 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator' }, + '/': { replacement: '*', mutationName: 'ArithmeticOperator_DivisionOperator_ToMultiplicationOperator' }, + '%': { replacement: '*', mutationName: 'ArithmeticOperator_RemainderOperator_ToMultiplicationOperator' }, + }, + *mutate(path, levelMutations) { if (path.isBinaryExpression() && isSupported(path.node.operator, path.node) && isInMutationLevel(path.node, levelMutations)) { - const mutatedOperator = operators[path.node.operator].replacement; + const mutatedOperator = this.operators[path.node.operator].replacement; const replacement = deepCloneNode(path.node); replacement.operator = mutatedOperator; yield replacement; @@ -35,12 +33,12 @@ function isInMutationLevel(node: types.BinaryExpression, operations: string[] | return true; } - const mutatedOperator = operators[node.operator as keyof typeof operators].mutationName; + const mutatedOperator = arithmeticOperatorMutator.operators[node.operator].mutationName; return operations.some((op) => op === mutatedOperator) ?? false; } -function isSupported(operator: string, node: types.BinaryExpression): operator is keyof typeof operators { - if (!Object.keys(operators).includes(operator)) { +function isSupported(operator: string, node: types.BinaryExpression): boolean { + if (!Object.keys(arithmeticOperatorMutator.operators).includes(operator)) { return false; } diff --git a/packages/instrumenter/src/mutators/array-declaration-mutator.ts b/packages/instrumenter/src/mutators/array-declaration-mutator.ts index bae5c72448..dba4509f6e 100644 --- a/packages/instrumenter/src/mutators/array-declaration-mutator.ts +++ b/packages/instrumenter/src/mutators/array-declaration-mutator.ts @@ -3,29 +3,28 @@ import babel from '@babel/core'; import { ArrayDeclaration } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { NodeMutator } from './node-mutator.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - FilledArray: { - replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), - mutationName: 'ArrayDeclaration_ArrayLiteral_Fill', - }, - FilledArrayConstructor: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'ArrayDeclaration_ArrayConstructor_Fill' }, - EmptyArray: { replacement: types.arrayExpression(), mutationName: 'ArrayDeclaration_ArrayLiteral_ItemsRemoval' }, - EmptyArrayConstructor: { replacement: [], mutationName: 'ArrayDeclaration_ArrayConstructor_ItemsRemoval' }, -}; - -export const arrayDeclarationMutator: NodeMutator = { +export const arrayDeclarationMutator: NodeMutator = { name: 'ArrayDeclaration', + operators: { + FilledArray: { + replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), + mutationName: 'ArrayDeclaration_ArrayLiteral_Fill', + }, + FilledArrayConstructor: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'ArrayDeclaration_ArrayConstructor_Fill' }, + EmptyArray: { replacement: types.arrayExpression(), mutationName: 'ArrayDeclaration_ArrayLiteral_ItemsRemoval' }, + EmptyArrayConstructor: { replacement: [], mutationName: 'ArrayDeclaration_ArrayConstructor_ItemsRemoval' }, + }, + *mutate(path, levelMutations) { // The check of the [] construct in code if (path.isArrayExpression() && isArrayInLevel(path.node, levelMutations)) { - const replacement = path.node.elements.length > 0 ? operators.EmptyArray.replacement : operators.FilledArray.replacement; + const replacement = path.node.elements.length > 0 ? this.operators.EmptyArray.replacement : this.operators.FilledArray.replacement; yield replacement; } // Check for the new Array() construct in code @@ -36,7 +35,7 @@ export const arrayDeclarationMutator: NodeMutator = { isArrayConstructorInLevel(path.node, levelMutations) ) { const mutatedCallArgs: babel.types.Expression[] = - path.node.arguments.length > 0 ? operators.EmptyArrayConstructor.replacement : operators.FilledArrayConstructor.replacement; + path.node.arguments.length > 0 ? this.operators.EmptyArrayConstructor.replacement : this.operators.FilledArrayConstructor.replacement; const replacement = types.isNewExpression(path.node) ? types.newExpression(deepCloneNode(path.node.callee), mutatedCallArgs) @@ -53,8 +52,8 @@ function isArrayInLevel(node: babel.types.ArrayExpression, levelMutations: strin } return ( - (levelMutations.includes(operators.EmptyArray.mutationName) && node.elements.length > 0) || - (levelMutations.includes(operators.FilledArray.mutationName) && node.elements.length === 0) + (levelMutations.includes(arrayDeclarationMutator.operators.EmptyArray.mutationName) && node.elements.length > 0) || + (levelMutations.includes(arrayDeclarationMutator.operators.FilledArray.mutationName) && node.elements.length === 0) ); } @@ -65,7 +64,7 @@ function isArrayConstructorInLevel(node: babel.types.CallExpression | babel.type } return ( - (levelMutations.includes(operators.EmptyArrayConstructor.mutationName) && node.arguments.length > 0) || - (levelMutations.includes(operators.FilledArrayConstructor.mutationName) && node.arguments.length === 0) + (levelMutations.includes(arrayDeclarationMutator.operators.EmptyArrayConstructor.mutationName) && node.arguments.length > 0) || + (levelMutations.includes(arrayDeclarationMutator.operators.FilledArrayConstructor.mutationName) && node.arguments.length === 0) ); } diff --git a/packages/instrumenter/src/mutators/arrow-function-mutator.ts b/packages/instrumenter/src/mutators/arrow-function-mutator.ts index 1bce644150..52eec1b29b 100644 --- a/packages/instrumenter/src/mutators/arrow-function-mutator.ts +++ b/packages/instrumenter/src/mutators/arrow-function-mutator.ts @@ -4,17 +4,15 @@ const { types } = babel; import { ArrowFunction } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; -const operators: NodeMutatorConfiguration = { - ArrowFunction: { mutationName: 'ArrowFunction_Removal' }, -}; - -export const arrowFunctionMutator: NodeMutator = { +export const arrowFunctionMutator: NodeMutator = { name: 'ArrowFunction', + operators: { + ArrowFunction: { mutationName: 'ArrowFunction_Removal' }, + }, + *mutate(path, levelMutations) { if ( path.isArrowFunctionExpression() && @@ -28,5 +26,5 @@ export const arrowFunctionMutator: NodeMutator = { }; function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(operators.ArrowFunction.mutationName); + return levelMutations === undefined || levelMutations.includes(arrowFunctionMutator.operators.ArrowFunction.mutationName); } diff --git a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts index 70cf33ef19..dd5c829e69 100644 --- a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts @@ -4,31 +4,29 @@ import { AssignmentOperator } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; -const operators: NodeMutatorConfiguration = { - '+=': { replacement: '-=', mutationName: 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment' }, - '-=': { replacement: '+=', mutationName: 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment' }, - '*=': { replacement: '/=', mutationName: 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment' }, - '/=': { replacement: '*=', mutationName: 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment' }, - '%=': { replacement: '*=', mutationName: 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment' }, - '<<=': { replacement: '>>=', mutationName: 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment' }, - '>>=': { replacement: '<<=', mutationName: 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment' }, - '&=': { replacement: '|=', mutationName: 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment' }, - '|=': { replacement: '&=', mutationName: 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment' }, - '&&=': { replacement: '||=', mutationName: 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment' }, - '||=': { replacement: '&&=', mutationName: 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment' }, - '??=': { replacement: '&&=', mutationName: 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment' }, -}; - const stringTypes = Object.freeze(['StringLiteral', 'TemplateLiteral']); const stringAssignmentTypes = Object.freeze(['&&=', '||=', '??=']); -export const assignmentOperatorMutator: NodeMutator = { +export const assignmentOperatorMutator: NodeMutator = { name: 'AssignmentOperator', + operators: { + '+=': { replacement: '-=', mutationName: 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment' }, + '-=': { replacement: '+=', mutationName: 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment' }, + '*=': { replacement: '/=', mutationName: 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment' }, + '/=': { replacement: '*=', mutationName: 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment' }, + '%=': { replacement: '*=', mutationName: 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment' }, + '<<=': { replacement: '>>=', mutationName: 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment' }, + '>>=': { replacement: '<<=', mutationName: 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment' }, + '&=': { replacement: '|=', mutationName: 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment' }, + '|=': { replacement: '&=', mutationName: 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment' }, + '&&=': { replacement: '||=', mutationName: 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment' }, + '||=': { replacement: '&&=', mutationName: 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment' }, + '??=': { replacement: '&&=', mutationName: 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment' }, + }, + *mutate(path, levelMutations) { if ( path.isAssignmentExpression() && @@ -36,7 +34,7 @@ export const assignmentOperatorMutator: NodeMutator = { isSupported(path.node) && isInMutationLevel(path.node, levelMutations) ) { - const mutatedOperator = operators[path.node.operator].replacement; + const mutatedOperator = this.operators[path.node.operator].replacement; const replacementOperator = deepCloneNode(path.node); replacementOperator.operator = mutatedOperator; yield replacementOperator; @@ -48,12 +46,12 @@ function isInMutationLevel(node: types.AssignmentExpression, operations: string[ if (operations === undefined) { return true; } - const { mutationName } = operators[node.operator]; + const { mutationName } = assignmentOperatorMutator.operators[node.operator]; return operations.some((op) => op === mutationName); } -function isSupportedAssignmentOperator(operator: string): operator is keyof typeof operators { - return Object.keys(operators).includes(operator); +function isSupportedAssignmentOperator(operator: string): boolean { + return Object.keys(assignmentOperatorMutator.operators).includes(operator); } function isSupported(node: types.AssignmentExpression): boolean { diff --git a/packages/instrumenter/src/mutators/block-statement-mutator.ts b/packages/instrumenter/src/mutators/block-statement-mutator.ts index 6b150ec99b..2ecd4b75a9 100644 --- a/packages/instrumenter/src/mutators/block-statement-mutator.ts +++ b/packages/instrumenter/src/mutators/block-statement-mutator.ts @@ -2,19 +2,17 @@ import babel, { type NodePath } from '@babel/core'; import { BlockStatement } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - BlockStatement: { mutationName: 'BlockStatement_Removal' }, -}; - -export const blockStatementMutator: NodeMutator = { +export const blockStatementMutator: NodeMutator = { name: 'BlockStatement', + operators: { + BlockStatement: { mutationName: 'BlockStatement_Removal' }, + }, + *mutate(path, levelMutations) { if (path.isBlockStatement() && isValid(path) && isInMutationLevel(levelMutations)) { yield types.blockStatement([]); @@ -79,5 +77,5 @@ function hasSuperExpressionOnFirstLine(constructor: NodePath = { - true: { replacement: false, mutationName: 'BooleanLiteral_TrueLiteral_ToFalseLiteral' }, - false: { replacement: true, mutationName: 'BooleanLiteral_FalseLiteral_ToTrueLiteral' }, - '!': { replacement: '', mutationName: 'BooleanLiteral_LogicalNot_Removal' }, -}; - -export const booleanLiteralMutator: NodeMutator = { +export const booleanLiteralMutator: NodeMutator = { name: 'BooleanLiteral', + operators: { + true: { replacement: false, mutationName: 'BooleanLiteral_TrueLiteral_ToFalseLiteral' }, + false: { replacement: true, mutationName: 'BooleanLiteral_FalseLiteral_ToTrueLiteral' }, + '!': { replacement: '', mutationName: 'BooleanLiteral_LogicalNot_Removal' }, + }, + *mutate(path, levelMutations) { if (isInMutationLevel(path, levelMutations)) { if (path.isBooleanLiteral()) { @@ -36,13 +34,13 @@ function isInMutationLevel(path: any, levelMutations: string[] | undefined): boo return true; } if (path.isBooleanLiteral()) { - const { mutationName: mutatorName } = operators[path.node.value as keyof typeof operators]; + const { mutationName: mutatorName } = booleanLiteralMutator.operators[path.node.value]; return levelMutations.some((lit) => lit === mutatorName); } return ( path.isUnaryExpression() && path.node.operator === '!' && path.node.prefix && - levelMutations.some((lit: string) => lit === operators['!'].mutationName) + levelMutations.some((lit: string) => lit === booleanLiteralMutator.operators['!'].mutationName) ); } diff --git a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts index 052f8c2183..4df585597d 100644 --- a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts @@ -4,46 +4,44 @@ import { ConditionalExpression } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; const booleanOperators = Object.freeze(['!=', '!==', '&&', '<', '<=', '==', '===', '>', '>=', '||']); const { types } = babel; -const operators: NodeMutatorConfiguration = { - BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_BooleanExpression_ToFalseLiteral' }, - BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_BooleanExpression_ToTrueLiteral' }, - DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral' }, - ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_ForLoopCondition_ToFalseLiteral' }, - IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_IfCondition_ToFalseLiteral' }, - IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_IfCondition_ToTrueLiteral' }, - WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral' }, - SwitchToEmpty: { replacement: [], mutationName: 'ConditionalExpression_SwitchStatementBody_Removal' }, -}; - -export const conditionalExpressionMutator: NodeMutator = { +export const conditionalExpressionMutator: NodeMutator = { name: 'ConditionalExpression', + operators: { + BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_BooleanExpression_ToFalseLiteral' }, + BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_BooleanExpression_ToTrueLiteral' }, + DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral' }, + ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_ForLoopCondition_ToFalseLiteral' }, + IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_IfCondition_ToFalseLiteral' }, + IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_IfCondition_ToTrueLiteral' }, + WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral' }, + SwitchToEmpty: { replacement: [], mutationName: 'ConditionalExpression_SwitchStatementBody_Removal' }, + }, + *mutate(path, levelMutations) { if (isTestOfLoop(path)) { - if (isTestOfWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(operators.WhileLoopToFalse.mutationName))) { - yield operators.WhileLoopToFalse.replacement; + if (isTestOfWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.WhileLoopToFalse.mutationName))) { + yield this.operators.WhileLoopToFalse.replacement; } - if (isTestOfDoWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(operators.DoWhileLoopToFalse.mutationName))) { - yield operators.DoWhileLoopToFalse.replacement; + if (isTestOfDoWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.DoWhileLoopToFalse.mutationName))) { + yield this.operators.DoWhileLoopToFalse.replacement; } - if (isTestOfForLoop(path) && (levelMutations === undefined || levelMutations.includes(operators.ForLoopToFalse.mutationName))) { - yield operators.ForLoopToFalse.replacement; + if (isTestOfForLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopToFalse.mutationName))) { + yield this.operators.ForLoopToFalse.replacement; } } else if (isTestOfCondition(path)) { - if (levelMutations === undefined || levelMutations.includes(operators.IfToTrue.mutationName)) { - yield operators.IfToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.IfToTrue.mutationName)) { + yield this.operators.IfToTrue.replacement; } - if (levelMutations === undefined || levelMutations.includes(operators.IfToFalse.mutationName)) { - yield operators.IfToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.IfToFalse.mutationName)) { + yield this.operators.IfToFalse.replacement; } } else if (isBooleanExpression(path)) { if (path.parent?.type === 'LogicalExpression') { @@ -51,8 +49,8 @@ export const conditionalExpressionMutator: NodeMutator = { // has the same behavior as the (true) mutator, handled in the // isTestOfCondition branch above if (path.parent.operator === '||') { - if (levelMutations === undefined || levelMutations.includes(operators.BooleanExpressionToFalse.mutationName)) { - yield operators.BooleanExpressionToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalse.mutationName)) { + yield this.operators.BooleanExpressionToFalse.replacement; } return; } @@ -60,29 +58,29 @@ export const conditionalExpressionMutator: NodeMutator = { // has the same behavior as the (false) mutator, handled in the // isTestOfCondition branch above if (path.parent.operator === '&&') { - if (levelMutations === undefined || levelMutations.includes(operators.BooleanExpressionToTrue.mutationName)) { - yield operators.BooleanExpressionToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrue.mutationName)) { + yield this.operators.BooleanExpressionToTrue.replacement; } return; } } - if (levelMutations === undefined || levelMutations.includes(operators.BooleanExpressionToTrue.mutationName)) { - yield operators.BooleanExpressionToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrue.mutationName)) { + yield this.operators.BooleanExpressionToTrue.replacement; } - if (levelMutations === undefined || levelMutations.includes(operators.BooleanExpressionToFalse.mutationName)) { - yield operators.BooleanExpressionToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalse.mutationName)) { + yield this.operators.BooleanExpressionToFalse.replacement; } } else if (path.isForStatement() && !path.node.test) { - if (levelMutations === undefined || levelMutations.includes(operators.ForLoopToFalse.mutationName)) { + if (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopToFalse.mutationName)) { const replacement = deepCloneNode(path.node); - replacement.test = operators.ForLoopToFalse.replacement; + replacement.test = this.operators.ForLoopToFalse.replacement; yield replacement; } } else if (path.isSwitchCase() && path.node.consequent.length > 0) { // if not a fallthrough case - if (levelMutations === undefined || levelMutations.includes(operators.SwitchToEmpty.mutationName)) { + if (levelMutations === undefined || levelMutations.includes(this.operators.SwitchToEmpty.mutationName)) { const replacement = deepCloneNode(path.node); - replacement.consequent = operators.SwitchToEmpty.replacement; + replacement.consequent = this.operators.SwitchToEmpty.replacement; yield replacement; } } diff --git a/packages/instrumenter/src/mutators/equality-operator-mutator.ts b/packages/instrumenter/src/mutators/equality-operator-mutator.ts index 1f611950f2..84faecab84 100644 --- a/packages/instrumenter/src/mutators/equality-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/equality-operator-mutator.ts @@ -2,40 +2,35 @@ import babel, { types } from '@babel/core'; import { EqualityOperator } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; const { types: t } = babel; -const operators: NodeMutatorConfiguration = { - '=': { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, +export const equalityOperatorMutator: NodeMutator = { + name: 'EqualityOperator', - '<=To<': { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, - '<=To>': { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, + operators: { + '=': { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, - '>To>=': { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, - '>To<=': { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, + '<=To<': { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, + '<=To>': { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, - '>=To>': { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, - '>=To<': { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, + '>To>=': { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, + '>To<=': { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, - '==': { replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }, - '!=': { replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }, - '===': { replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }, - '!==': { replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }, -}; + '>=To>': { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, + '>=To<': { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, -function isEqualityOperator(operator: string): operator is keyof typeof operators { - return Object.keys(operators).includes(operator); -} -export const equalityOperatorMutator: NodeMutator = { - name: 'EqualityOperator', + '==To!=': { replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }, + '!=To==': { replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }, + '===To!==': { replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }, + '!==To===': { replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }, + }, - *mutate(path, operations) { + *mutate(path, levelMutations) { if (path.isBinaryExpression() && isEqualityOperator(path.node.operator)) { - const allMutations = filterMutationLevel(path.node, operations); + const allMutations = filterMutationLevel(path.node, levelMutations); // throw new Error(allMutations.toString()); for (const mutableOperator of allMutations) { const replacementOperator = t.cloneNode(path.node, true); @@ -46,15 +41,20 @@ export const equalityOperatorMutator: NodeMutator = { }, }; +function isEqualityOperator(operator: string): operator is keyof typeof equalityOperatorMutator.operators { + return Object.keys(equalityOperatorMutator.operators).some((k) => k.startsWith(operator + 'To')); +} + function filterMutationLevel(node: types.BinaryExpression, levelMutations: string[] | undefined) { // Nothing allowed, so return an empty array + + const allMutations = Object.keys(equalityOperatorMutator.operators) + .filter((k) => k.startsWith(node.operator + 'To')) + .map((k) => equalityOperatorMutator.operators[k]); + if (levelMutations === undefined) { - return []; + return allMutations; } - const allMutations = Object.keys(operators) - .filter((k) => k.startsWith(node.operator)) - .map((k) => operators[k]); - return allMutations.filter((mut) => levelMutations.some((op) => op === mut.mutationName)); } diff --git a/packages/instrumenter/src/mutators/logical-operator-mutator.ts b/packages/instrumenter/src/mutators/logical-operator-mutator.ts index 75e769d489..47a52d4d11 100644 --- a/packages/instrumenter/src/mutators/logical-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/logical-operator-mutator.ts @@ -1,22 +1,21 @@ import { LogicalOperator } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; import { deepCloneNode } from '../util/index.js'; import { NodeMutator } from './index.js'; -const operators: NodeMutatorConfiguration = { - '&&': { replacement: '||', mutationName: 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator' }, - '||': { replacement: '&&', mutationName: 'LogicalOperator_LogicalOrOperator_ToLogicalAndOperator' }, - '??': { replacement: '&&', mutationName: 'LogicalOperator_NullishCoalescingOperator_ToLogicalAnd' }, -}; - -export const logicalOperatorMutator: NodeMutator = { +export const logicalOperatorMutator: NodeMutator = { name: 'LogicalOperator', + operators: { + '&&': { replacement: '||', mutationName: 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator' }, + '||': { replacement: '&&', mutationName: 'LogicalOperator_LogicalOrOperator_ToLogicalAndOperator' }, + '??': { replacement: '&&', mutationName: 'LogicalOperator_NullishCoalescingOperator_ToLogicalAnd' }, + }, + *mutate(path, levelMutations) { if (path.isLogicalExpression() && isSupported(path.node.operator) && isInMutationLevel(path.node.operator, levelMutations)) { - const mutatedOperator = operators[path.node.operator].replacement; + const mutatedOperator = this.operators[path.node.operator].replacement; const replacementOperator = deepCloneNode(path.node); replacementOperator.operator = mutatedOperator; @@ -25,10 +24,10 @@ export const logicalOperatorMutator: NodeMutator = { }, }; -function isSupported(operator: string): operator is keyof typeof operators { - return Object.keys(operators).includes(operator); +function isSupported(operator: string): operator is keyof typeof logicalOperatorMutator.operators { + return Object.keys(logicalOperatorMutator.operators).includes(operator); } -function isInMutationLevel(operator: string, levelMutations: string[] | undefined): operator is keyof typeof operators { - return levelMutations === undefined || levelMutations.includes(operators[operator].mutationName as string); +function isInMutationLevel(operator: string, levelMutations: string[] | undefined): boolean { + return levelMutations === undefined || levelMutations.includes(logicalOperatorMutator.operators[operator].mutationName as string); } diff --git a/packages/instrumenter/src/mutators/method-expression-mutator.ts b/packages/instrumenter/src/mutators/method-expression-mutator.ts index 4a40d5cc78..e1a00144b7 100644 --- a/packages/instrumenter/src/mutators/method-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/method-expression-mutator.ts @@ -4,39 +4,42 @@ import { MethodExpression } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; const { types } = babel; -// prettier-ignore -const operators: NodeMutatorConfiguration = { - 'charAt': { replacement: null, mutationName: 'MethodExpression_charAtMethodCall_Removal' }, - 'endsWith': { replacement: 'startsWith', mutationName: 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall' }, - 'startsWith': { replacement: 'endsWith', mutationName: 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall' }, - 'every': { replacement: 'some', mutationName: 'MethodExpression_everyMethodCall_TosomeMethodCall' }, - 'some': { replacement: 'every', mutationName: 'MethodExpression_someMethodCall_ToeveryMethodCall' }, - 'filter': { replacement: null, mutationName: 'MethodExpression_filterMethodCall_Removal' }, - 'reverse': { replacement: null, mutationName: 'MethodExpression_reverseMethodCall_Removal' }, - 'slice': { replacement: null, mutationName: 'MethodExpression_sliceMethodCall_Removal' }, - 'sort': { replacement: null, mutationName: 'MethodExpression_sortMethodCall_Removal' }, - 'substr': { replacement: null, mutationName: 'MethodExpression_substrMethodCall_Removal' }, - 'substring': { replacement: null, mutationName: 'MethodExpression_substringMethodCall_Removal' }, - 'toLocaleLowerCase': { replacement: 'toLocaleUpperCase', mutationName: 'MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall' }, - 'toLocaleUpperCase': { replacement: 'toLocaleLowerCase', mutationName: 'MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall' }, - 'toLowerCase': { replacement: 'toUpperCase', mutationName: 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall' }, - 'toUpperCase': { replacement: 'toLowerCase', mutationName: 'MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall' }, - 'trim': { replacement: null, mutationName: 'MethodExpression_trimMethodCall_Removal' }, - 'trimEnd': { replacement: 'trimStart', mutationName: 'MethodExpression_trimEndMethodCall_TotrimStartMethodCall' }, - 'trimStart': { replacement: 'trimEnd', mutationName: 'MethodExpression_trimStartMethodCall_TotrimEndMutator' }, - 'min': { replacement: 'max', mutationName: 'MethodExpression_minMethodCall_TomaxMethodCall' }, - 'max': { replacement: 'min', mutationName: 'MethodExpression_maxMethodCall_toMinMethodCall' }, -}; - -export const methodExpressionMutator: NodeMutator = { +export const methodExpressionMutator: NodeMutator = { name: 'MethodExpression', + operators: { + charAt: { replacement: null, mutationName: 'MethodExpression_charAtMethodCall_Removal' }, + endsWith: { replacement: 'startsWith', mutationName: 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall' }, + startsWith: { replacement: 'endsWith', mutationName: 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall' }, + every: { replacement: 'some', mutationName: 'MethodExpression_everyMethodCall_TosomeMethodCall' }, + some: { replacement: 'every', mutationName: 'MethodExpression_someMethodCall_ToeveryMethodCall' }, + filter: { replacement: null, mutationName: 'MethodExpression_filterMethodCall_Removal' }, + reverse: { replacement: null, mutationName: 'MethodExpression_reverseMethodCall_Removal' }, + slice: { replacement: null, mutationName: 'MethodExpression_sliceMethodCall_Removal' }, + sort: { replacement: null, mutationName: 'MethodExpression_sortMethodCall_Removal' }, + substr: { replacement: null, mutationName: 'MethodExpression_substrMethodCall_Removal' }, + substring: { replacement: null, mutationName: 'MethodExpression_substringMethodCall_Removal' }, + toLocaleLowerCase: { + replacement: 'toLocaleUpperCase', + mutationName: 'MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall', + }, + toLocaleUpperCase: { + replacement: 'toLocaleLowerCase', + mutationName: 'MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall', + }, + toLowerCase: { replacement: 'toUpperCase', mutationName: 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall' }, + toUpperCase: { replacement: 'toLowerCase', mutationName: 'MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall' }, + trim: { replacement: null, mutationName: 'MethodExpression_trimMethodCall_Removal' }, + trimEnd: { replacement: 'trimStart', mutationName: 'MethodExpression_trimEndMethodCall_TotrimStartMethodCall' }, + trimStart: { replacement: 'trimEnd', mutationName: 'MethodExpression_trimStartMethodCall_TotrimEndMutator' }, + min: { replacement: 'max', mutationName: 'MethodExpression_minMethodCall_TomaxMethodCall' }, + max: { replacement: 'min', mutationName: 'MethodExpression_maxMethodCall_toMinMethodCall' }, + }, + *mutate(path, levelMutations) { // In case `operations` is undefined, any checks will short-circuit to true and allow the mutation @@ -49,7 +52,7 @@ export const methodExpressionMutator: NodeMutator = { return; } - const mutation = operators[callee.property.name]; + const mutation = this.operators[callee.property.name]; if (mutation === undefined) { // Function is not known in `operators`, so no mutations return; diff --git a/packages/instrumenter/src/mutators/mutate.ts b/packages/instrumenter/src/mutators/mutate.ts index 7350fead57..cc8153f1db 100644 --- a/packages/instrumenter/src/mutators/mutate.ts +++ b/packages/instrumenter/src/mutators/mutate.ts @@ -1,3 +1,5 @@ +import { MutationLevel } from '../mutation-level/mutation-level.js'; + import { arithmeticOperatorMutator } from './arithmetic-operator-mutator.js'; import { NodeMutator } from './node-mutator.js'; import { blockStatementMutator } from './block-statement-mutator.js'; @@ -16,7 +18,7 @@ import { regexMutator } from './regex-mutator.js'; import { optionalChainingMutator } from './optional-chaining-mutator.js'; import { assignmentOperatorMutator } from './assignment-operator-mutator.js'; -export const allMutators: NodeMutator[] = [ +export const allMutators: Array> = [ arithmeticOperatorMutator, arrayDeclarationMutator, arrowFunctionMutator, diff --git a/packages/instrumenter/src/mutators/node-mutator.ts b/packages/instrumenter/src/mutators/node-mutator.ts index 33c8755e5e..5a87c2b4df 100644 --- a/packages/instrumenter/src/mutators/node-mutator.ts +++ b/packages/instrumenter/src/mutators/node-mutator.ts @@ -1,6 +1,9 @@ import type { types, NodePath } from '@babel/core'; -export interface NodeMutator { +import { NodeMutatorConfiguration, MutationLevel } from '../mutation-level/mutation-level.js'; + +export interface NodeMutator { mutate(path: NodePath, levelMutations: string[] | undefined): Iterable; readonly name: string; + operators: NodeMutatorConfiguration; } diff --git a/packages/instrumenter/src/mutators/object-literal-mutator.ts b/packages/instrumenter/src/mutators/object-literal-mutator.ts index 33c2efe300..1114a37f48 100644 --- a/packages/instrumenter/src/mutators/object-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/object-literal-mutator.ts @@ -2,19 +2,17 @@ import babel from '@babel/core'; import { ObjectLiteral } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - ObjectLiteral: { mutationName: 'ObjectLiteral_PropertiesRemoval' }, -}; - -export const objectLiteralMutator: NodeMutator = { +export const objectLiteralMutator: NodeMutator = { name: 'ObjectLiteral', + operators: { + ObjectLiteral: { mutationName: 'ObjectLiteral_PropertiesRemoval' }, + }, + *mutate(path, levelMutations) { if (path.isObjectExpression() && path.node.properties.length > 0 && isInMutationLevel(levelMutations)) { yield types.objectExpression([]); @@ -23,5 +21,5 @@ export const objectLiteralMutator: NodeMutator = { }; function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(operators.ObjectLiteral.mutationName as string); + return levelMutations === undefined || levelMutations.includes(objectLiteralMutator.operators.ObjectLiteral.mutationName as string); } diff --git a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts index 4a14e48559..b764e760ab 100644 --- a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts +++ b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts @@ -2,8 +2,6 @@ import babel from '@babel/core'; import { OptionalChaining } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; const { types: t } = babel; @@ -21,19 +19,19 @@ const { types: t } = babel; * foo?.() -> foo() */ -const operators: NodeMutatorConfiguration = { - OptionalCallExpression: { mutationName: 'OptionalChaining_OptionalCallExpression_OptionRemoval' }, - OptionalMemberExpression: { mutationName: 'OptionalChaining_OptionalMemberExpression_OptionRemoval' }, -}; - -export const optionalChainingMutator: NodeMutator = { +export const optionalChainingMutator: NodeMutator = { name: 'OptionalChaining', + operators: { + OptionalCallExpression: { mutationName: 'OptionalChaining_OptionalCallExpression_OptionRemoval' }, + OptionalMemberExpression: { mutationName: 'OptionalChaining_OptionalMemberExpression_OptionRemoval' }, + }, + *mutate(path, levelMutations) { if ( path.isOptionalMemberExpression() && path.node.optional && - (levelMutations === undefined || levelMutations.includes(operators.OptionalMemberExpression.mutationName)) + (levelMutations === undefined || levelMutations.includes(this.operators.OptionalMemberExpression.mutationName)) ) { yield t.optionalMemberExpression( t.cloneNode(path.node.object, true), @@ -45,7 +43,7 @@ export const optionalChainingMutator: NodeMutator = { if ( path.isOptionalCallExpression() && path.node.optional && - (levelMutations === undefined || levelMutations.includes(operators.OptionalCallExpression.mutationName)) + (levelMutations === undefined || levelMutations.includes(this.operators.OptionalCallExpression.mutationName)) ) { yield t.optionalCallExpression( t.cloneNode(path.node.callee, true), diff --git a/packages/instrumenter/src/mutators/regex-mutator.ts b/packages/instrumenter/src/mutators/regex-mutator.ts index 937f364613..7a42cf7582 100644 --- a/packages/instrumenter/src/mutators/regex-mutator.ts +++ b/packages/instrumenter/src/mutators/regex-mutator.ts @@ -3,16 +3,10 @@ import * as weaponRegex from 'weapon-regex'; import { Regex } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - Regex: { mutationName: 'Regex_Removal' }, -}; - /** * Checks that a string literal is an obvious regex string literal * @param path The string literal to checks @@ -37,9 +31,13 @@ function getFlags(path: NodePath): string | undefined { const weaponRegexOptions: weaponRegex.MutationOptions = { mutationLevels: [1] }; -export const regexMutator: NodeMutator = { +export const regexMutator: NodeMutator = { name: 'Regex', + operators: { + Regex: { mutationName: 'Regex_Removal' }, + }, + *mutate(path, options) { if (path.isRegExpLiteral() && isInMutationLevel(options)) { for (const replacementPattern of mutatePattern(path.node.pattern, path.node.flags)) { @@ -69,5 +67,5 @@ function mutatePattern(pattern: string, flags: string | undefined): string[] { } function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(operators.Regex.mutationName); + return levelMutations === undefined || levelMutations.includes(regexMutator.operators.Regex.mutationName); } diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index 87553d6aeb..aec028af22 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -2,47 +2,45 @@ import babel, { type NodePath } from '@babel/core'; import { StringLiteral } from '@stryker-mutator/api/core'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './node-mutator.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'StringLiteral_EmptyStringLiteral_ToFilledStringLiteral' }, - EmptyString: { replacement: types.stringLiteral(''), mutationName: 'StringLiteral_FilledStringLiteral_ToEmptyStringLiteral' }, - EmptyInterpolation: { - replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), - mutationName: 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString', - }, - FillInterpolation: { - replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), - mutationName: 'StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString', - }, -}; - -export const stringLiteralMutator: NodeMutator = { +export const stringLiteralMutator: NodeMutator = { name: 'StringLiteral', + operators: { + FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'StringLiteral_EmptyStringLiteral_ToFilledStringLiteral' }, + EmptyString: { replacement: types.stringLiteral(''), mutationName: 'StringLiteral_FilledStringLiteral_ToEmptyStringLiteral' }, + EmptyInterpolation: { + replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), + mutationName: 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString', + }, + FillInterpolation: { + replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), + mutationName: 'StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString', + }, + }, + *mutate(path, levelMutations) { if (path.isTemplateLiteral()) { const stringIsEmpty = path.node.quasis.length === 1 && path.node.quasis[0].value.raw.length === 0; if ( levelMutations === undefined || - (stringIsEmpty && levelMutations.includes(operators.FillInterpolation.mutationName)) || - (!stringIsEmpty && levelMutations.includes(operators.EmptyInterpolation.mutationName)) + (stringIsEmpty && levelMutations.includes(this.operators.FillInterpolation.mutationName)) || + (!stringIsEmpty && levelMutations.includes(this.operators.EmptyInterpolation.mutationName)) ) { - yield stringIsEmpty ? operators.FillInterpolation.replacement : operators.EmptyInterpolation.replacement; + yield stringIsEmpty ? this.operators.FillInterpolation.replacement : this.operators.EmptyInterpolation.replacement; } } if (path.isStringLiteral() && isValidParent(path)) { const stringIsEmpty = path.node.value.length === 0; if ( levelMutations === undefined || - (stringIsEmpty && levelMutations.includes(operators.FillString.mutationName)) || - (!stringIsEmpty && levelMutations.includes(operators.EmptyString.mutationName)) + (stringIsEmpty && levelMutations.includes(this.operators.FillString.mutationName)) || + (!stringIsEmpty && levelMutations.includes(this.operators.EmptyString.mutationName)) ) { - yield stringIsEmpty ? operators.FillString.replacement : operators.EmptyString.replacement; + yield stringIsEmpty ? this.operators.FillString.replacement : this.operators.EmptyString.replacement; } } }, diff --git a/packages/instrumenter/src/mutators/unary-operator-mutator.ts b/packages/instrumenter/src/mutators/unary-operator-mutator.ts index da66bee3ac..498325072f 100644 --- a/packages/instrumenter/src/mutators/unary-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/unary-operator-mutator.ts @@ -4,24 +4,22 @@ import { UnaryOperator } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - '+': { replacement: '-', mutationName: 'UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator' }, - '-': { replacement: '+', mutationName: 'UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator' }, - '~': { replacement: '', mutationName: 'UnaryOperator_BitwiseOrOperator_Removal' }, -}; - -export const unaryOperatorMutator: NodeMutator = { +export const unaryOperatorMutator: NodeMutator = { name: 'UnaryOperator', + operators: { + '+': { replacement: '-', mutationName: 'UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator' }, + '-': { replacement: '+', mutationName: 'UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator' }, + '~': { replacement: '', mutationName: 'UnaryOperator_BitwiseOrOperator_Removal' }, + }, + *mutate(path, levelMutations) { if (path.isUnaryExpression() && isSupported(path.node.operator) && path.node.prefix) { - const mutation = operators[path.node.operator]; + const mutation = this.operators[path.node.operator]; if (levelMutations !== undefined && !levelMutations.includes(mutation.mutationName)) { // Mutator not allowed by MutationLevel @@ -37,6 +35,6 @@ export const unaryOperatorMutator: NodeMutator = { }, }; -function isSupported(operator: string): operator is keyof typeof operators { - return operator in operators; +function isSupported(operator: string): operator is keyof typeof unaryOperatorMutator.operators { + return operator in unaryOperatorMutator.operators; } diff --git a/packages/instrumenter/src/mutators/update-operator-mutator.ts b/packages/instrumenter/src/mutators/update-operator-mutator.ts index cf1e2cbf46..2ca1e8320b 100644 --- a/packages/instrumenter/src/mutators/update-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/update-operator-mutator.ts @@ -4,34 +4,32 @@ import { UpdateOperator } from '@stryker-mutator/api/core'; import { deepCloneNode } from '../util/index.js'; -import { NodeMutatorConfiguration } from '../mutation-level/mutation-level.js'; - import { NodeMutator } from './index.js'; const { types } = babel; -const operators: NodeMutatorConfiguration = { - UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator: { - replacement: '--', - mutationName: 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', - }, - UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator: { - replacement: '++', - mutationName: 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', - }, - UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator: { - replacement: '--', - mutationName: 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', - }, - UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator: { - replacement: '++', - mutationName: 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', - }, -}; - -export const updateOperatorMutator: NodeMutator = { +export const updateOperatorMutator: NodeMutator = { name: 'UpdateOperator', + operators: { + UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator: { + replacement: '--', + mutationName: 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', + }, + UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator: { + replacement: '++', + mutationName: 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', + }, + UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator: { + replacement: '--', + mutationName: 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', + }, + UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator: { + replacement: '++', + mutationName: 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', + }, + }, + *mutate(path, levelMutations) { if (path.isUpdateExpression()) { if (levelMutations === undefined) { @@ -40,13 +38,19 @@ export const updateOperatorMutator: NodeMutator = { } else { let replacement = undefined; if (path.node.prefix && path.node.operator == '++') { - replacement = getReplacement(levelMutations, operators.UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator.mutationName); + replacement = getReplacement(levelMutations, this.operators.UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator.mutationName); } else if (path.node.prefix && path.node.operator == '--') { - replacement = getReplacement(levelMutations, operators.UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator.mutationName); + replacement = getReplacement(levelMutations, this.operators.UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator.mutationName); } else if (!path.node.prefix && path.node.operator == '++') { - replacement = getReplacement(levelMutations, operators.UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator.mutationName); + replacement = getReplacement( + levelMutations, + this.operators.UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator.mutationName, + ); } else if (!path.node.prefix && path.node.operator == '--') { - replacement = getReplacement(levelMutations, operators.UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator.mutationName); + replacement = getReplacement( + levelMutations, + this.operators.UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator.mutationName, + ); } if (replacement !== undefined) { yield types.updateExpression(replacement, deepCloneNode(path.node.argument), path.node.prefix); @@ -58,7 +62,7 @@ export const updateOperatorMutator: NodeMutator = { function getReplacement(levelMutations: string[], mutationName: string): '--' | '++' | undefined { if (levelMutations.includes(mutationName)) { - const { replacement } = operators[mutationName]; + const { replacement } = updateOperatorMutator.operators[mutationName]; return replacement; } return undefined; diff --git a/packages/instrumenter/src/transformers/directive-bookkeeper.ts b/packages/instrumenter/src/transformers/directive-bookkeeper.ts index 6d724058da..15857acd47 100644 --- a/packages/instrumenter/src/transformers/directive-bookkeeper.ts +++ b/packages/instrumenter/src/transformers/directive-bookkeeper.ts @@ -4,6 +4,7 @@ import { notEmpty } from '@stryker-mutator/util'; import { Logger } from '@stryker-mutator/api/logging'; import { NodeMutator } from '../mutators/node-mutator.js'; +import { MutationLevel } from '../mutation-level/mutation-level.js'; const WILDCARD = 'all'; const DEFAULT_REASON = 'Ignored using a comment'; @@ -60,7 +61,7 @@ export class DirectiveBookkeeper { constructor( private readonly logger: Logger, - private readonly allMutators: NodeMutator[], + private readonly allMutators: Array>, private readonly originFileName: string, ) { this.allMutatorNames = this.allMutators.map((x) => x.name.toLowerCase()); diff --git a/packages/instrumenter/test/helpers/expect-mutation.ts b/packages/instrumenter/test/helpers/expect-mutation.ts index 741b51fada..a2a60ee026 100644 --- a/packages/instrumenter/test/helpers/expect-mutation.ts +++ b/packages/instrumenter/test/helpers/expect-mutation.ts @@ -4,6 +4,7 @@ import generator from '@babel/generator'; import { expect } from 'chai'; import { NodeMutator } from '../../src/mutators/node-mutator.js'; +import { MutationLevel } from '../../src/mutation-level/mutation-level.js'; const generate = generator.default; @@ -35,12 +36,12 @@ const plugins = [ 'typescript', ] as ParserPlugin[]; -export function expectJSMutation(sut: NodeMutator, originalCode: string, ...expectedReplacements: string[]): void { +export function expectJSMutation(sut: NodeMutator, originalCode: string, ...expectedReplacements: string[]): void { expectJSMutationWithLevel(sut, undefined, originalCode, ...expectedReplacements); } export function expectJSMutationWithLevel( - sut: NodeMutator, + sut: NodeMutator, level: string[] | undefined, originalCode: string, ...expectedReplacements: string[] diff --git a/packages/instrumenter/test/unit/mutators/mutate.spec.ts b/packages/instrumenter/test/unit/mutators/mutate.spec.ts index 2d58fb9cf6..0a507e77af 100644 --- a/packages/instrumenter/test/unit/mutators/mutate.spec.ts +++ b/packages/instrumenter/test/unit/mutators/mutate.spec.ts @@ -5,6 +5,7 @@ import { fileURLToPath, pathToFileURL } from 'url'; import { expect } from 'chai'; import { allMutators, NodeMutator } from '../../../src/mutators/index.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; describe('allMutators', () => { it('should include all mutators', async () => { @@ -23,7 +24,7 @@ describe('allMutators', () => { } return mutatorModule[keys[0]]; }), - )) as NodeMutator[]; + )) as Array>; actualMutators.forEach((mutator) => { expect(allMutators.includes(mutator), `${mutator.name} is missing!`).ok; }); diff --git a/packages/instrumenter/test/unit/transformers/babel-transformer.spec.ts b/packages/instrumenter/test/unit/transformers/babel-transformer.spec.ts index 9ca93afe64..a166951e6f 100644 --- a/packages/instrumenter/test/unit/transformers/babel-transformer.spec.ts +++ b/packages/instrumenter/test/unit/transformers/babel-transformer.spec.ts @@ -14,6 +14,7 @@ import { instrumentationBabelHeader } from '../../../src/util/index.js'; import { MutantPlacer } from '../../../src/mutant-placers/index.js'; import { NodeMutator } from '../../../src/mutators/index.js'; import { createJSAst, createTSAst } from '../../helpers/factories.js'; +import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const generate = generator.default; const { types } = babel; @@ -26,20 +27,22 @@ const { types } = babel; */ describe('babel-transformer', () => { let context: sinon.SinonStubbedInstance; - let mutators: NodeMutator[]; + let mutators: Array>; let mutantPlacers: MutantPlacer[]; let mutantCollector: MutantCollector; - const fooMutator: NodeMutator = { + const fooMutator: NodeMutator = { name: 'Foo', + operators: {}, *mutate(path) { if (path.isIdentifier() && path.node.name === 'foo') { yield types.identifier('bar'); } }, }; - const plusMutator: NodeMutator = { + const plusMutator: NodeMutator = { name: 'Plus', + operators: {}, *mutate(path) { if (path.isBinaryExpression() && path.node.operator === '+') { yield types.binaryExpression('-', types.cloneNode(path.node.left, true), types.cloneNode(path.node.right, true)); @@ -622,6 +625,7 @@ describe('babel-transformer', () => { }); mutators.push({ name: 'blockMutatorForTest', + operators: {}, *mutate(path) { if (path.isBlockStatement()) { yield types.blockStatement([]); @@ -729,12 +733,10 @@ describe('babel-transformer', () => { }); function act(ast: ScriptAst) { - (transformBabel as (...args: [...Parameters>, mutators: NodeMutator[], mutantPlacers: MutantPlacer[]]) => void)( - ast, - mutantCollector, - context, - mutators, - mutantPlacers, - ); + ( + transformBabel as ( + ...args: [...Parameters>, mutators: Array>, mutantPlacers: MutantPlacer[]] + ) => void + )(ast, mutantCollector, context, mutators, mutantPlacers); } }); From 9dc80ad77feecb5e4757d619db138536ab5c4fc2 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 15:49:15 +0100 Subject: [PATCH 07/13] Update conditionalLevel test name --- .../conditional-expression-mutator.spec.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts index 1812a564ef..9dac99d5f9 100644 --- a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts @@ -4,8 +4,8 @@ import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expec import { conditionalExpressionMutator as sut } from '../../../src/mutators/conditional-expression-mutator.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const conditionLevel: MutationLevel = { - name: 'conditionLevel', +const conditionalLevel: MutationLevel = { + name: 'ConditionalLevel', ConditionalExpression: [ 'ConditionalExpression_ForLoopCondition_ToFalseLiteral', 'ConditionalExpression_IfCondition_ToFalseLiteral', @@ -14,8 +14,8 @@ const conditionLevel: MutationLevel = { ], }; -const conditionLevel2: MutationLevel = { - name: 'conditionLevel2', +const conditionalLevel2: MutationLevel = { + name: 'ConditionalLevel2', ConditionalExpression: [ 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral', 'ConditionalExpression_BooleanExpression_ToFalseLiteral', @@ -24,8 +24,8 @@ const conditionLevel2: MutationLevel = { ], }; -const conditionLevel3: MutationLevel = { - name: 'conditionLevel2', +const conditionalLevelUndefined: MutationLevel = { + name: 'ConditionLevelEmpty', }; describe(sut.name, () => { @@ -169,7 +169,7 @@ describe(sut.name, () => { it('should only mutate for, if and switch statement', () => { expectJSMutationWithLevel( sut, - conditionLevel.ConditionalExpression, + conditionalLevel.ConditionalExpression, 'for (var i = 0; i < 10; i++) { };if(x > 2); switch (x) {case 0: 2}', 'for (var i = 0; false; i++) { };if(x > 2); switch (x) {case 0: 2}', // mutates for loop 'for (var i = 0; i < 10; i++) { };if(false); switch (x) {case 0: 2}', // mutates if statement to false @@ -181,7 +181,7 @@ describe(sut.name, () => { it('should only mutate while, while do and boolean expression', () => { expectJSMutationWithLevel( sut, - conditionLevel2.ConditionalExpression, + conditionalLevel2.ConditionalExpression, 'while (a > b) { }; do { } while (a > b); var x = a > b ? 1 : 2', 'while (false) { }; do { } while (a > b); var x = a > b ? 1 : 2', // mutates while loop 'while (a > b) { }; do { } while (a > b); var x = false ? 1 : 2', // mutates boolean to false @@ -193,7 +193,7 @@ describe(sut.name, () => { it('should only mutate all', () => { expectJSMutationWithLevel( sut, - conditionLevel3.ConditionalExpression, + conditionalLevelUndefined.ConditionalExpression, 'for (var i = 0; i < 10; i++) { };if(x > 2); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', 'for (var i = 0; false; i++) { };if(x > 2); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', // mutates for loop 'for (var i = 0; i < 10; i++) { };if(false); switch (x) {case 0: 2}; while (a > b); { } do { } while (a > b); var x = a > b ? 1 : 2', // mutates if statement to false From c77919ff0a3f74fb636923847ca731f955eaf0f0 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 16:47:22 +0100 Subject: [PATCH 08/13] Finish aritmetic through conditional operators, stable --- packages/api/schema/stryker-core.json | 124 +++++++++--------- .../mutators/arithmetic-operator-mutator.ts | 10 +- .../src/mutators/array-declaration-mutator.ts | 24 ++-- .../src/mutators/arrow-function-mutator.ts | 2 +- .../mutators/assignment-operator-mutator.ts | 24 ++-- .../src/mutators/block-statement-mutator.ts | 2 +- .../src/mutators/boolean-literal-mutator.ts | 6 +- .../conditional-expression-mutator.ts | 20 +-- .../src/mutators/regex-mutator.ts | 2 +- .../arithmatic-operator-mutator.spec.ts | 6 +- .../array-declaration-mutator.spec.ts | 7 +- .../mutators/arrow-function-mutator.spec.ts | 2 +- .../assignment-operator-mutator.spec.ts | 30 ++--- .../mutators/block-statement-mutator.spec.ts | 2 +- .../mutators/boolean-literal-mutator.spec.ts | 4 +- .../conditional-expression-mutator.spec.ts | 16 +-- .../test/unit/mutators/regex-mutator.spec.ts | 2 +- 17 files changed, 136 insertions(+), 147 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index 85d0c13df4..7dcf67c3f5 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -303,28 +303,28 @@ "title": "ArithmeticOperator", "anyOf": [ { - "const" : "ArithmeticOperator_RemainderOperator_ToMultiplicationOperator", - "title": "RemainderOperatorToMultiplicationOperator", + "const" : "RemainderOperatorToMultiplicationReplacement", + "title": "RemainderOperatorToMultiplicationReplacement", "description": "Replace ```a % b``` with ```a * b```." }, { - "const" : "ArithmeticOperator_MultiplicationOperator_ToDivisionOperator", - "title": "MultiplicationOperatorToDivisionOperator", + "const" : "MultiplicationOperatorNegation", + "title": "MultiplicationOperatorNegation", "description": "Replace ```a * b``` with ```a / b```." }, { - "const" : "ArithmeticOperator_DivisionOperator_ToMultiplicationOperator", - "title": "DivisionOperatorToMultiplicationOperator", + "const" : "DivisionOperatorNegation", + "title": "DivisionOperatorNegation", "description": "Replace ```a / b``` with ```a * b```." }, { - "const" : "ArithmeticOperator_AdditionOperator_ToSubtractionOperator", - "title": "AdditionOperatorToSubtractionOperator", + "const" : "AdditionOperatorNegation", + "title": "AdditionOperatorNegation", "description": "Replace ```a + b``` with ```a - b```." }, { - "const" : "ArithmeticOperator_SubtractionOperator_ToAdditionOperator", - "title": "SubtractionOperatorToAdditionOperator", + "const" : "SubtractionOperatorNegation", + "title": "SubtractionOperatorNegation", "description": "Replace ```a - b``` with ```a + b```." } ] @@ -333,22 +333,22 @@ "title": "ArrayDeclaration", "anyOf": [ { - "const": "ArrayDeclaration_ArrayLiteral_Fill", - "title": "ArrayLiteralFill", + "const": "ArrayLiteralItemsFill", + "title": "ArrayLiteralItemsFill", "description": "Replace ```[ ]``` with ```[Stryker was here]```." }, { - "const": "ArrayDeclaration_ArrayConstructor_Fill", - "title": "ArrayConstructorFill", + "const": "ArrayConstructorItemsFill", + "title": "ArrayConstructorItemsFill", "description": "Replace ```new Array()``` with ```new Array(Stryker was here)```." }, { - "const": "ArrayDeclaration_ArrayLiteral_ItemsRemoval", + "const": "ArrayLiteralItemsRemoval", "title": "ArrayLiteralItemsRemoval", "description": "Replace ```[1, 2, 3, 4]``` with ```[ ]```." }, { - "const": "ArrayDeclaration_ArrayConstructor_ItemsRemoval", + "const": "ArrayConstructorItemsRemoval", "title": "ArrayConstructorItemsRemoval", "description": "Replace ```new Array([1, 2, 3, 4])``` with ```new Array()```." } @@ -358,90 +358,90 @@ "title": "AssignmentOperator", "anyOf": [ { - "const" : "AssignmentOperator_AdditionAssignment_ToSubstractionAssignment", - "title": "AdditionAssignmentToSubstractionAssignment", + "const" : "AdditionAssignmentNegation", + "title": "AdditionAssignmentNegation", "description": "Replace ```a += b``` with ```a -= b```." }, { - "const" : "AssignmentOperator_SubstractionAssignment_ToAdditionAssignment", - "title": "SubstractionAssignmentToAdditionAssignment", + "const" : "SubtractionAssignmentNegation", + "title": "SubtractionAssignmentNegation", "description": "Replace ```a -= b``` with ```a += b```." }, { - "const" : "AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment", - "title": "MultiplicationAssignmentToDivisionAssignment", + "const" : "MultiplicationAssignmentNegation", + "title": "MultiplicationAssignmentNegation", "description": "Replace ```a *= b``` with ```a /= b```." }, { - "const" : "AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment", - "title": "DivisionAssignmentToMultiplicationAssignment", + "const" : "DivisionAssignmentNegation", + "title": "DivisionAssignmentNegation", "description": "Replace ```a /= b``` with ```a *= b```." }, { - "const" : "AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment", - "title": "RemainderAssignmentToMultiplicationAssignment", + "const" : "RemainderAssignmentToMultiplicationReplacement", + "title": "RemainderAssignmentToMultiplicationReplacement", "description": "Replace ```a %= b``` with ```a *= b```." }, { - "const" : "AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment", - "title": "LeftShiftAssignmentToRightShiftAssignment", + "const" : "LeftShiftAssignmentNegation", + "title": "LeftShiftAssignmentNegation", "description": "Replace ```a <<= b``` with ```a >>= b```." }, { - "const" : "AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment", - "title": "RightShiftAssignmentToLeftShiftAssignment", + "const" : "RightShiftAssignmentNegation", + "title": "RightShiftAssignmentNegation", "description": "Replace ```a >>= b``` with ```a <<= b```." }, { - "const" : "AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment", - "title": "BitwiseAndAssignmentToBitwiseOrAssignment", + "const" : "BitwiseAndAssignmentNegation", + "title": "BitwiseAndAssignmentNegation", "description": "Replace ```a &= b``` with ```a |= b```." }, { - "const" : "AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment", - "title": "BitwiseOrAssignmentToBitwiseAndAssignment", + "const" : "BitwiseOrAssignmentNegation", + "title": "BitwiseOrAssignmentNegation", "description": "Replace ```a |= b``` with ```a &= b```." }, { - "const" : "AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment", - "title": "LogicalAndAssignmentToLogicalOrAssignment", + "const" : "LogicalAndAssignmentNegation", + "title": "LogicalOrAssignmentNegation", "description": "Replace ```a &&= b``` with ```a ||= b```." }, { - "const" : "AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment", - "title": "LogicalOrAssignmentToLogicalAndAssignment", + "const" : "LogicalOrAssignmentNegation", + "title": "LogicalOrAssignmentNegation", "description": "Replace ```a ||= b``` with ```a &&= b```." }, { - "const" : "AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment", + "const" : "NullishCoalescingAssignmentToLogicalAndReplacement", "title": "NullishCoalescingAssignmentToLogicalAndAssignment", "description": "Replace ```a ??= b``` with ```a &&= b```." } ] }, "ArrowFunction": { - "const": "ArrowFunction_Removal", + "const": "ArrowFunctionRemoval", "description": "Mutates bodies of arrow functions to undefined" }, "BlockStatement": { - "const": "BlockStatement_Removal", + "const": "BlockStatementRemoval", "description": "Removes the content of every block statement." }, "BooleanLiteral": { "title": "BooleanLiteral", "anyOf": [ { - "const" : "BooleanLiteral_TrueLiteral_ToFalseLiteral", - "title": "TrueLiteralToFalseLiteral", + "const" : "TrueLiteralNegation", + "title": "TrueLiteralNegation", "description": "Replace ```true``` with ```false```." }, { - "const" : "BooleanLiteral_FalseLiteral_ToTrueLiteral", - "title": "FalseLiteralToTrueLiteral", + "const" : "FalseLiteralNegation", + "title": "FalseLiteralNegation", "description": "Replace ```false``` with ```true```." }, { - "const" : "BooleanLiteral_LogicalNot_Removal", + "const" : "LogicalNotRemoval", "title": "LogicalNotRemoval", "description": "Replace ```!(a == b)``` with ```a == b```." } @@ -451,42 +451,42 @@ "title": "ConditionalExpression", "anyOf": [ { - "const" : "ConditionalExpression_ForLoopCondition_ToFalseLiteral", - "title": "ForLoopConditionToFalseLiteral", + "const" : "ForLoopConditionToFalseReplacement", + "title": "ForLoopConditionToFalseReplacement", "description": "Replace ```for (var i = 0; i < 10; i++) { }``` with ```for (var i = 0; false; i++) { }```." }, { - "const" : "ConditionalExpression_WhileLoopCondition_ToFalseLiteral", - "title": "WhileLoopConditionToFalseLiteral", + "const" : "WhileLoopConditionToFalseReplacement", + "title": "WhileLoopConditionToFalseReplacement", "description": "Replace ```while (a > b) { }``` with ```while (false) { }```." }, { - "const" : "ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral", - "title": "DoWhileLoopConditionToFalseLiteral", + "const" : "DoWhileLoopConditionToFalseReplacement", + "title": "DoWhileLoopConditionToFalseReplacement", "description": "Replace ```do { } while (a > b);``` with ```do { } while (false);```." }, { - "const" : "ConditionalExpression_IfCondition_ToTrueLiteral", - "title": "IfConditionToTrueLiteral", + "const" : "IfConditionToTrueReplacement", + "title": "IfConditionToTrueReplacement", "description": "Replace ```if (a > b) { }``` with ```if (true) { }```." }, { - "const" : "ConditionalExpression_IfCondition_ToFalseLiteral", - "title": "IfConditionToFalseLiteral", + "const" : "IfConditionToFalseReplacement", + "title": "IfConditionToFalseReplacement", "description": "Replace ```if (a > b) { }``` with ```if (false) { }```." }, { - "const" : "ConditionalExpression_BooleanExpression_ToTrueLiteral", - "title": "TernaryConditionToTrueLiteral", + "const" : "BooleanExpressionToTrueReplacement", + "title": "BooleanExpressionToTrueReplacement", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = true ? 1 : 2;```." }, { - "const" : "ConditionalExpression_BooleanExpression_ToFalseLiteral", - "title": "ConditionalExpressionTernaryCondition_ToFalseLiteral", + "const" : "BooleanExpressionToFalseReplacement", + "title": "BooleanExpressionToFalseReplacement", "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = false ? 1 : 2;```." }, { - "const" : "ConditionalExpression_SwitchStatementBody_Removal", + "const" : "SwitchStatementBodyRemoval", "title": "SwitchStatementBodyRemoval", "description": "Replace ```switch(x) with switch()```." } @@ -702,7 +702,7 @@ ] }, "Regex": { - "const": "Regex_Removal" + "const": "RegexRemoval" }, "StringLiteral": { "title": "StringLiteral", diff --git a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts index 19844cc8e4..7f1a2ec860 100644 --- a/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/arithmetic-operator-mutator.ts @@ -10,11 +10,11 @@ export const arithmeticOperatorMutator: NodeMutator = { name: 'ArithmeticOperator', operators: { - '+': { replacement: '-', mutationName: 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator' }, - '-': { replacement: '+', mutationName: 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator' }, - '*': { replacement: '/', mutationName: 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator' }, - '/': { replacement: '*', mutationName: 'ArithmeticOperator_DivisionOperator_ToMultiplicationOperator' }, - '%': { replacement: '*', mutationName: 'ArithmeticOperator_RemainderOperator_ToMultiplicationOperator' }, + '+': { replacement: '-', mutationName: 'AdditionOperatorNegation' }, + '-': { replacement: '+', mutationName: 'SubtractionOperatorNegation' }, + '*': { replacement: '/', mutationName: 'MultiplicationOperatorNegation' }, + '/': { replacement: '*', mutationName: 'DivisionOperatorNegation' }, + '%': { replacement: '*', mutationName: 'RemainderOperatorToMultiplicationReplacement' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/array-declaration-mutator.ts b/packages/instrumenter/src/mutators/array-declaration-mutator.ts index dba4509f6e..5dc09f6376 100644 --- a/packages/instrumenter/src/mutators/array-declaration-mutator.ts +++ b/packages/instrumenter/src/mutators/array-declaration-mutator.ts @@ -12,19 +12,19 @@ export const arrayDeclarationMutator: NodeMutator = { name: 'ArrayDeclaration', operators: { - FilledArray: { + ArrayLiteralItemsFill: { replacement: types.arrayExpression([types.stringLiteral('Stryker was here')]), - mutationName: 'ArrayDeclaration_ArrayLiteral_Fill', + mutationName: 'ArrayLiteralItemsFill', }, - FilledArrayConstructor: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'ArrayDeclaration_ArrayConstructor_Fill' }, - EmptyArray: { replacement: types.arrayExpression(), mutationName: 'ArrayDeclaration_ArrayLiteral_ItemsRemoval' }, - EmptyArrayConstructor: { replacement: [], mutationName: 'ArrayDeclaration_ArrayConstructor_ItemsRemoval' }, + ArrayConstructorItemsFill: { replacement: [types.stringLiteral('Stryker was here')], mutationName: 'ArrayConstructorItemsFill' }, + ArrayLiteralItemsRemoval: { replacement: types.arrayExpression(), mutationName: 'ArrayLiteralItemsRemoval' }, + ArrayConstructorItemsRemoval: { replacement: [], mutationName: 'ArrayConstructorItemsRemoval' }, }, *mutate(path, levelMutations) { // The check of the [] construct in code if (path.isArrayExpression() && isArrayInLevel(path.node, levelMutations)) { - const replacement = path.node.elements.length > 0 ? this.operators.EmptyArray.replacement : this.operators.FilledArray.replacement; + const replacement = path.node.elements.length > 0 ? this.operators.ArrayLiteralItemsRemoval.replacement : this.operators.ArrayLiteralItemsFill.replacement; yield replacement; } // Check for the new Array() construct in code @@ -35,7 +35,9 @@ export const arrayDeclarationMutator: NodeMutator = { isArrayConstructorInLevel(path.node, levelMutations) ) { const mutatedCallArgs: babel.types.Expression[] = - path.node.arguments.length > 0 ? this.operators.EmptyArrayConstructor.replacement : this.operators.FilledArrayConstructor.replacement; + path.node.arguments.length > 0 + ? this.operators.ArrayConstructorItemsRemoval.replacement + : this.operators.ArrayConstructorItemsFill.replacement; const replacement = types.isNewExpression(path.node) ? types.newExpression(deepCloneNode(path.node.callee), mutatedCallArgs) @@ -52,8 +54,8 @@ function isArrayInLevel(node: babel.types.ArrayExpression, levelMutations: strin } return ( - (levelMutations.includes(arrayDeclarationMutator.operators.EmptyArray.mutationName) && node.elements.length > 0) || - (levelMutations.includes(arrayDeclarationMutator.operators.FilledArray.mutationName) && node.elements.length === 0) + (levelMutations.includes(arrayDeclarationMutator.operators.ArrayLiteralItemsRemoval.mutationName) && node.elements.length > 0) || + (levelMutations.includes(arrayDeclarationMutator.operators.ArrayLiteralItemsFill.mutationName) && node.elements.length === 0) ); } @@ -64,7 +66,7 @@ function isArrayConstructorInLevel(node: babel.types.CallExpression | babel.type } return ( - (levelMutations.includes(arrayDeclarationMutator.operators.EmptyArrayConstructor.mutationName) && node.arguments.length > 0) || - (levelMutations.includes(arrayDeclarationMutator.operators.FilledArrayConstructor.mutationName) && node.arguments.length === 0) + (levelMutations.includes(arrayDeclarationMutator.operators.ArrayConstructorItemsRemoval.mutationName) && node.arguments.length > 0) || + (levelMutations.includes(arrayDeclarationMutator.operators.ArrayConstructorItemsFill.mutationName) && node.arguments.length === 0) ); } diff --git a/packages/instrumenter/src/mutators/arrow-function-mutator.ts b/packages/instrumenter/src/mutators/arrow-function-mutator.ts index 52eec1b29b..fcc0453059 100644 --- a/packages/instrumenter/src/mutators/arrow-function-mutator.ts +++ b/packages/instrumenter/src/mutators/arrow-function-mutator.ts @@ -10,7 +10,7 @@ export const arrowFunctionMutator: NodeMutator = { name: 'ArrowFunction', operators: { - ArrowFunction: { mutationName: 'ArrowFunction_Removal' }, + ArrowFunction: { mutationName: 'ArrowFunctionRemoval' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts index dd5c829e69..9c6b5e4a26 100644 --- a/packages/instrumenter/src/mutators/assignment-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/assignment-operator-mutator.ts @@ -13,18 +13,18 @@ export const assignmentOperatorMutator: NodeMutator = { name: 'AssignmentOperator', operators: { - '+=': { replacement: '-=', mutationName: 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment' }, - '-=': { replacement: '+=', mutationName: 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment' }, - '*=': { replacement: '/=', mutationName: 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment' }, - '/=': { replacement: '*=', mutationName: 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment' }, - '%=': { replacement: '*=', mutationName: 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment' }, - '<<=': { replacement: '>>=', mutationName: 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment' }, - '>>=': { replacement: '<<=', mutationName: 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment' }, - '&=': { replacement: '|=', mutationName: 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment' }, - '|=': { replacement: '&=', mutationName: 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment' }, - '&&=': { replacement: '||=', mutationName: 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment' }, - '||=': { replacement: '&&=', mutationName: 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment' }, - '??=': { replacement: '&&=', mutationName: 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment' }, + '+=': { replacement: '-=', mutationName: 'AdditionAssignmentNegation' }, + '-=': { replacement: '+=', mutationName: 'SubtractionAssignmentNegation' }, + '*=': { replacement: '/=', mutationName: 'MultiplicationAssignmentNegation' }, + '/=': { replacement: '*=', mutationName: 'DivisionAssignmentNegation' }, + '%=': { replacement: '*=', mutationName: 'RemainderAssignmentToMultiplicationReplacement' }, + '<<=': { replacement: '>>=', mutationName: 'LeftShiftAssignmentNegation' }, + '>>=': { replacement: '<<=', mutationName: 'RightShiftAssignmentNegation' }, + '&=': { replacement: '|=', mutationName: 'BitwiseAndAssignmentNegation' }, + '|=': { replacement: '&=', mutationName: 'BitwiseOrAssignmentNegation' }, + '&&=': { replacement: '||=', mutationName: 'LogicalAndAssignmentNegation' }, + '||=': { replacement: '&&=', mutationName: 'LogicalOrAssignmentNegation' }, + '??=': { replacement: '&&=', mutationName: 'NullishCoalescingAssignmentToLogicalAndReplacement' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/block-statement-mutator.ts b/packages/instrumenter/src/mutators/block-statement-mutator.ts index 2ecd4b75a9..9290046664 100644 --- a/packages/instrumenter/src/mutators/block-statement-mutator.ts +++ b/packages/instrumenter/src/mutators/block-statement-mutator.ts @@ -10,7 +10,7 @@ export const blockStatementMutator: NodeMutator = { name: 'BlockStatement', operators: { - BlockStatement: { mutationName: 'BlockStatement_Removal' }, + BlockStatement: { mutationName: 'BlockStatementRemoval' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/boolean-literal-mutator.ts b/packages/instrumenter/src/mutators/boolean-literal-mutator.ts index e0e0fa348a..41c21e7a21 100644 --- a/packages/instrumenter/src/mutators/boolean-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/boolean-literal-mutator.ts @@ -12,9 +12,9 @@ export const booleanLiteralMutator: NodeMutator = { name: 'BooleanLiteral', operators: { - true: { replacement: false, mutationName: 'BooleanLiteral_TrueLiteral_ToFalseLiteral' }, - false: { replacement: true, mutationName: 'BooleanLiteral_FalseLiteral_ToTrueLiteral' }, - '!': { replacement: '', mutationName: 'BooleanLiteral_LogicalNot_Removal' }, + true: { replacement: false, mutationName: 'TrueLiteralNegation' }, + false: { replacement: true, mutationName: 'FalseLiteralNegation' }, + '!': { replacement: '', mutationName: 'LogicalNotRemoval' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts index 4df585597d..486a16a39c 100644 --- a/packages/instrumenter/src/mutators/conditional-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/conditional-expression-mutator.ts @@ -14,14 +14,14 @@ export const conditionalExpressionMutator: NodeMutator = name: 'ConditionalExpression', operators: { - BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_BooleanExpression_ToFalseLiteral' }, - BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_BooleanExpression_ToTrueLiteral' }, - DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral' }, - ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_ForLoopCondition_ToFalseLiteral' }, - IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_IfCondition_ToFalseLiteral' }, - IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'ConditionalExpression_IfCondition_ToTrueLiteral' }, - WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral' }, - SwitchToEmpty: { replacement: [], mutationName: 'ConditionalExpression_SwitchStatementBody_Removal' }, + BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'BooleanExpressionToFalseReplacement' }, + BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'BooleanExpressionToTrueReplacement' }, + DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'DoWhileLoopConditionToFalseReplacement' }, + ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ForLoopConditionToFalseReplacement' }, + IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'IfConditionToFalseReplacement' }, + IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'IfConditionToTrueReplacement' }, + WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'WhileLoopConditionToFalseReplacement' }, + SwitchBodyRemoval: { replacement: [], mutationName: 'SwitchStatementBodyRemoval' }, }, *mutate(path, levelMutations) { @@ -78,9 +78,9 @@ export const conditionalExpressionMutator: NodeMutator = } } else if (path.isSwitchCase() && path.node.consequent.length > 0) { // if not a fallthrough case - if (levelMutations === undefined || levelMutations.includes(this.operators.SwitchToEmpty.mutationName)) { + if (levelMutations === undefined || levelMutations.includes(this.operators.SwitchBodyRemoval.mutationName)) { const replacement = deepCloneNode(path.node); - replacement.consequent = this.operators.SwitchToEmpty.replacement; + replacement.consequent = this.operators.SwitchBodyRemoval.replacement; yield replacement; } } diff --git a/packages/instrumenter/src/mutators/regex-mutator.ts b/packages/instrumenter/src/mutators/regex-mutator.ts index 7a42cf7582..3325cdd878 100644 --- a/packages/instrumenter/src/mutators/regex-mutator.ts +++ b/packages/instrumenter/src/mutators/regex-mutator.ts @@ -35,7 +35,7 @@ export const regexMutator: NodeMutator = { name: 'Regex', operators: { - Regex: { mutationName: 'Regex_Removal' }, + Regex: { mutationName: 'RegexRemoval' }, }, *mutate(path, options) { diff --git a/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts index 7f440023cb..b92ad996f4 100644 --- a/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/arithmatic-operator-mutator.spec.ts @@ -6,11 +6,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const arithmeticLevel: MutationLevel = { name: 'ArithemticLevel', - ArithmeticOperator: [ - 'ArithmeticOperator_AdditionOperator_ToSubtractionOperator', - 'ArithmeticOperator_SubtractionOperator_ToAdditionOperator', - 'ArithmeticOperator_MultiplicationOperator_ToDivisionOperator', - ], + ArithmeticOperator: ['AdditionOperatorNegation', 'SubtractionOperatorNegation', 'MultiplicationOperatorNegation'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts index e0f4b5114d..2c6f266308 100644 --- a/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/array-declaration-mutator.spec.ts @@ -6,12 +6,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const arrayDeclarationLevel: MutationLevel = { name: 'ArrayDeclarationLevel', - ArrayDeclaration: [ - 'ArrayDeclaration_ArrayLiteral_Fill', - 'ArrayDeclaration_ArrayConstructor_Fill', - 'ArrayDeclaration_ArrayLiteral_ItemsRemoval', - 'ArrayDeclaration_ArrayConstructor_ItemsRemoval', - ], + ArrayDeclaration: ['ArrayLiteralItemsFill', 'ArrayConstructorItemsRemoval', 'ArrayLiteralItemsRemoval', 'ArrayConstructorItemsFill'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts index c54b991bd2..6b58ae91f8 100644 --- a/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/arrow-function-mutator.spec.ts @@ -4,7 +4,7 @@ import { arrowFunctionMutator as sut } from '../../../src/mutators/arrow-functio import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const arrowFunctionLevel: MutationLevel = { name: 'ArrowFunctionLevel', ArrowFunction: ['ArrowFunction_Removal'] }; +const arrowFunctionLevel: MutationLevel = { name: 'ArrowFunctionLevel', ArrowFunction: ['ArrowFunctionRemoval'] }; const arrowFunctionUndefinedLevel: MutationLevel = { name: 'ArrowFunctionLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts index 1075ea1e41..010ccb9a67 100644 --- a/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/assignment-operator-mutator.spec.ts @@ -6,27 +6,23 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const assignmentOperatorLevel: MutationLevel = { name: 'AssignmentOperatorLevel', - AssignmentOperator: [ - 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment', - 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment', - 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment', - ], + AssignmentOperator: ['SubtractionAssignmentNegation', 'LeftShiftAssignmentNegation', 'LogicalAndAssignmentNegation'], }; const assignmentOperatorAllLevel: MutationLevel = { name: 'AssignmentOperatorLevel', AssignmentOperator: [ - 'AssignmentOperator_AdditionAssignment_ToSubstractionAssignment', - 'AssignmentOperator_SubstractionAssignment_ToAdditionAssignment', - 'AssignmentOperator_MultiplicationAssignment_ToDivisionAssignment', - 'AssignmentOperator_DivisionAssignment_ToMultiplicationAssignment', - 'AssignmentOperator_RemainderAssignment_ToMultiplicationAssignment', - 'AssignmentOperator_LeftShiftAssignment_ToRightShiftAssignment', - 'AssignmentOperator_RightShiftAssignment_ToLeftShiftAssignment', - 'AssignmentOperator_BitwiseAndAssignment_ToBitwiseOrAssignment', - 'AssignmentOperator_BitwiseOrAssignment_ToBitwiseAndAssignment', - 'AssignmentOperator_LogicalAndAssignment_ToLogicalOrAssignment', - 'AssignmentOperator_LogicalOrAssignment_ToLogicalAndAssignment', - 'AssignmentOperator_NullishCoalescingAssignment_ToLogicalAndAssignment', + 'AdditionAssignmentNegation', + 'SubtractionAssignmentNegation', + 'MultiplicationAssignmentNegation', + 'DivisionAssignmentNegation', + 'RemainderAssignmentToMultiplicationReplacement', + 'LeftShiftAssignmentNegation', + 'RightShiftAssignmentNegation', + 'BitwiseAndAssignmentNegation', + 'BitwiseOrAssignmentNegation', + 'LogicalAndAssignmentNegation', + 'LogicalOrAssignmentNegation', + 'NullishCoalescingAssignmentToLogicalAndReplacement', ], }; const assignmentOperatorUndefinedLevel: MutationLevel = { name: 'AssignmentOperatorLevel' }; diff --git a/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts index f46e743f15..f83727b2e6 100644 --- a/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/block-statement-mutator.spec.ts @@ -4,7 +4,7 @@ import { blockStatementMutator as sut } from '../../../src/mutators/block-statem import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const blockStatementLevel: MutationLevel = { name: 'BlockStatementLevel', BlockStatement: ['BlockStatement_Removal'] }; +const blockStatementLevel: MutationLevel = { name: 'BlockStatementLevel', BlockStatement: ['BlockStatementRemoval'] }; const blockStatementUndefinedLevel: MutationLevel = { name: 'BlockStatementLevel' }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts index 274f260aed..e76810657b 100644 --- a/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/boolean-literal-mutator.spec.ts @@ -6,12 +6,12 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const booleanLiteralLevel: MutationLevel = { name: 'BooleanLiteralLevel', - BooleanLiteral: ['BooleanLiteral_TrueLiteral_ToFalseLiteral', 'BooleanLiteral_LogicalNot_Removal'], + BooleanLiteral: ['TrueLiteralNegation', 'LogicalNotRemoval'], }; const booleanLiteralAllLevel: MutationLevel = { name: 'BooleanLiteralLevel', - BooleanLiteral: ['BooleanLiteral_TrueLiteral_ToFalseLiteral', 'BooleanLiteral_FalseLiteral_ToTrueLiteral', 'BooleanLiteral_LogicalNot_Removal'], + BooleanLiteral: ['TrueLiteralNegation', 'FalseLiteralNegation', 'LogicalNotRemoval'], }; const booleanLiteralUndefinedLevel: MutationLevel = { diff --git a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts index 9dac99d5f9..349d6114ad 100644 --- a/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/conditional-expression-mutator.spec.ts @@ -7,20 +7,20 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const conditionalLevel: MutationLevel = { name: 'ConditionalLevel', ConditionalExpression: [ - 'ConditionalExpression_ForLoopCondition_ToFalseLiteral', - 'ConditionalExpression_IfCondition_ToFalseLiteral', - 'ConditionalExpression_IfCondition_ToTrueLiteral', - 'ConditionalExpression_SwitchStatementBody_Removal', + 'ForLoopConditionToFalseReplacement', + 'IfConditionToFalseReplacement', + 'IfConditionToTrueReplacement', + 'SwitchStatementBodyRemoval', ], }; const conditionalLevel2: MutationLevel = { name: 'ConditionalLevel2', ConditionalExpression: [ - 'ConditionalExpression_WhileLoopCondition_ToFalseLiteral', - 'ConditionalExpression_BooleanExpression_ToFalseLiteral', - 'ConditionalExpression_DoWhileLoopCondition_ToFalseLiteral', - 'ConditionalExpression_BooleanExpression_ToTrueLiteral', + 'WhileLoopConditionToFalseReplacement', + 'BooleanExpressionToFalseReplacement', + 'DoWhileLoopConditionToFalseReplacement', + 'BooleanExpressionToTrueReplacement', ], }; diff --git a/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts index 0b8b9c5432..b035bf9f47 100644 --- a/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/regex-mutator.spec.ts @@ -5,7 +5,7 @@ import { regexMutator as sut } from '../../../src/mutators/regex-mutator.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_Removal'] }; +const regexLevel: MutationLevel = { name: 'RegexLevel', Regex: ['RegexRemoval'] }; const regexUndefinedLevel: MutationLevel = { name: 'RegexLevel' }; describe(sut.name, () => { From db78fe2b665a036a01cdbecf6ae2fab2bedbfb45 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 17:34:24 +0100 Subject: [PATCH 09/13] Fix arithmetic through object-literal operators, stable --- packages/api/schema/stryker-core.json | 138 +++++++++--------- .../src/mutators/equality-operator-mutator.ts | 24 +-- .../src/mutators/logical-operator-mutator.ts | 6 +- .../src/mutators/method-expression-mutator.ts | 46 +++--- .../src/mutators/object-literal-mutator.ts | 2 +- .../equality-operator-mutator.spec.ts | 16 +- .../mutators/logical-operator-mutator.spec.ts | 2 +- .../method-expression-mutator.spec.ts | 7 +- .../mutators/object-literal-mutator.spec.ts | 2 +- 9 files changed, 115 insertions(+), 128 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index 7dcf67c3f5..c07d979276 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -220,6 +220,7 @@ }, "includedMutations": { "type": "array", + "uniqueItems": true, "default": [], "items": { "$ref": "#/definitions/MutatorDefinition" @@ -227,6 +228,7 @@ }, "excludedMutations": { "type": "array", + "uniqueItems": true, "default": [], "items": { "$ref": "#/definitions/MutatorDefinition" @@ -496,62 +498,62 @@ "title": "EqualityOperator", "anyOf": [ { - "const" : "EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator", - "title": "StrictInequalityOperatorToStrictEqualityOperator", + "const" : "StrictInequalityOperatorNegation", + "title": "StrictInequalityOperatorNegation", "description": "Replace ```a !== b``` with ```a === b```." }, { - "const" : "EqualityOperator_InequalityOperator_ToEqualityOperator", - "title": "InequalityOperatorToEqualityOperator", + "const" : "InequalityOperatorNegation", + "title": "InequalityOperatorNegation", "description": "Replace ```a != b``` with ```a == b```." }, { - "const" : "EqualityOperator_LessThanEqualOperator_Boundary", + "const" : "LessThanEqualOperatorBoundary", "title": "LessThanEqualOperatorBoundary", "description": "Replace ```a <= b``` with ```a < b```." }, { - "const" : "EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator", - "title": "LessThanEqualOperatorToGreatherThanOperator", + "const" : "LessThanEqualOperatorNegation", + "title": "LessThanEqualOperatorNegation", "description": "Replace ```a <= b``` with ```a > b```." }, { - "const" : "EqualityOperator_LessThanOperator_Boundary", + "const" : "LessThanOperatorBoundary", "title": "LessThanOperatorBoundary", "description": "Replace ```a < b``` with ```a <= b```." }, { - "const" : "EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator", - "title": "LessThanOperatorToGreatherThanEqualOperator", + "const" : "LessThanOperatorNegation", + "title": "LessThanOperatorNegation", "description": "Replace ```a < b``` with ```a >= b```." }, { - "const" : "EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator", - "title": "StrictEqualityOperatorToStrictInequalityOperator", + "const" : "StrictEqualityOperatorNegation", + "title": "StrictEqualityOperatorNegation", "description": "Replace ```a === b``` with ```a !== b```." }, { - "const" : "EqualityOperator_EqualityOperator_ToInequalityOperator", - "title": "EqualityOperatorToInequalityOperator", + "const" : "EqualityOperatorNegation", + "title": "EqualityOperatorNegation", "description": "Replace ```a == b``` with ```a != b```." }, { - "const" : "EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator", - "title": "GreatherThanEqualOperatorToLessThanOperator", + "const" : "GreaterThanEqualOperatorNegation", + "title": "GreaterThanEqualOperatorNegation", "description": "Replace ```a >= b``` with ```a < b```." }, { - "const" : "EqualityOperator_GreatherThanEqualOperator_Boundary", - "title": "GreatherThanEqualOperatorBoundary", + "const" : "GreaterThanEqualOperatorBoundary", + "title": "GreaterThanEqualOperatorBoundary", "description": "Replace ```a >= b``` with ```a > b```." }, { - "const" : "EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator", - "title": "GreaterThanOperatorToLessThanEqualOperator", + "const" : "GreaterThanOperatorNegation", + "title": "GreaterThanOperatorNegation", "description": "Replace ```a > b``` with ```a <= b```." }, { - "const" : "EqualityOperator_GreaterThanOperator_Boundary", + "const" : "GreaterThanOperatorBoundary", "title": "GreaterThanOperatorBoundary", "description": "Replace ```a > b``` with ```a >= b```." } @@ -561,18 +563,18 @@ "title": "LogicalOperator", "anyOf": [ { - "const" : "LogicalOperator_LogicalAndOperator_ToLogicalOrOperator", - "title": "LogicalAndOperatorToLogicalOrOperator", + "const" : "LogicalAndOperatorNegation", + "title": "LogicalAndOperatorNegation", "description": "Replace ```a && b``` with ```a || b```." }, { - "const" : "LogicalOperator_LogicalOrOperator_ToLogicalAndOperator", - "title": "LogicalOrOperatorToLogicalAndOperator", + "const" : "LogicalOrOperatorNegation", + "title": "LogicalOrOperatorNegation", "description": "Replace ```a || b``` with ```a && b```." }, { - "const" : "LogicalOperator_NullishCoalescingOperator_ToLogicalAnd", - "title": "NullishCoalescingOperatorToLogicalAnd", + "const" : "NullishCoalescingOperatorToLogicalAndReplacement", + "title": "NullishCoalescingOperatorToLogicalAndReplacement", "description": "Replace ```a ?? b``` with ```a && b```." } ] @@ -581,109 +583,109 @@ "title": "MethodExpression", "anyOf": [ { - "const": "MethodExpression_charAtMethodCall_Removal", - "title": "charAtMethodCallRemoval", + "const": "CharAtMethodCallRemoval", + "title": "CharAtMethodCallRemoval", "description": "Remove ```charAt()``` call." }, { - "const": "MethodExpression_endsWithMethodCall_TostartsWithMethodCall", - "title": "endsWithMethodCallTostartsWithMethodCall", + "const": "EndsWithMethodCallNegation", + "title": "EndsWithMethodCallNegation", "description": "Replace ```endsWith()``` with ```startsWith()```." }, { - "const": "MethodExpression_startsWithMethodCall_ToendsWithMethodCall", - "title": "startsWithMethodCallToendsWithMethodCall", + "const": "StartsWithMethodCallNegation", + "title": "StartsWithMethodCallNegation", "description": "Replace ```startsWith()``` with ```endsWith()```." }, { - "const": "MethodExpression_everyMethodCall_TosomeMethodCall", - "title": "everyMethodCallTosomeMethodCall", + "const": "EveryMethodCallNegation", + "title": "EveryMethodCallNegation", "description": "Replace ```every()``` with ```some()```." }, { - "const": "MethodExpression_someMethodCall_ToeveryMethodCall", - "title": "someMethodCallToeveryMethodCall", + "const": "SomeMethodCallNegation", + "title": "SomeMethodCallNegation", "description": "Replace ```some()``` with ```every()```." }, { - "const": "MethodExpression_filterMethodCall_Removal", - "title": "filterMethodCallRemoval", + "const": "FilterMethodCallRemoval", + "title": "FilterMethodCallRemoval", "description": "Remove ```filter()``` call." }, { - "const": "MethodExpression_reverseMethodCall_Removal", - "title": "reverseMethodCallRemoval", + "const": "ReverseMethodCallRemoval", + "title": "ReverseMethodCallRemoval", "description": "Remove ```reverse()``` call" }, { - "const": "MethodExpression_sliceMethodCall_Removal", - "title": "sliceMethodCallRemoval", + "const": "SliceMethodCallRemoval", + "title": "SliceMethodCallRemoval", "description": "Remove ```slice()``` call." }, { - "const": "MethodExpression_sortMethodCall_Removal", - "title": "sortMethodCallRemoval", + "const": "SortMethodCallRemoval", + "title": "SortMethodCallRemoval", "description": "Remove ```sort()``` call." }, { - "const": "MethodExpression_substrMethodCall_Removal", - "title": "substrMethodCallRemoval", + "const": "SubstrMethodCallRemoval", + "title": "SubstrMethodCallRemoval", "description": "Remove ```substr()``` call." }, { - "const": "MethodExpression_substringMethodCall_Removal", - "title": "substringMethodCallRemoval", + "const": "SubstringMethodCallRemoval", + "title": "SubstringMethodCallRemoval", "description": "Remove ```substring()``` call." }, { - "const": "MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall", - "title": "toLocaleLowerCaseMethodCallTotoLocaleUpperCaseMethodCall", + "const": "ToLocaleLowerCaseMethodCallNegation", + "title": "ToLocaleLowerCaseMethodCallNegation", "description": "Replace ```toLocaleLowerCase()``` with ```toLocaleUpperCase()```." }, { - "const": "MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall", - "title": "toLocaleUpperCaseMethodCallTotoLocaleLowerCaseMethodCall", + "const": "ToLocaleUpperCaseMethodCallNegation", + "title": "ToLocaleUpperCaseMethodCallNegation", "description": "Replace ```toLocaleUpperCase()``` with ```toLocaleLowerCase()```." }, { - "const": "MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall", - "title": "toLowerCaseMethodCallTotoUpperCaseMethodCall", + "const": "ToLowerCaseMethodCallNegation", + "title": "ToLowerCaseMethodCallNegation", "description": "Replace ```toLowerCase()``` with ```toUpperCase()```." }, { - "const": "MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall", - "title": "toUpperCaseMethodCallTotoLowerCaseMethodCall", + "const": "ToUpperCaseMethodCallNegation", + "title": "ToUpperCaseMethodCallNegation", "description": "Replace ```toUpperCase()``` with ```toLowerCase()```." }, { - "const": "MethodExpression_trimMethodCall_Removal", - "title": "trimMethodCallRemoval", + "const": "TrimMethodCallRemoval", + "title": "TrimMethodCallRemoval", "description": "Remove ```trim()``` call." }, { - "const": "MethodExpression_trimEndMethodCall_TotrimStartMethodCall", - "title": "trimEndMethodCallTotrimStartMethodCall", + "const": "TrimEndMethodCallNegation", + "title": "TrimEndMethodCallNegation", "description": "Replace ```trimEnd()``` with ```trimStart()```." }, { - "const": "MethodExpression_trimStartMethodCall_TotrimEndMutator", - "title": "trimStartMethodCallTotrimEndMutator", + "const": "TrimStartMethodCallNegation", + "title": "TrimStartMethodCallNegation", "description": "Replace ```trimStart()``` with ```trimEnd()```." }, { - "const": "MethodExpression_minMethodCall_TomaxMethodCall", - "title": "minMethodCallTomaxMethodCall", + "const": "MinMethodCallNegation", + "title": "MinMethodCallNegation", "description": "Replace ```min()``` with ```max()```." }, { - "const": "MethodExpression_maxMethodCall_toMinMethodCall", - "title": "maxMethodCalltoMinMethodCall", + "const": "MaxMethodCallNegation", + "title": "MaxMethodCallNegation", "description": "Replace ```max()``` with ```min()```." } ] }, "ObjectLiteral": { - "const": "ObjectLiteral_PropertiesRemoval", + "const": "ObjectLiteralPropertiesRemoval", "description": "Replace ```{ foo: 'bar' }``` with ```{ }```." }, "OptionalChaining": { diff --git a/packages/instrumenter/src/mutators/equality-operator-mutator.ts b/packages/instrumenter/src/mutators/equality-operator-mutator.ts index 84faecab84..a7c0338d7a 100644 --- a/packages/instrumenter/src/mutators/equality-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/equality-operator-mutator.ts @@ -10,22 +10,22 @@ export const equalityOperatorMutator: NodeMutator = { name: 'EqualityOperator', operators: { - '=': { replacement: '>=', mutationName: 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator' }, + '=': { replacement: '>=', mutationName: 'LessThanOperatorNegation' }, - '<=To<': { replacement: '<', mutationName: 'EqualityOperator_LessThanEqualOperator_Boundary' }, - '<=To>': { replacement: '>', mutationName: 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator' }, + '<=To<': { replacement: '<', mutationName: 'LessThanEqualOperatorBoundary' }, + '<=To>': { replacement: '>', mutationName: 'LessThanEqualOperatorNegation' }, - '>To>=': { replacement: '>=', mutationName: 'EqualityOperator_GreaterThanOperator_Boundary' }, - '>To<=': { replacement: '<=', mutationName: 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator' }, + '>To>=': { replacement: '>=', mutationName: 'GreaterThanOperatorBoundary' }, + '>To<=': { replacement: '<=', mutationName: 'GreaterThanOperatorNegation' }, - '>=To>': { replacement: '>', mutationName: 'EqualityOperator_GreatherThanEqualOperator_Boundary' }, - '>=To<': { replacement: '<', mutationName: 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator' }, + '>=To>': { replacement: '>', mutationName: 'GreaterThanEqualOperatorBoundary' }, + '>=To<': { replacement: '<', mutationName: 'GreaterThanEqualOperatorNegation' }, - '==To!=': { replacement: '!=', mutationName: 'EqualityOperator_EqualityOperator_ToInequalityOperator' }, - '!=To==': { replacement: '==', mutationName: 'EqualityOperator_InequalityOperator_ToEqualityOperator' }, - '===To!==': { replacement: '!==', mutationName: 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator' }, - '!==To===': { replacement: '===', mutationName: 'EqualityOperator_StrictInequalityOperator_ToStrictEqualityOperator' }, + '==To!=': { replacement: '!=', mutationName: 'EqualityOperatorNegation' }, + '!=To==': { replacement: '==', mutationName: 'InequalityOperatorNegation' }, + '===To!==': { replacement: '!==', mutationName: 'StrictEqualityOperatorNegation' }, + '!==To===': { replacement: '===', mutationName: 'StrictInequalityOperatorNegation' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/logical-operator-mutator.ts b/packages/instrumenter/src/mutators/logical-operator-mutator.ts index 47a52d4d11..6de4d4c339 100644 --- a/packages/instrumenter/src/mutators/logical-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/logical-operator-mutator.ts @@ -8,9 +8,9 @@ export const logicalOperatorMutator: NodeMutator = { name: 'LogicalOperator', operators: { - '&&': { replacement: '||', mutationName: 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator' }, - '||': { replacement: '&&', mutationName: 'LogicalOperator_LogicalOrOperator_ToLogicalAndOperator' }, - '??': { replacement: '&&', mutationName: 'LogicalOperator_NullishCoalescingOperator_ToLogicalAnd' }, + '&&': { replacement: '||', mutationName: 'LogicalAndOperatorNegation' }, + '||': { replacement: '&&', mutationName: 'LogicalOrOperatorNegation' }, + '??': { replacement: '&&', mutationName: 'NullishCoalescingOperatorToLogicalAndReplacement' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/method-expression-mutator.ts b/packages/instrumenter/src/mutators/method-expression-mutator.ts index e1a00144b7..f04f845e9c 100644 --- a/packages/instrumenter/src/mutators/method-expression-mutator.ts +++ b/packages/instrumenter/src/mutators/method-expression-mutator.ts @@ -12,32 +12,26 @@ export const methodExpressionMutator: NodeMutator = { name: 'MethodExpression', operators: { - charAt: { replacement: null, mutationName: 'MethodExpression_charAtMethodCall_Removal' }, - endsWith: { replacement: 'startsWith', mutationName: 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall' }, - startsWith: { replacement: 'endsWith', mutationName: 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall' }, - every: { replacement: 'some', mutationName: 'MethodExpression_everyMethodCall_TosomeMethodCall' }, - some: { replacement: 'every', mutationName: 'MethodExpression_someMethodCall_ToeveryMethodCall' }, - filter: { replacement: null, mutationName: 'MethodExpression_filterMethodCall_Removal' }, - reverse: { replacement: null, mutationName: 'MethodExpression_reverseMethodCall_Removal' }, - slice: { replacement: null, mutationName: 'MethodExpression_sliceMethodCall_Removal' }, - sort: { replacement: null, mutationName: 'MethodExpression_sortMethodCall_Removal' }, - substr: { replacement: null, mutationName: 'MethodExpression_substrMethodCall_Removal' }, - substring: { replacement: null, mutationName: 'MethodExpression_substringMethodCall_Removal' }, - toLocaleLowerCase: { - replacement: 'toLocaleUpperCase', - mutationName: 'MethodExpression_toLocaleLowerCaseMethodCall_TotoLocaleUpperCaseMethodCall', - }, - toLocaleUpperCase: { - replacement: 'toLocaleLowerCase', - mutationName: 'MethodExpression_toLocaleUpperCaseMethodCall_TotoLocaleLowerCaseMethodCall', - }, - toLowerCase: { replacement: 'toUpperCase', mutationName: 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall' }, - toUpperCase: { replacement: 'toLowerCase', mutationName: 'MethodExpression_toUpperCaseMethodCall_TotoLowerCaseMethodCall' }, - trim: { replacement: null, mutationName: 'MethodExpression_trimMethodCall_Removal' }, - trimEnd: { replacement: 'trimStart', mutationName: 'MethodExpression_trimEndMethodCall_TotrimStartMethodCall' }, - trimStart: { replacement: 'trimEnd', mutationName: 'MethodExpression_trimStartMethodCall_TotrimEndMutator' }, - min: { replacement: 'max', mutationName: 'MethodExpression_minMethodCall_TomaxMethodCall' }, - max: { replacement: 'min', mutationName: 'MethodExpression_maxMethodCall_toMinMethodCall' }, + charAt: { replacement: null, mutationName: 'CharAtMethodCallRemoval' }, + endsWith: { replacement: 'startsWith', mutationName: 'EndsWithMethodCallNegation' }, + startsWith: { replacement: 'endsWith', mutationName: 'StartsWithMethodCallNegation' }, + every: { replacement: 'some', mutationName: 'EveryMethodCallNegation' }, + some: { replacement: 'every', mutationName: 'SomeMethodCallNegation' }, + filter: { replacement: null, mutationName: 'FilterMethodCallRemoval' }, + reverse: { replacement: null, mutationName: 'ReverseMethodCallRemoval' }, + slice: { replacement: null, mutationName: 'SliceMethodCallRemoval' }, + sort: { replacement: null, mutationName: 'SortMethodCallRemoval' }, + substr: { replacement: null, mutationName: 'SubstrMethodCallRemoval' }, + substring: { replacement: null, mutationName: 'SubstringMethodCallRemoval' }, + toLocaleLowerCase: { replacement: 'toLocaleUpperCase', mutationName: 'ToLocaleLowerCaseMethodCallNegation' }, + toLocaleUpperCase: { replacement: 'toLocaleLowerCase', mutationName: 'ToLocaleUpperCaseMethodCallNegation' }, + toLowerCase: { replacement: 'toUpperCase', mutationName: 'ToLowerCaseMethodCallNegation' }, + toUpperCase: { replacement: 'toLowerCase', mutationName: 'ToUpperCaseMethodCallNegation' }, + trim: { replacement: null, mutationName: 'TrimMethodCallRemoval' }, + trimEnd: { replacement: 'trimStart', mutationName: 'TrimEndMethodCallNegation' }, + trimStart: { replacement: 'trimEnd', mutationName: 'TrimStartMethodCallNegation' }, + min: { replacement: 'max', mutationName: 'MinMethodCallNegation' }, + max: { replacement: 'min', mutationName: 'MaxMethodCallNegation' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/object-literal-mutator.ts b/packages/instrumenter/src/mutators/object-literal-mutator.ts index 1114a37f48..1155cfb676 100644 --- a/packages/instrumenter/src/mutators/object-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/object-literal-mutator.ts @@ -10,7 +10,7 @@ export const objectLiteralMutator: NodeMutator = { name: 'ObjectLiteral', operators: { - ObjectLiteral: { mutationName: 'ObjectLiteral_PropertiesRemoval' }, + ObjectLiteral: { mutationName: 'ObjectLiteralPropertiesRemoval' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts index 97b15581e2..efe7bfcb73 100644 --- a/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/equality-operator-mutator.spec.ts @@ -7,21 +7,17 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const equalityLevelA: MutationLevel = { name: 'EqualityLevelA', EqualityOperator: [ - 'EqualityOperator_LessThanOperator_Boundary', - 'EqualityOperator_LessThanOperator_ToGreatherThanEqualOperator', - 'EqualityOperator_GreatherThanEqualOperator_Boundary', - 'EqualityOperator_GreatherThanEqualOperator_ToLessThanOperator', - 'EqualityOperator_EqualityOperator_ToInequalityOperator', + 'LessThanOperatorBoundary', + 'LessThanOperatorNegation', + 'GreaterThanEqualOperatorBoundary', + 'GreaterThanEqualOperatorNegation', + 'EqualityOperatorNegation', ], }; const equalityLevelB: MutationLevel = { name: 'EqualityLevelB', - EqualityOperator: [ - 'EqualityOperator_LessThanEqualOperator_ToGreatherThanOperator', - 'EqualityOperator_GreaterThanOperator_ToLessThanEqualOperator', - 'EqualityOperator_StrictEqualityOperator_ToStrictInequalityOperator', - ], + EqualityOperator: ['LessThanEqualOperatorNegation', 'GreaterThanOperatorNegation', 'StrictEqualityOperatorNegation'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts index 88c3b0456b..acf7279b3d 100644 --- a/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/logical-operator-mutator.spec.ts @@ -6,7 +6,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const logicalOpLevel: MutationLevel = { name: 'EqualityLevelB', - LogicalOperator: ['LogicalOperator_LogicalOrOperator_ToLogicalAndOperator', 'LogicalOperator_LogicalAndOperator_ToLogicalOrOperator'], + LogicalOperator: ['LogicalOrOperatorNegation', 'LogicalAndOperatorNegation'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts index 1570a7beb1..d6b8cf83a0 100644 --- a/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/method-expression-mutator.spec.ts @@ -6,12 +6,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const methodExpressionLevel: MutationLevel = { name: 'methodExpressionLevel', - MethodExpression: [ - 'MethodExpression_endsWithMethodCall_TostartsWithMethodCall', - 'MethodExpression_startsWithMethodCall_ToendsWithMethodCall', - 'MethodExpression_substringMethodCall_Removal', - 'MethodExpression_toLowerCaseMethodCall_TotoUpperCaseMethodCall', - ], + MethodExpression: ['EndsWithMethodCallNegation', 'StartsWithMethodCallNegation', 'SubstringMethodCallRemoval', 'ToLowerCaseMethodCallNegation'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts index e9bbf1a8f0..d727ffc9c8 100644 --- a/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/object-literal-mutator.spec.ts @@ -4,7 +4,7 @@ import { objectLiteralMutator as sut } from '../../../src/mutators/object-litera import { expectJSMutation, expectJSMutationWithLevel } from '../../helpers/expect-mutation.js'; import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; -const objectLiteralLevel: MutationLevel = { name: 'ObjectLiteralLevel', ObjectLiteral: ['ObjectLiteral_PropertiesRemoval'] }; +const objectLiteralLevel: MutationLevel = { name: 'ObjectLiteralLevel', ObjectLiteral: ['ObjectLiteralPropertiesRemoval'] }; const objectLiteralUndefinedLevel: MutationLevel = { name: 'ObjectLiteralLevel' }; describe(sut.name, () => { From f2526898fbe8db7a259c728b94fdc4ac026ad7ea Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 17:46:40 +0100 Subject: [PATCH 10/13] Fix up optional-chaining --- packages/api/schema/stryker-core.json | 13 +++++++++---- .../src/mutators/optional-chaining-mutator.ts | 9 ++++++--- .../unit/mutators/optional-chaining-mutator.spec.ts | 3 +-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index c07d979276..ddf36c45a6 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -692,13 +692,18 @@ "title": "OptionalChaining", "anyOf": [ { - "const": "OptionalChaining_OptionalMemberExpression_OptionRemoval", - "title": "OptionalMemberExpressionOptionRemoval", + "const": "OptionalMemberExpressionOptionalRemoval", + "title": "OptionalMemberExpressionOptionalRemoval", "description": "Replace ```foo?.bar``` with ```foo.bar```." }, { - "const": "OptionalChaining_OptionalCallExpression_OptionRemoval", - "title": "OptionalCallExpressionOptionRemoval", + "const": "OptionalComputedMemberExpressionOptionalRemoval", + "title": "OptionalComputedMemberExpressionOptionalRemoval", + "description": "Replace ```foo?.[1]``` with ```foo[1]```." + }, + { + "const": "OptionalCallExpressionOptionalRemoval", + "title": "OptionalCallExpressionOptionalRemoval", "description": "Replace ```foo?.()``` with ```foo()```." } ] diff --git a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts index b764e760ab..0481b2700e 100644 --- a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts +++ b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts @@ -23,15 +23,18 @@ export const optionalChainingMutator: NodeMutator = { name: 'OptionalChaining', operators: { - OptionalCallExpression: { mutationName: 'OptionalChaining_OptionalCallExpression_OptionRemoval' }, - OptionalMemberExpression: { mutationName: 'OptionalChaining_OptionalMemberExpression_OptionRemoval' }, + OptionalCallExpression: { mutationName: 'OptionalCallExpressionOptionalRemoval' }, + OptionalMemberExpression: { mutationName: 'OptionalMemberExpressionOptionalRemoval' }, + OptionalComputedMemberExpression: { mutationName: 'OptionalComputedMemberExpressionOptionalRemoval' }, }, *mutate(path, levelMutations) { if ( path.isOptionalMemberExpression() && path.node.optional && - (levelMutations === undefined || levelMutations.includes(this.operators.OptionalMemberExpression.mutationName)) + (levelMutations === undefined || + (!path.node.computed && levelMutations.includes(this.operators.OptionalMemberExpression.mutationName)) || + (path.node.computed && levelMutations.includes(this.operators.OptionalComputedMemberExpression.mutationName))) ) { yield t.optionalMemberExpression( t.cloneNode(path.node.object, true), diff --git a/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts index abbee3bd0f..9e887c5609 100644 --- a/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/optional-chaining-mutator.spec.ts @@ -7,7 +7,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const optionalChainingLevel: MutationLevel = { name: 'OptionalChainingLevel', - OptionalChaining: ['OptionalChaining_OptionalMemberExpression_OptionRemoval'], + OptionalChaining: ['OptionalMemberExpressionOptionalRemoval'], }; describe(sut.name, () => { @@ -43,7 +43,6 @@ describe(sut.name, () => { optionalChainingLevel.OptionalChaining, 'foo?.bar; foo?.[0]; foo?.()', 'foo.bar; foo?.[0]; foo?.()', // removes .bar optional - 'foo?.bar; foo[0]; foo?.()', // removes [0] optional ); }); it('should block all mutators', () => { From a02c87dd3a496e5d3ceb90478401ca2692838a24 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 18:06:37 +0100 Subject: [PATCH 11/13] Finish renaming mutators --- packages/api/schema/stryker-core.json | 46 +++++++++---------- .../src/mutators/string-literal-mutator.ts | 8 ++-- .../src/mutators/unary-operator-mutator.ts | 6 +-- .../src/mutators/update-operator-mutator.ts | 30 +++++------- .../mutators/string-literal-mutator.spec.ts | 2 +- .../mutators/unary-operator-mutator.spec.ts | 4 +- .../mutators/update-operator-mutator.spec.ts | 10 +--- 7 files changed, 47 insertions(+), 59 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index ddf36c45a6..e9606ccf69 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -715,23 +715,23 @@ "title": "StringLiteral", "anyOf": [ { - "const": "StringLiteral_FilledStringLiteral_ToEmptyStringLiteral", - "title": "FilledStringLiteralToEmptyStringLiteral", + "const": "FilledStringLiteralToEmptyReplacement", + "title": "FilledStringLiteralToEmptyReplacement", "description": "Replace ```\"foo\"``` with ```\"\"```." }, { - "const": "StringLiteral_EmptyStringLiteral_ToFilledStringLiteral", - "title": "EmptyStringLiteralToFilledStringLiteral", + "const": "EmptyStringLiteralToFilledReplacement", + "title": "EmptyStringLiteralToFilledReplacement", "description": "Replace ```\"\"``` with ```\"Stryker was here!\"```." }, { - "const": "StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString", - "title": "FilledInterpolatedStringToEmptyInterpolatedString", + "const": "FilledInterpolatedStringToEmptyReplacement", + "title": "FilledInterpolatedStringToEmptyReplacement", "description": "Replace ```s\"foo ${bar}\"``` with ```s\"\"```." }, { - "const": "StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString", - "title": "EmptyInterpolatedStringToFilledInterpolatedString", + "const": "EmptdInterpolatedStringToFilledReplacement", + "title": "EmptdInterpolatedStringToFilledReplacement", "description": "Replace ```s\"\"``` with ```s\"Stryker was here!\"```." } ] @@ -740,19 +740,19 @@ "title": "UnaryOperator", "anyOf": [ { - "const": "UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator", - "title": "UnaryPlusOperatorToUnaryMinusOperator", + "const": "UnaryPlusOperatorNegation", + "title": "UnaryPlusOperatorNegation", "description": "Replace ```+a``` with ```-a```." }, { - "const": "UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator", - "title": "UnaryMinusOperatorToUnaryPlusOperator", + "const": "UnaryMinOperatorNegation", + "title": "UnaryMinOperatorNegation", "description": "Replace ```-a``` with ```+a.```" }, { - "const": "UnaryOperator_BitwiseOrOperator_Removal", - "title": "BitwiseOrOperatorRemoval", - "description": "" + "const": "UnaryBitwiseOrRemoval", + "title": "UnaryBitwiseOrRemoval", + "description": "Remove ```~``` from ```~a```." } ] }, @@ -760,23 +760,23 @@ "title": "UpdateOperator", "anyOf": [ { - "const": "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator", - "title": "PostfixIncrementOperatorToPostfixDecrementOperator", + "const": "PostfixIncrementOperatorNegation", + "title": "PostfixIncrementOperatorNegation", "description": "Replace ```a++``` with ```a--```." }, { - "const": "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", - "title": "PostfixDecrementOperatorToPostfixIncrementOperator", + "const": "PostfixDecrementOperatorNegation", + "title": "PostfixDecrementOperatorNegation", "description": "Replace ```a--``` with ```a++```." }, { - "const": "UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator", - "title": "PrefixIncrementOperatorToPrefixDecrementOperator", + "const": "PrefixIncrementOperatorNegation", + "title": "PrefixIncrementOperatorNegation", "description": "Replace ```++a``` with ```--a```." }, { - "const": "UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator", - "title": "PrefixDecrementOperatorToPrefixIncrementOperator", + "const": "PrefixDecrementOperatorNegation", + "title": "PrefixDecrementOperatorNegation", "description": "Replace ```--a``` with ```++a```." } ] diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index aec028af22..996c9c596d 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -10,15 +10,15 @@ export const stringLiteralMutator: NodeMutator = { name: 'StringLiteral', operators: { - FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'StringLiteral_EmptyStringLiteral_ToFilledStringLiteral' }, - EmptyString: { replacement: types.stringLiteral(''), mutationName: 'StringLiteral_FilledStringLiteral_ToEmptyStringLiteral' }, + FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'EmptyStringLiteralToFilledReplacement' }, + EmptyString: { replacement: types.stringLiteral(''), mutationName: 'FilledStringLiteralToEmptyReplacement' }, EmptyInterpolation: { replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), - mutationName: 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString', + mutationName: 'FilledInterpolatedStringToEmptyReplacement', }, FillInterpolation: { replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), - mutationName: 'StringLiteral_EmptyInterpolatedString_ToFilledInterpolatedString', + mutationName: 'EmptdInterpolatedStringToFilledReplacement', }, }, diff --git a/packages/instrumenter/src/mutators/unary-operator-mutator.ts b/packages/instrumenter/src/mutators/unary-operator-mutator.ts index 498325072f..7ddb553264 100644 --- a/packages/instrumenter/src/mutators/unary-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/unary-operator-mutator.ts @@ -12,9 +12,9 @@ export const unaryOperatorMutator: NodeMutator = { name: 'UnaryOperator', operators: { - '+': { replacement: '-', mutationName: 'UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator' }, - '-': { replacement: '+', mutationName: 'UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator' }, - '~': { replacement: '', mutationName: 'UnaryOperator_BitwiseOrOperator_Removal' }, + '+': { replacement: '-', mutationName: 'UnaryPlusOperatorNegation' }, + '-': { replacement: '+', mutationName: 'UnaryMinOperatorNegation' }, + '~': { replacement: '', mutationName: 'UnaryBitwiseOrRemoval' }, }, *mutate(path, levelMutations) { diff --git a/packages/instrumenter/src/mutators/update-operator-mutator.ts b/packages/instrumenter/src/mutators/update-operator-mutator.ts index 2ca1e8320b..269646ad88 100644 --- a/packages/instrumenter/src/mutators/update-operator-mutator.ts +++ b/packages/instrumenter/src/mutators/update-operator-mutator.ts @@ -12,21 +12,21 @@ export const updateOperatorMutator: NodeMutator = { name: 'UpdateOperator', operators: { - UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator: { + PostfixIncrementOperatorNegation: { replacement: '--', - mutationName: 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', + mutationName: 'PostfixIncrementOperatorNegation', }, - UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator: { + PostfixDecrementOperatorNegation: { replacement: '++', - mutationName: 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', + mutationName: 'PostfixDecrementOperatorNegation', }, - UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator: { + PrefixIncrementOperatorNegation: { replacement: '--', - mutationName: 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', + mutationName: 'PrefixIncrementOperatorNegation', }, - UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator: { + PrefixDecrementOperatorNegation: { replacement: '++', - mutationName: 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', + mutationName: 'PrefixDecrementOperatorNegation', }, }, @@ -38,19 +38,13 @@ export const updateOperatorMutator: NodeMutator = { } else { let replacement = undefined; if (path.node.prefix && path.node.operator == '++') { - replacement = getReplacement(levelMutations, this.operators.UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator.mutationName); + replacement = getReplacement(levelMutations, this.operators.PrefixIncrementOperatorNegation.mutationName); } else if (path.node.prefix && path.node.operator == '--') { - replacement = getReplacement(levelMutations, this.operators.UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator.mutationName); + replacement = getReplacement(levelMutations, this.operators.PrefixDecrementOperatorNegation.mutationName); } else if (!path.node.prefix && path.node.operator == '++') { - replacement = getReplacement( - levelMutations, - this.operators.UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator.mutationName, - ); + replacement = getReplacement(levelMutations, this.operators.PostfixIncrementOperatorNegation.mutationName); } else if (!path.node.prefix && path.node.operator == '--') { - replacement = getReplacement( - levelMutations, - this.operators.UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator.mutationName, - ); + replacement = getReplacement(levelMutations, this.operators.PostfixDecrementOperatorNegation.mutationName); } if (replacement !== undefined) { yield types.updateExpression(replacement, deepCloneNode(path.node.argument), path.node.prefix); diff --git a/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts index 938209df41..f1a248077d 100644 --- a/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/string-literal-mutator.spec.ts @@ -6,7 +6,7 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const stringLiteralLevel: MutationLevel = { name: 'ObjectLiteralLevel', - StringLiteral: ['StringLiteral_FilledStringLiteral_ToEmptyStringLiteral', 'StringLiteral_FilledInterpolatedString_ToEmptyInterpolatedString'], + StringLiteral: ['FilledStringLiteralToEmptyReplacement', 'FilledInterpolatedStringToEmptyReplacement'], }; describe(sut.name, () => { diff --git a/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts b/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts index 0cbb1c35ce..b4db64192b 100644 --- a/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/unary-operator-mutator.spec.ts @@ -6,9 +6,9 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const unaryOperatorLevelA: MutationLevel = { name: 'unaryOperatorA', - UnaryOperator: ['UnaryOperator_UnaryPlusOperator_ToUnaryMinusOperator', 'UnaryOperator_BitwiseOrOperator_Removal'], + UnaryOperator: ['UnaryPlusOperatorNegation', 'UnaryBitwiseOrRemoval'], }; -const unaryOperatorLevelB: MutationLevel = { name: 'unaryOperatorB', UnaryOperator: ['UnaryOperator_UnaryMinusOperator_ToUnaryPlusOperator'] }; +const unaryOperatorLevelB: MutationLevel = { name: 'unaryOperatorB', UnaryOperator: ['UnaryMinOperatorNegation'] }; describe(sut.name, () => { it('should have name "UnaryOperator"', () => { 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 ac9831cf52..5b02fbd78e 100644 --- a/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts +++ b/packages/instrumenter/test/unit/mutators/update-operator-mutator.spec.ts @@ -6,18 +6,12 @@ import { MutationLevel } from '../../../src/mutation-level/mutation-level.js'; const updateLevel: MutationLevel = { name: 'UpdateLevel', - UpdateOperator: [ - 'UpdateOperator_PrefixDecrementOperator_ToPrefixIncrementOperator', - 'UpdateOperator_PrefixIncrementOperator_ToPrefixDecrementOperator', - ], + UpdateOperator: ['PrefixDecrementOperatorNegation', 'PrefixIncrementOperatorNegation'], }; const updateLevel2: MutationLevel = { name: 'UpdateLevel2', - UpdateOperator: [ - 'UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator', - 'UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator', - ], + UpdateOperator: ['PostfixDecrementOperatorNegation', 'PostfixIncrementOperatorNegation'], }; const updateUndefinedLevel: MutationLevel = { From fd642cd5bf552de03d3df3871729169c0c745f99 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 18:42:48 +0100 Subject: [PATCH 12/13] Reorder stryker-core to reduce generated warnings --- packages/api/schema/stryker-core.json | 328 +++++++----------- .../src/mutators/array-declaration-mutator.ts | 3 +- .../src/mutators/string-literal-mutator.ts | 2 +- 3 files changed, 129 insertions(+), 204 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index e9606ccf69..8e2f825f63 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -223,7 +223,10 @@ "uniqueItems": true, "default": [], "items": { - "$ref": "#/definitions/MutatorDefinition" + "anyOf": [ + { "$ref": "#/definitions/MutatorDefinition"}, + { "title": "MutationLevelName", "type": "string"} + ] } }, "excludedMutations": { @@ -231,7 +234,10 @@ "uniqueItems": true, "default": [], "items": { - "$ref": "#/definitions/MutatorDefinition" + "anyOf": [ + { "$ref": "#/definitions/MutatorDefinition"}, + { "title": "MutationLevelName", "type": "string"} + ] } } } @@ -265,11 +271,12 @@ }, "MutatorDefinition" : { "anyOf": [ + { "$ref": "#/definitions/_MutatorGroupName"}, { "$ref": "#/definitions/ArithmeticOperator" }, { "$ref": "#/definitions/ArrayDeclaration" }, + { "$ref": "#/definitions/ArrowFunction"}, { "$ref": "#/definitions/AssignmentOperator" }, { "$ref": "#/definitions/BlockStatement" }, - { "$ref": "#/definitions/ArrowFunction"}, { "$ref": "#/definitions/BooleanLiteral" }, { "$ref": "#/definitions/ConditionalExpression" }, { "$ref": "#/definitions/EqualityOperator" }, @@ -280,12 +287,10 @@ { "$ref": "#/definitions/Regex" }, { "$ref": "#/definitions/StringLiteral" }, { "$ref": "#/definitions/UnaryOperator" }, - { "$ref": "#/definitions/UpdateOperator" }, - { "$ref": "#/definitions/MutatorGroupName"}, - { "title": "MutationLevelName", "type": "string"} + { "$ref": "#/definitions/UpdateOperator" } ] }, - "MutatorGroupName": { + "_MutatorGroupName": { "enum": [ "@ArithmeticOperator", "@ArrayDeclaration", @@ -305,28 +310,23 @@ "title": "ArithmeticOperator", "anyOf": [ { - "const" : "RemainderOperatorToMultiplicationReplacement", - "title": "RemainderOperatorToMultiplicationReplacement", - "description": "Replace ```a % b``` with ```a * b```." - }, - { - "const" : "MultiplicationOperatorNegation", - "title": "MultiplicationOperatorNegation", - "description": "Replace ```a * b``` with ```a / b```." + "const" : "AdditionOperatorNegation", + "description": "Replace ```a + b``` with ```a - b```." }, { "const" : "DivisionOperatorNegation", - "title": "DivisionOperatorNegation", "description": "Replace ```a / b``` with ```a * b```." }, { - "const" : "AdditionOperatorNegation", - "title": "AdditionOperatorNegation", - "description": "Replace ```a + b``` with ```a - b```." + "const" : "MultiplicationOperatorNegation", + "description": "Replace ```a * b``` with ```a / b```." + }, + { + "const" : "RemainderOperatorToMultiplicationReplacement", + "description": "Replace ```a % b``` with ```a * b```." }, { "const" : "SubtractionOperatorNegation", - "title": "SubtractionOperatorNegation", "description": "Replace ```a - b``` with ```a + b```." } ] @@ -334,25 +334,21 @@ "ArrayDeclaration": { "title": "ArrayDeclaration", "anyOf": [ - { - "const": "ArrayLiteralItemsFill", - "title": "ArrayLiteralItemsFill", - "description": "Replace ```[ ]``` with ```[Stryker was here]```." - }, { "const": "ArrayConstructorItemsFill", - "title": "ArrayConstructorItemsFill", "description": "Replace ```new Array()``` with ```new Array(Stryker was here)```." }, - { - "const": "ArrayLiteralItemsRemoval", - "title": "ArrayLiteralItemsRemoval", - "description": "Replace ```[1, 2, 3, 4]``` with ```[ ]```." - }, { "const": "ArrayConstructorItemsRemoval", - "title": "ArrayConstructorItemsRemoval", "description": "Replace ```new Array([1, 2, 3, 4])``` with ```new Array()```." + }, + { + "const": "ArrayLiteralItemsFill", + "description": "Replace ```[ ]``` with ```[Stryker was here]```." + }, + { + "const": "ArrayLiteralItemsRemoval", + "description": "Replace ```[1, 2, 3, 4]``` with ```[ ]```." } ] }, @@ -361,63 +357,51 @@ "anyOf": [ { "const" : "AdditionAssignmentNegation", - "title": "AdditionAssignmentNegation", "description": "Replace ```a += b``` with ```a -= b```." }, { - "const" : "SubtractionAssignmentNegation", - "title": "SubtractionAssignmentNegation", - "description": "Replace ```a -= b``` with ```a += b```." + "const" : "BitwiseAndAssignmentNegation", + "description": "Replace ```a &= b``` with ```a |= b```." }, { - "const" : "MultiplicationAssignmentNegation", - "title": "MultiplicationAssignmentNegation", - "description": "Replace ```a *= b``` with ```a /= b```." + "const" : "BitwiseOrAssignmentNegation", + "description": "Replace ```a |= b``` with ```a &= b```." }, { "const" : "DivisionAssignmentNegation", - "title": "DivisionAssignmentNegation", "description": "Replace ```a /= b``` with ```a *= b```." }, - { - "const" : "RemainderAssignmentToMultiplicationReplacement", - "title": "RemainderAssignmentToMultiplicationReplacement", - "description": "Replace ```a %= b``` with ```a *= b```." - }, { "const" : "LeftShiftAssignmentNegation", - "title": "LeftShiftAssignmentNegation", "description": "Replace ```a <<= b``` with ```a >>= b```." }, - { - "const" : "RightShiftAssignmentNegation", - "title": "RightShiftAssignmentNegation", - "description": "Replace ```a >>= b``` with ```a <<= b```." - }, - { - "const" : "BitwiseAndAssignmentNegation", - "title": "BitwiseAndAssignmentNegation", - "description": "Replace ```a &= b``` with ```a |= b```." - }, - { - "const" : "BitwiseOrAssignmentNegation", - "title": "BitwiseOrAssignmentNegation", - "description": "Replace ```a |= b``` with ```a &= b```." - }, { "const" : "LogicalAndAssignmentNegation", - "title": "LogicalOrAssignmentNegation", "description": "Replace ```a &&= b``` with ```a ||= b```." }, { "const" : "LogicalOrAssignmentNegation", - "title": "LogicalOrAssignmentNegation", "description": "Replace ```a ||= b``` with ```a &&= b```." }, + { + "const" : "MultiplicationAssignmentNegation", + "description": "Replace ```a *= b``` with ```a /= b```." + }, { "const" : "NullishCoalescingAssignmentToLogicalAndReplacement", - "title": "NullishCoalescingAssignmentToLogicalAndAssignment", "description": "Replace ```a ??= b``` with ```a &&= b```." + }, + { + "const" : "RemainderAssignmentToMultiplicationReplacement", + "description": "Replace ```a %= b``` with ```a *= b```." + }, + { + "const" : "RightShiftAssignmentNegation", + "description": "Replace ```a >>= b``` with ```a <<= b```." + }, + { + "const" : "SubtractionAssignmentNegation", + "description": "Replace ```a -= b``` with ```a += b```." } ] }, @@ -432,20 +416,17 @@ "BooleanLiteral": { "title": "BooleanLiteral", "anyOf": [ - { - "const" : "TrueLiteralNegation", - "title": "TrueLiteralNegation", - "description": "Replace ```true``` with ```false```." - }, { "const" : "FalseLiteralNegation", - "title": "FalseLiteralNegation", "description": "Replace ```false``` with ```true```." }, { "const" : "LogicalNotRemoval", - "title": "LogicalNotRemoval", "description": "Replace ```!(a == b)``` with ```a == b```." + }, + { + "const" : "TrueLiteralNegation", + "description": "Replace ```true``` with ```false```." } ] }, @@ -453,109 +434,89 @@ "title": "ConditionalExpression", "anyOf": [ { - "const" : "ForLoopConditionToFalseReplacement", - "title": "ForLoopConditionToFalseReplacement", - "description": "Replace ```for (var i = 0; i < 10; i++) { }``` with ```for (var i = 0; false; i++) { }```." + "const" : "BooleanExpressionToFalseReplacement", + "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = false ? 1 : 2;```." }, { - "const" : "WhileLoopConditionToFalseReplacement", - "title": "WhileLoopConditionToFalseReplacement", - "description": "Replace ```while (a > b) { }``` with ```while (false) { }```." + "const" : "BooleanExpressionToTrueReplacement", + "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = true ? 1 : 2;```." }, { "const" : "DoWhileLoopConditionToFalseReplacement", - "title": "DoWhileLoopConditionToFalseReplacement", "description": "Replace ```do { } while (a > b);``` with ```do { } while (false);```." }, { - "const" : "IfConditionToTrueReplacement", - "title": "IfConditionToTrueReplacement", - "description": "Replace ```if (a > b) { }``` with ```if (true) { }```." + "const" : "ForLoopConditionToFalseReplacement", + "description": "Replace ```for (var i = 0; i < 10; i++) { }``` with ```for (var i = 0; false; i++) { }```." }, { "const" : "IfConditionToFalseReplacement", - "title": "IfConditionToFalseReplacement", "description": "Replace ```if (a > b) { }``` with ```if (false) { }```." }, { - "const" : "BooleanExpressionToTrueReplacement", - "title": "BooleanExpressionToTrueReplacement", - "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = true ? 1 : 2;```." - }, - { - "const" : "BooleanExpressionToFalseReplacement", - "title": "BooleanExpressionToFalseReplacement", - "description": "Replace ```var x = a > b ? 1 : 2;``` with ```var x = false ? 1 : 2;```." + "const" : "IfConditionToTrueReplacement", + "description": "Replace ```if (a > b) { }``` with ```if (true) { }```." }, { "const" : "SwitchStatementBodyRemoval", - "title": "SwitchStatementBodyRemoval", "description": "Replace ```switch(x) with switch()```." + }, + { + "const" : "WhileLoopConditionToFalseReplacement", + "description": "Replace ```while (a > b) { }``` with ```while (false) { }```." } ] }, - "EqualityOperator": { + "EqualityOperator": { "title": "EqualityOperator", "anyOf": [ { - "const" : "StrictInequalityOperatorNegation", - "title": "StrictInequalityOperatorNegation", - "description": "Replace ```a !== b``` with ```a === b```." + "const" : "EqualityOperatorNegation", + "description": "Replace ```a == b``` with ```a != b```." + }, + { + "const" : "GreaterThanEqualOperatorBoundary", + "description": "Replace ```a >= b``` with ```a > b```." + }, + { + "const" : "GreaterThanEqualOperatorNegation", + "description": "Replace ```a >= b``` with ```a < b```." + }, + { + "const" : "GreaterThanOperatorBoundary", + "description": "Replace ```a > b``` with ```a >= b```." + }, + { + "const" : "GreaterThanOperatorNegation", + "description": "Replace ```a > b``` with ```a <= b```." }, { "const" : "InequalityOperatorNegation", - "title": "InequalityOperatorNegation", "description": "Replace ```a != b``` with ```a == b```." }, { "const" : "LessThanEqualOperatorBoundary", - "title": "LessThanEqualOperatorBoundary", "description": "Replace ```a <= b``` with ```a < b```." }, { "const" : "LessThanEqualOperatorNegation", - "title": "LessThanEqualOperatorNegation", "description": "Replace ```a <= b``` with ```a > b```." }, { "const" : "LessThanOperatorBoundary", - "title": "LessThanOperatorBoundary", "description": "Replace ```a < b``` with ```a <= b```." }, { "const" : "LessThanOperatorNegation", - "title": "LessThanOperatorNegation", "description": "Replace ```a < b``` with ```a >= b```." }, { "const" : "StrictEqualityOperatorNegation", - "title": "StrictEqualityOperatorNegation", "description": "Replace ```a === b``` with ```a !== b```." }, { - "const" : "EqualityOperatorNegation", - "title": "EqualityOperatorNegation", - "description": "Replace ```a == b``` with ```a != b```." - }, - { - "const" : "GreaterThanEqualOperatorNegation", - "title": "GreaterThanEqualOperatorNegation", - "description": "Replace ```a >= b``` with ```a < b```." - }, - { - "const" : "GreaterThanEqualOperatorBoundary", - "title": "GreaterThanEqualOperatorBoundary", - "description": "Replace ```a >= b``` with ```a > b```." - }, - { - "const" : "GreaterThanOperatorNegation", - "title": "GreaterThanOperatorNegation", - "description": "Replace ```a > b``` with ```a <= b```." - }, - { - "const" : "GreaterThanOperatorBoundary", - "title": "GreaterThanOperatorBoundary", - "description": "Replace ```a > b``` with ```a >= b```." + "const" : "StrictInequalityOperatorNegation", + "description": "Replace ```a !== b``` with ```a === b```." } ] }, @@ -564,17 +525,14 @@ "anyOf": [ { "const" : "LogicalAndOperatorNegation", - "title": "LogicalAndOperatorNegation", "description": "Replace ```a && b``` with ```a || b```." }, { "const" : "LogicalOrOperatorNegation", - "title": "LogicalOrOperatorNegation", "description": "Replace ```a || b``` with ```a && b```." }, { "const" : "NullishCoalescingOperatorToLogicalAndReplacement", - "title": "NullishCoalescingOperatorToLogicalAndReplacement", "description": "Replace ```a ?? b``` with ```a && b```." } ] @@ -584,103 +542,83 @@ "anyOf": [ { "const": "CharAtMethodCallRemoval", - "title": "CharAtMethodCallRemoval", "description": "Remove ```charAt()``` call." }, { "const": "EndsWithMethodCallNegation", - "title": "EndsWithMethodCallNegation", "description": "Replace ```endsWith()``` with ```startsWith()```." }, - { - "const": "StartsWithMethodCallNegation", - "title": "StartsWithMethodCallNegation", - "description": "Replace ```startsWith()``` with ```endsWith()```." - }, { "const": "EveryMethodCallNegation", - "title": "EveryMethodCallNegation", "description": "Replace ```every()``` with ```some()```." }, - { - "const": "SomeMethodCallNegation", - "title": "SomeMethodCallNegation", - "description": "Replace ```some()``` with ```every()```." - }, { "const": "FilterMethodCallRemoval", - "title": "FilterMethodCallRemoval", "description": "Remove ```filter()``` call." }, + { + "const": "MaxMethodCallNegation", + "description": "Replace ```max()``` with ```min()```." + }, + { + "const": "MinMethodCallNegation", + "description": "Replace ```min()``` with ```max()```." + }, { "const": "ReverseMethodCallRemoval", - "title": "ReverseMethodCallRemoval", "description": "Remove ```reverse()``` call" }, { "const": "SliceMethodCallRemoval", - "title": "SliceMethodCallRemoval", "description": "Remove ```slice()``` call." }, + { + "const": "SomeMethodCallNegation", + "description": "Replace ```some()``` with ```every()```." + }, { "const": "SortMethodCallRemoval", - "title": "SortMethodCallRemoval", "description": "Remove ```sort()``` call." }, { - "const": "SubstrMethodCallRemoval", - "title": "SubstrMethodCallRemoval", - "description": "Remove ```substr()``` call." + "const": "StartsWithMethodCallNegation", + "description": "Replace ```startsWith()``` with ```endsWith()```." }, { "const": "SubstringMethodCallRemoval", - "title": "SubstringMethodCallRemoval", "description": "Remove ```substring()``` call." }, + { + "const": "SubstrMethodCallRemoval", + "description": "Remove ```substr()``` call." + }, { "const": "ToLocaleLowerCaseMethodCallNegation", - "title": "ToLocaleLowerCaseMethodCallNegation", "description": "Replace ```toLocaleLowerCase()``` with ```toLocaleUpperCase()```." }, { "const": "ToLocaleUpperCaseMethodCallNegation", - "title": "ToLocaleUpperCaseMethodCallNegation", "description": "Replace ```toLocaleUpperCase()``` with ```toLocaleLowerCase()```." }, { "const": "ToLowerCaseMethodCallNegation", - "title": "ToLowerCaseMethodCallNegation", "description": "Replace ```toLowerCase()``` with ```toUpperCase()```." }, { "const": "ToUpperCaseMethodCallNegation", - "title": "ToUpperCaseMethodCallNegation", "description": "Replace ```toUpperCase()``` with ```toLowerCase()```." }, - { - "const": "TrimMethodCallRemoval", - "title": "TrimMethodCallRemoval", - "description": "Remove ```trim()``` call." - }, { "const": "TrimEndMethodCallNegation", - "title": "TrimEndMethodCallNegation", "description": "Replace ```trimEnd()``` with ```trimStart()```." }, { - "const": "TrimStartMethodCallNegation", - "title": "TrimStartMethodCallNegation", - "description": "Replace ```trimStart()``` with ```trimEnd()```." - }, - { - "const": "MinMethodCallNegation", - "title": "MinMethodCallNegation", - "description": "Replace ```min()``` with ```max()```." + "const": "TrimMethodCallRemoval", + "description": "Remove ```trim()``` call." }, { - "const": "MaxMethodCallNegation", - "title": "MaxMethodCallNegation", - "description": "Replace ```max()``` with ```min()```." + "const": "TrimStartMethodCallNegation", + "description": "Replace ```trimStart()``` with ```trimEnd()```." } ] }, @@ -692,19 +630,16 @@ "title": "OptionalChaining", "anyOf": [ { - "const": "OptionalMemberExpressionOptionalRemoval", - "title": "OptionalMemberExpressionOptionalRemoval", - "description": "Replace ```foo?.bar``` with ```foo.bar```." + "const": "OptionalCallExpressionOptionalRemoval", + "description": "Replace ```foo?.()``` with ```foo()```." }, { "const": "OptionalComputedMemberExpressionOptionalRemoval", - "title": "OptionalComputedMemberExpressionOptionalRemoval", "description": "Replace ```foo?.[1]``` with ```foo[1]```." }, { - "const": "OptionalCallExpressionOptionalRemoval", - "title": "OptionalCallExpressionOptionalRemoval", - "description": "Replace ```foo?.()``` with ```foo()```." + "const": "OptionalMemberExpressionOptionalRemoval", + "description": "Replace ```foo?.bar``` with ```foo.bar```." } ] }, @@ -715,24 +650,20 @@ "title": "StringLiteral", "anyOf": [ { - "const": "FilledStringLiteralToEmptyReplacement", - "title": "FilledStringLiteralToEmptyReplacement", - "description": "Replace ```\"foo\"``` with ```\"\"```." + "const": "EmptyInterpolatedStringToFilledReplacement", + "description": "Replace ```s\"\"``` with ```s\"Stryker was here!\"```." }, { "const": "EmptyStringLiteralToFilledReplacement", - "title": "EmptyStringLiteralToFilledReplacement", "description": "Replace ```\"\"``` with ```\"Stryker was here!\"```." }, { "const": "FilledInterpolatedStringToEmptyReplacement", - "title": "FilledInterpolatedStringToEmptyReplacement", "description": "Replace ```s\"foo ${bar}\"``` with ```s\"\"```." }, { - "const": "EmptdInterpolatedStringToFilledReplacement", - "title": "EmptdInterpolatedStringToFilledReplacement", - "description": "Replace ```s\"\"``` with ```s\"Stryker was here!\"```." + "const": "FilledStringLiteralToEmptyReplacement", + "description": "Replace ```\"foo\"``` with ```\"\"```." } ] }, @@ -740,44 +671,37 @@ "title": "UnaryOperator", "anyOf": [ { - "const": "UnaryPlusOperatorNegation", - "title": "UnaryPlusOperatorNegation", - "description": "Replace ```+a``` with ```-a```." + "const": "UnaryBitwiseOrRemoval", + "description": "Remove ```~``` from ```~a```." }, { "const": "UnaryMinOperatorNegation", - "title": "UnaryMinOperatorNegation", "description": "Replace ```-a``` with ```+a.```" }, { - "const": "UnaryBitwiseOrRemoval", - "title": "UnaryBitwiseOrRemoval", - "description": "Remove ```~``` from ```~a```." + "const": "UnaryPlusOperatorNegation", + "description": "Replace ```+a``` with ```-a```." } ] }, "UpdateOperator": { "title": "UpdateOperator", "anyOf": [ - { - "const": "PostfixIncrementOperatorNegation", - "title": "PostfixIncrementOperatorNegation", - "description": "Replace ```a++``` with ```a--```." - }, { "const": "PostfixDecrementOperatorNegation", - "title": "PostfixDecrementOperatorNegation", "description": "Replace ```a--``` with ```a++```." }, { - "const": "PrefixIncrementOperatorNegation", - "title": "PrefixIncrementOperatorNegation", - "description": "Replace ```++a``` with ```--a```." + "const": "PostfixIncrementOperatorNegation", + "description": "Replace ```a++``` with ```a--```." }, - { + { "const": "PrefixDecrementOperatorNegation", - "title": "PrefixDecrementOperatorNegation", "description": "Replace ```--a``` with ```++a```." + }, + { + "const": "PrefixIncrementOperatorNegation", + "description": "Replace ```++a``` with ```--a```." } ] } diff --git a/packages/instrumenter/src/mutators/array-declaration-mutator.ts b/packages/instrumenter/src/mutators/array-declaration-mutator.ts index 5dc09f6376..37ff9884d4 100644 --- a/packages/instrumenter/src/mutators/array-declaration-mutator.ts +++ b/packages/instrumenter/src/mutators/array-declaration-mutator.ts @@ -24,7 +24,8 @@ export const arrayDeclarationMutator: NodeMutator = { *mutate(path, levelMutations) { // The check of the [] construct in code if (path.isArrayExpression() && isArrayInLevel(path.node, levelMutations)) { - const replacement = path.node.elements.length > 0 ? this.operators.ArrayLiteralItemsRemoval.replacement : this.operators.ArrayLiteralItemsFill.replacement; + const replacement = + path.node.elements.length > 0 ? this.operators.ArrayLiteralItemsRemoval.replacement : this.operators.ArrayLiteralItemsFill.replacement; yield replacement; } // Check for the new Array() construct in code diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index 996c9c596d..84942e2c8e 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -18,7 +18,7 @@ export const stringLiteralMutator: NodeMutator = { }, FillInterpolation: { replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), - mutationName: 'EmptdInterpolatedStringToFilledReplacement', + mutationName: 'EmptyInterpolatedStringToFilledReplacement', }, }, From 8c59f12e396943c890e93a8b7ef7a13db18951b8 Mon Sep 17 00:00:00 2001 From: Danut Copae Date: Fri, 8 Dec 2023 20:16:03 +0100 Subject: [PATCH 13/13] Use the same key for the mutator operators when there is no reason to be more specific --- packages/api/schema/stryker-core.json | 24 ++++--- .../default-mutation-levels.json | 6 +- .../src/mutators/arrow-function-mutator.ts | 4 +- .../src/mutators/block-statement-mutator.ts | 4 +- .../conditional-expression-mutator.ts | 69 +++++++++++-------- .../src/mutators/mutator-options.ts | 6 +- .../src/mutators/object-literal-mutator.ts | 6 +- .../src/mutators/optional-chaining-mutator.ts | 12 ++-- .../src/mutators/regex-mutator.ts | 4 +- .../src/mutators/string-literal-mutator.ts | 30 +++++--- .../src/transformers/babel-transformer.ts | 2 +- 11 files changed, 96 insertions(+), 71 deletions(-) diff --git a/packages/api/schema/stryker-core.json b/packages/api/schema/stryker-core.json index 8e2f825f63..cc210a4617 100644 --- a/packages/api/schema/stryker-core.json +++ b/packages/api/schema/stryker-core.json @@ -223,10 +223,7 @@ "uniqueItems": true, "default": [], "items": { - "anyOf": [ - { "$ref": "#/definitions/MutatorDefinition"}, - { "title": "MutationLevelName", "type": "string"} - ] + "$ref": "#/definitions/MutationSpecification" } }, "excludedMutations": { @@ -234,10 +231,7 @@ "uniqueItems": true, "default": [], "items": { - "anyOf": [ - { "$ref": "#/definitions/MutatorDefinition"}, - { "title": "MutationLevelName", "type": "string"} - ] + "$ref": "#/definitions/MutationSpecification" } } } @@ -269,9 +263,19 @@ } } }, + "MutationSpecification": { + "anyOf": [ + { "$ref": "#/definitions/MutationLevelName"}, + { "$ref": "#/definitions/MutatorDefinition"}, + { "$ref": "#/definitions/MutatorGroupName"} + ] + }, + "MutationLevelName": { + "title": "MutationLevelName", + "type": "string" + }, "MutatorDefinition" : { "anyOf": [ - { "$ref": "#/definitions/_MutatorGroupName"}, { "$ref": "#/definitions/ArithmeticOperator" }, { "$ref": "#/definitions/ArrayDeclaration" }, { "$ref": "#/definitions/ArrowFunction"}, @@ -290,7 +294,7 @@ { "$ref": "#/definitions/UpdateOperator" } ] }, - "_MutatorGroupName": { + "MutatorGroupName": { "enum": [ "@ArithmeticOperator", "@ArrayDeclaration", diff --git a/packages/instrumenter/src/mutation-level/default-mutation-levels.json b/packages/instrumenter/src/mutation-level/default-mutation-levels.json index 1323464177..5bb94fb0cd 100644 --- a/packages/instrumenter/src/mutation-level/default-mutation-levels.json +++ b/packages/instrumenter/src/mutation-level/default-mutation-levels.json @@ -1,7 +1,7 @@ { "mutationLevels":[ { - "name":"level1", + "name":"Level1", "UpdateOperator":[ "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator" ], @@ -36,7 +36,7 @@ ] }, { - "name":"level2", + "name":"Level2", "UpdateOperator":[ "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator" @@ -89,7 +89,7 @@ ] }, { - "name":"level3", + "name":"Level3", "UpdateOperator":[ "UpdateOperator_PostfixDecrementOperator_ToPostfixIncrementOperator", "UpdateOperator_PostfixIncrementOperator_ToPostfixDecrementOperator" diff --git a/packages/instrumenter/src/mutators/arrow-function-mutator.ts b/packages/instrumenter/src/mutators/arrow-function-mutator.ts index fcc0453059..79acecc081 100644 --- a/packages/instrumenter/src/mutators/arrow-function-mutator.ts +++ b/packages/instrumenter/src/mutators/arrow-function-mutator.ts @@ -10,7 +10,7 @@ export const arrowFunctionMutator: NodeMutator = { name: 'ArrowFunction', operators: { - ArrowFunction: { mutationName: 'ArrowFunctionRemoval' }, + ArrowFunctionRemoval: { mutationName: 'ArrowFunctionRemoval' }, }, *mutate(path, levelMutations) { @@ -26,5 +26,5 @@ export const arrowFunctionMutator: NodeMutator = { }; function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(arrowFunctionMutator.operators.ArrowFunction.mutationName); + return levelMutations === undefined || levelMutations.includes(arrowFunctionMutator.operators.ArrowFunctionRemoval.mutationName); } diff --git a/packages/instrumenter/src/mutators/block-statement-mutator.ts b/packages/instrumenter/src/mutators/block-statement-mutator.ts index 9290046664..188d58eb5a 100644 --- a/packages/instrumenter/src/mutators/block-statement-mutator.ts +++ b/packages/instrumenter/src/mutators/block-statement-mutator.ts @@ -10,7 +10,7 @@ export const blockStatementMutator: NodeMutator = { name: 'BlockStatement', operators: { - BlockStatement: { mutationName: 'BlockStatementRemoval' }, + BlockStatementRemoval: { mutationName: 'BlockStatementRemoval' }, }, *mutate(path, levelMutations) { @@ -77,5 +77,5 @@ function hasSuperExpressionOnFirstLine(constructor: NodePath = name: 'ConditionalExpression', operators: { - BooleanExpressionToFalse: { replacement: types.booleanLiteral(false), mutationName: 'BooleanExpressionToFalseReplacement' }, - BooleanExpressionToTrue: { replacement: types.booleanLiteral(true), mutationName: 'BooleanExpressionToTrueReplacement' }, - DoWhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'DoWhileLoopConditionToFalseReplacement' }, - ForLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'ForLoopConditionToFalseReplacement' }, - IfToFalse: { replacement: types.booleanLiteral(false), mutationName: 'IfConditionToFalseReplacement' }, - IfToTrue: { replacement: types.booleanLiteral(true), mutationName: 'IfConditionToTrueReplacement' }, - WhileLoopToFalse: { replacement: types.booleanLiteral(false), mutationName: 'WhileLoopConditionToFalseReplacement' }, - SwitchBodyRemoval: { replacement: [], mutationName: 'SwitchStatementBodyRemoval' }, + BooleanExpressionToFalseReplacement: { replacement: types.booleanLiteral(false), mutationName: 'BooleanExpressionToFalseReplacement' }, + BooleanExpressionToTrueReplacement: { replacement: types.booleanLiteral(true), mutationName: 'BooleanExpressionToTrueReplacement' }, + DoWhileLoopConditionToFalseReplacement: { replacement: types.booleanLiteral(false), mutationName: 'DoWhileLoopConditionToFalseReplacement' }, + ForLoopConditionToFalseReplacement: { replacement: types.booleanLiteral(false), mutationName: 'ForLoopConditionToFalseReplacement' }, + IfConditionToFalseReplacement: { replacement: types.booleanLiteral(false), mutationName: 'IfConditionToFalseReplacement' }, + IfConditionToTrueReplacement: { replacement: types.booleanLiteral(true), mutationName: 'IfConditionToTrueReplacement' }, + WhileLoopConditionToFalseReplacement: { replacement: types.booleanLiteral(false), mutationName: 'WhileLoopConditionToFalseReplacement' }, + SwitchStatementBodyRemoval: { replacement: [], mutationName: 'SwitchStatementBodyRemoval' }, }, *mutate(path, levelMutations) { if (isTestOfLoop(path)) { - if (isTestOfWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.WhileLoopToFalse.mutationName))) { - yield this.operators.WhileLoopToFalse.replacement; + if ( + isTestOfWhileLoop(path) && + (levelMutations === undefined || levelMutations.includes(this.operators.WhileLoopConditionToFalseReplacement.mutationName)) + ) { + yield this.operators.WhileLoopConditionToFalseReplacement.replacement; } - if (isTestOfDoWhileLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.DoWhileLoopToFalse.mutationName))) { - yield this.operators.DoWhileLoopToFalse.replacement; + if ( + isTestOfDoWhileLoop(path) && + (levelMutations === undefined || levelMutations.includes(this.operators.DoWhileLoopConditionToFalseReplacement.mutationName)) + ) { + yield this.operators.DoWhileLoopConditionToFalseReplacement.replacement; } - if (isTestOfForLoop(path) && (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopToFalse.mutationName))) { - yield this.operators.ForLoopToFalse.replacement; + if ( + isTestOfForLoop(path) && + (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopConditionToFalseReplacement.mutationName)) + ) { + yield this.operators.ForLoopConditionToFalseReplacement.replacement; } } else if (isTestOfCondition(path)) { - if (levelMutations === undefined || levelMutations.includes(this.operators.IfToTrue.mutationName)) { - yield this.operators.IfToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.IfConditionToTrueReplacement.mutationName)) { + yield this.operators.IfConditionToTrueReplacement.replacement; } - if (levelMutations === undefined || levelMutations.includes(this.operators.IfToFalse.mutationName)) { - yield this.operators.IfToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.IfConditionToFalseReplacement.mutationName)) { + yield this.operators.IfConditionToFalseReplacement.replacement; } } else if (isBooleanExpression(path)) { if (path.parent?.type === 'LogicalExpression') { @@ -49,8 +58,8 @@ export const conditionalExpressionMutator: NodeMutator = // has the same behavior as the (true) mutator, handled in the // isTestOfCondition branch above if (path.parent.operator === '||') { - if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalse.mutationName)) { - yield this.operators.BooleanExpressionToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalseReplacement.mutationName)) { + yield this.operators.BooleanExpressionToFalseReplacement.replacement; } return; } @@ -58,29 +67,29 @@ export const conditionalExpressionMutator: NodeMutator = // has the same behavior as the (false) mutator, handled in the // isTestOfCondition branch above if (path.parent.operator === '&&') { - if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrue.mutationName)) { - yield this.operators.BooleanExpressionToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrueReplacement.mutationName)) { + yield this.operators.BooleanExpressionToTrueReplacement.replacement; } return; } } - if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrue.mutationName)) { - yield this.operators.BooleanExpressionToTrue.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToTrueReplacement.mutationName)) { + yield this.operators.BooleanExpressionToTrueReplacement.replacement; } - if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalse.mutationName)) { - yield this.operators.BooleanExpressionToFalse.replacement; + if (levelMutations === undefined || levelMutations.includes(this.operators.BooleanExpressionToFalseReplacement.mutationName)) { + yield this.operators.BooleanExpressionToFalseReplacement.replacement; } } else if (path.isForStatement() && !path.node.test) { - if (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopToFalse.mutationName)) { + if (levelMutations === undefined || levelMutations.includes(this.operators.ForLoopConditionToFalseReplacement.mutationName)) { const replacement = deepCloneNode(path.node); - replacement.test = this.operators.ForLoopToFalse.replacement; + replacement.test = this.operators.ForLoopConditionToFalseReplacement.replacement; yield replacement; } } else if (path.isSwitchCase() && path.node.consequent.length > 0) { // if not a fallthrough case - if (levelMutations === undefined || levelMutations.includes(this.operators.SwitchBodyRemoval.mutationName)) { + if (levelMutations === undefined || levelMutations.includes(this.operators.SwitchStatementBodyRemoval.mutationName)) { const replacement = deepCloneNode(path.node); - replacement.consequent = this.operators.SwitchBodyRemoval.replacement; + replacement.consequent = this.operators.SwitchStatementBodyRemoval.replacement; yield replacement; } } diff --git a/packages/instrumenter/src/mutators/mutator-options.ts b/packages/instrumenter/src/mutators/mutator-options.ts index a9e684da9a..3cb669a20c 100644 --- a/packages/instrumenter/src/mutators/mutator-options.ts +++ b/packages/instrumenter/src/mutators/mutator-options.ts @@ -1,7 +1,7 @@ -import { MutatorDefinition } from '@stryker-mutator/api/core'; +import { MutationSpecification } from '@stryker-mutator/api/core'; export interface MutatorOptions { - includedMutations: MutatorDefinition[]; - excludedMutations: MutatorDefinition[]; + includedMutations: MutationSpecification[]; + excludedMutations: MutationSpecification[]; noHeader?: boolean; } diff --git a/packages/instrumenter/src/mutators/object-literal-mutator.ts b/packages/instrumenter/src/mutators/object-literal-mutator.ts index 1155cfb676..9137324d18 100644 --- a/packages/instrumenter/src/mutators/object-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/object-literal-mutator.ts @@ -10,7 +10,7 @@ export const objectLiteralMutator: NodeMutator = { name: 'ObjectLiteral', operators: { - ObjectLiteral: { mutationName: 'ObjectLiteralPropertiesRemoval' }, + ObjectLiteralPropertiesRemoval: { mutationName: 'ObjectLiteralPropertiesRemoval' }, }, *mutate(path, levelMutations) { @@ -21,5 +21,7 @@ export const objectLiteralMutator: NodeMutator = { }; function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(objectLiteralMutator.operators.ObjectLiteral.mutationName as string); + return ( + levelMutations === undefined || levelMutations.includes(objectLiteralMutator.operators.ObjectLiteralPropertiesRemoval.mutationName as string) + ); } diff --git a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts index 0481b2700e..e30962e94e 100644 --- a/packages/instrumenter/src/mutators/optional-chaining-mutator.ts +++ b/packages/instrumenter/src/mutators/optional-chaining-mutator.ts @@ -23,9 +23,9 @@ export const optionalChainingMutator: NodeMutator = { name: 'OptionalChaining', operators: { - OptionalCallExpression: { mutationName: 'OptionalCallExpressionOptionalRemoval' }, - OptionalMemberExpression: { mutationName: 'OptionalMemberExpressionOptionalRemoval' }, - OptionalComputedMemberExpression: { mutationName: 'OptionalComputedMemberExpressionOptionalRemoval' }, + OptionalCallExpressionOptionalRemoval: { mutationName: 'OptionalCallExpressionOptionalRemoval' }, + OptionalMemberExpressionOptionalRemoval: { mutationName: 'OptionalMemberExpressionOptionalRemoval' }, + OptionalComputedMemberExpressionOptionalRemoval: { mutationName: 'OptionalComputedMemberExpressionOptionalRemoval' }, }, *mutate(path, levelMutations) { @@ -33,8 +33,8 @@ export const optionalChainingMutator: NodeMutator = { path.isOptionalMemberExpression() && path.node.optional && (levelMutations === undefined || - (!path.node.computed && levelMutations.includes(this.operators.OptionalMemberExpression.mutationName)) || - (path.node.computed && levelMutations.includes(this.operators.OptionalComputedMemberExpression.mutationName))) + (!path.node.computed && levelMutations.includes(this.operators.OptionalMemberExpressionOptionalRemoval.mutationName)) || + (path.node.computed && levelMutations.includes(this.operators.OptionalComputedMemberExpressionOptionalRemoval.mutationName))) ) { yield t.optionalMemberExpression( t.cloneNode(path.node.object, true), @@ -46,7 +46,7 @@ export const optionalChainingMutator: NodeMutator = { if ( path.isOptionalCallExpression() && path.node.optional && - (levelMutations === undefined || levelMutations.includes(this.operators.OptionalCallExpression.mutationName)) + (levelMutations === undefined || levelMutations.includes(this.operators.OptionalCallExpressionOptionalRemoval.mutationName)) ) { yield t.optionalCallExpression( t.cloneNode(path.node.callee, true), diff --git a/packages/instrumenter/src/mutators/regex-mutator.ts b/packages/instrumenter/src/mutators/regex-mutator.ts index 3325cdd878..467808f226 100644 --- a/packages/instrumenter/src/mutators/regex-mutator.ts +++ b/packages/instrumenter/src/mutators/regex-mutator.ts @@ -35,7 +35,7 @@ export const regexMutator: NodeMutator = { name: 'Regex', operators: { - Regex: { mutationName: 'RegexRemoval' }, + RegexRemoval: { mutationName: 'RegexRemoval' }, }, *mutate(path, options) { @@ -67,5 +67,5 @@ function mutatePattern(pattern: string, flags: string | undefined): string[] { } function isInMutationLevel(levelMutations: string[] | undefined): boolean { - return levelMutations === undefined || levelMutations.includes(regexMutator.operators.Regex.mutationName); + return levelMutations === undefined || levelMutations.includes(regexMutator.operators.RegexRemoval.mutationName); } diff --git a/packages/instrumenter/src/mutators/string-literal-mutator.ts b/packages/instrumenter/src/mutators/string-literal-mutator.ts index 84942e2c8e..ed168c2a68 100644 --- a/packages/instrumenter/src/mutators/string-literal-mutator.ts +++ b/packages/instrumenter/src/mutators/string-literal-mutator.ts @@ -10,13 +10,19 @@ export const stringLiteralMutator: NodeMutator = { name: 'StringLiteral', operators: { - FillString: { replacement: types.stringLiteral('Stryker was here!'), mutationName: 'EmptyStringLiteralToFilledReplacement' }, - EmptyString: { replacement: types.stringLiteral(''), mutationName: 'FilledStringLiteralToEmptyReplacement' }, - EmptyInterpolation: { + EmptyStringLiteralToFilledReplacement: { + replacement: types.stringLiteral('Stryker was here!'), + mutationName: 'EmptyStringLiteralToFilledReplacement', + }, + FilledStringLiteralToEmptyReplacement: { + replacement: types.stringLiteral(''), + mutationName: 'FilledStringLiteralToEmptyReplacement', + }, + FilledInterpolatedStringToEmptyReplacement: { replacement: types.templateLiteral([types.templateElement({ raw: '' })], []), mutationName: 'FilledInterpolatedStringToEmptyReplacement', }, - FillInterpolation: { + EmptyInterpolatedStringToFilledReplacement: { replacement: types.templateLiteral([types.templateElement({ raw: 'Stryker was here!' })], []), mutationName: 'EmptyInterpolatedStringToFilledReplacement', }, @@ -27,20 +33,24 @@ export const stringLiteralMutator: NodeMutator = { const stringIsEmpty = path.node.quasis.length === 1 && path.node.quasis[0].value.raw.length === 0; if ( levelMutations === undefined || - (stringIsEmpty && levelMutations.includes(this.operators.FillInterpolation.mutationName)) || - (!stringIsEmpty && levelMutations.includes(this.operators.EmptyInterpolation.mutationName)) + (stringIsEmpty && levelMutations.includes(this.operators.EmptyInterpolatedStringToFilledReplacement.mutationName)) || + (!stringIsEmpty && levelMutations.includes(this.operators.FilledInterpolatedStringToEmptyReplacement.mutationName)) ) { - yield stringIsEmpty ? this.operators.FillInterpolation.replacement : this.operators.EmptyInterpolation.replacement; + yield stringIsEmpty + ? this.operators.EmptyInterpolatedStringToFilledReplacement.replacement + : this.operators.FilledInterpolatedStringToEmptyReplacement.replacement; } } if (path.isStringLiteral() && isValidParent(path)) { const stringIsEmpty = path.node.value.length === 0; if ( levelMutations === undefined || - (stringIsEmpty && levelMutations.includes(this.operators.FillString.mutationName)) || - (!stringIsEmpty && levelMutations.includes(this.operators.EmptyString.mutationName)) + (stringIsEmpty && levelMutations.includes(this.operators.EmptyStringLiteralToFilledReplacement.mutationName)) || + (!stringIsEmpty && levelMutations.includes(this.operators.FilledStringLiteralToEmptyReplacement.mutationName)) ) { - yield stringIsEmpty ? this.operators.FillString.replacement : this.operators.EmptyString.replacement; + yield stringIsEmpty + ? this.operators.EmptyStringLiteralToFilledReplacement.replacement + : this.operators.FilledStringLiteralToEmptyReplacement.replacement; } } }, diff --git a/packages/instrumenter/src/transformers/babel-transformer.ts b/packages/instrumenter/src/transformers/babel-transformer.ts index 5642d2068b..4e7751d319 100644 --- a/packages/instrumenter/src/transformers/babel-transformer.ts +++ b/packages/instrumenter/src/transformers/babel-transformer.ts @@ -159,7 +159,7 @@ export const transformBabel: AstTransformer = ( //TODO: Create runLevel here const runLevel: MutationLevel | undefined = undefined; for (const defaultLevel of defaultMutationLevels) { - if ('@' + defaultLevel.name in options.includedMutations) { + if (options.includedMutations.includes('@' + defaultLevel.name)) { //For each key in defaultLevel, ADD it to the runLevel } }