From 89b0c2c68d89b6fe7fe7dd12858d68fef15d4694 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Wed, 27 Oct 2021 14:20:12 +0100 Subject: [PATCH] mutate map returns to emptyMap instead of null --- README.md | 4 ++++ .../EquivalentReturnMutationFilter.java | 1 + .../EquivalentReturnMutationFilterTest.java | 11 +++++++++++ .../returns/EmptyObjectReturnValsMutator.java | 17 +++++++++++++++++ .../mutators/EmptyObjectReturnValsTest.java | 15 +++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/README.md b/README.md index 3f690af89..b4f5cd433 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ Read all about it at http://pitest.org ## Releases +### 1.7.3 (unreleased) + +* #952 Mutate map return to emptyMap instead of null + ### 1.7.2 * #943 Change default mutators - replace negate conditional with remove conditional diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilter.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilter.java index 5a424808e..c16318742 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilter.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilter.java @@ -268,6 +268,7 @@ public boolean test(MutationDetails a) { || returns(method, mutatedInstruction, "java/util/Optional","empty") || returns(method, mutatedInstruction, "java/util/stream/Stream","empty") || returns(method, mutatedInstruction, "java/util/Collections","emptyList") + || returns(method, mutatedInstruction, "java/util/Collections","emptyMap") || returns(method, mutatedInstruction, "java/util/Collections","emptySet") || returns(method, mutatedInstruction, "java/util/List","of") || returns(method, mutatedInstruction, "java/util/Set","of"); diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilterTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilterTest.java index 224a43d72..d90252b2f 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilterTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/build/intercept/equivalent/EquivalentReturnMutationFilterTest.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; @@ -143,6 +144,11 @@ public void filtersEquivalentListMutants() { this.verifier.assertFiltersNMutationFromClass(1, AlreadyReturnsEmptyList.class); } + @Test + public void filtersEquivalentMapMutants() { + this.verifier.assertFiltersNMutationFromClass(1, AlreadyReturnsEmptyMap.class); + } + @Test public void filtersEquivalentListMutantsInTryCatch() { this.verifier.assertFiltersNMutationFromClass(1, AlreadyReturnsEmptyListInTryCatch.class); @@ -317,6 +323,11 @@ public List a() { } } +class AlreadyReturnsEmptyMap { + public Map a() { + return Collections.emptyMap(); + } +} class AlreadyReturnsEmptyListInTryCatch { public List a(String s) { diff --git a/pitest/src/main/java/org/pitest/mutationtest/engine/gregor/mutators/returns/EmptyObjectReturnValsMutator.java b/pitest/src/main/java/org/pitest/mutationtest/engine/gregor/mutators/returns/EmptyObjectReturnValsMutator.java index 2dba32f02..12638f561 100644 --- a/pitest/src/main/java/org/pitest/mutationtest/engine/gregor/mutators/returns/EmptyObjectReturnValsMutator.java +++ b/pitest/src/main/java/org/pitest/mutationtest/engine/gregor/mutators/returns/EmptyObjectReturnValsMutator.java @@ -69,6 +69,7 @@ class AReturnMethodVisitor extends AbstractInsnMutator { NON_NULL_MUTATIONS.put("java.util.Optional", returnEmptyOptional()); NON_NULL_MUTATIONS.put("java.util.stream.Stream", returnEmptyStream()); NON_NULL_MUTATIONS.put("java.util.List", returnEmptyList()); + NON_NULL_MUTATIONS.put("java.util.Map", returnEmptyMap()); NON_NULL_MUTATIONS.put("java.util.Set", returnEmptySet()); NON_NULL_MUTATIONS.put("java.util.Collection", returnEmptyList()); } @@ -204,6 +205,22 @@ public String describe(final int opCode, final MethodInfo methodInfo) { }; } + private static ZeroOperandMutation returnEmptyMap() { + return new ZeroOperandMutation() { + @Override + public void apply(final int opCode, final MethodVisitor mv) { + mv.visitInsn(Opcodes.POP); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Collections", "emptyMap", "()Ljava/util/Map;", false); + mv.visitInsn(Opcodes.ARETURN); + } + + @Override + public String describe(final int opCode, final MethodInfo methodInfo) { + return "replaced return value with Collections.emptyMap for " + methodInfo.getDescription(); + } + }; + } + private static ZeroOperandMutation returnEmptySet() { return new ZeroOperandMutation() { @Override diff --git a/pitest/src/test/java/org/pitest/mutationtest/engine/gregor/mutators/EmptyObjectReturnValsTest.java b/pitest/src/test/java/org/pitest/mutationtest/engine/gregor/mutators/EmptyObjectReturnValsTest.java index 06e5104bd..64f531395 100644 --- a/pitest/src/test/java/org/pitest/mutationtest/engine/gregor/mutators/EmptyObjectReturnValsTest.java +++ b/pitest/src/test/java/org/pitest/mutationtest/engine/gregor/mutators/EmptyObjectReturnValsTest.java @@ -8,7 +8,9 @@ import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; @@ -131,6 +133,12 @@ public void mutatesListToEmptyList() throws Exception { createFirstMutant(AList.class), Collections.emptyList()); } + @Test + public void mutatesMapToEmptyMap() throws Exception { + assertMutantCallableReturns(new AMap(), + createFirstMutant(AMap.class), Collections.emptyMap()); + } + @Test public void mutatesSetToEmptySet() throws Exception { assertMutantCallableReturns(new ASet(), @@ -235,6 +243,13 @@ public List call() throws Exception { } } + private static class AMap implements Callable> { + @Override + public Map call() throws Exception { + return new HashMap<>(); + } + } + private static class ASet implements Callable> { @Override public Set call() throws Exception {