From c56ec6f1cc547a268c728de322a8081376202568 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Tue, 9 May 2023 16:25:26 +0100 Subject: [PATCH] warn when spring plugin not present --- .../verify/KotlinVerifierFactory.java | 2 +- .../verify/SpringVerifierFactory.java | 48 +++++++++++++++ ...t.mutationtest.verify.BuildVerifierFactory | 3 +- .../verify/SpringVerifierFactoryTest.java | 59 +++++++++++++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java create mode 100644 pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java index 4357b0591..598a07170 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java @@ -31,7 +31,7 @@ class KotlinVerifier implements BuildVerifier { @Override public List verify() { if (kotlinIsOnClassPath() && !kotlinPluginIsPresent() && kotlinClassesToBeMutated()) { - return asList("Project uses kotlin, but the Arcmutate kotlin plugin is not on classpath (https://docs.arcmutate.com/docs/kotlin.html)"); + return asList("Project uses kotlin, but the Arcmutate kotlin plugin is not present (https://docs.arcmutate.com/docs/kotlin.html)"); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java new file mode 100644 index 000000000..15ede5364 --- /dev/null +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java @@ -0,0 +1,48 @@ +package org.pitest.mutationtest.verify; + +import org.pitest.classinfo.ClassName; +import org.pitest.classpath.CodeSource; + +import java.util.Collections; +import java.util.List; + +import static java.util.Arrays.asList; + +public class SpringVerifierFactory implements BuildVerifierFactory { + @Override + public BuildVerifier create(CodeSource code) { + return new SpringVerifier(code); + } + + @Override + public String description() { + return "Detect missing spring plugin"; + } +} + +class SpringVerifier implements BuildVerifier { + + private final CodeSource code; + + SpringVerifier(CodeSource code) { + this.code = code; + } + + @Override + public List verify() { + if (springIsOnClassPath() && !springPluginIsPresent()) { + return asList("Project uses Spring, but the Arcmutate Spring plugin is not present (https://docs.arcmutate.com/docs/spring.html)"); + } + + return Collections.emptyList(); + } + + + private boolean springPluginIsPresent() { + return code.fetchClassBytes(ClassName.fromString("com.groupcdg.arcmutate.spring.PluginMarker")).isPresent(); + } + + private boolean springIsOnClassPath() { + return code.fetchClassBytes(ClassName.fromString("org.springframework.core.SpringVersion")).isPresent(); + } +} \ No newline at end of file diff --git a/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.verify.BuildVerifierFactory b/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.verify.BuildVerifierFactory index 20e31c744..b449ff196 100644 --- a/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.verify.BuildVerifierFactory +++ b/pitest-entry/src/main/resources/META-INF/services/org.pitest.mutationtest.verify.BuildVerifierFactory @@ -1,4 +1,5 @@ org.pitest.mutationtest.verify.DefaultBuildVerifierFactory org.pitest.mutationtest.verify.MissingJUnit5PluginVerifierFactory org.pitest.mutationtest.verify.MissingTestNGPluginVerifierFactory -org.pitest.mutationtest.verify.KotlinVerifierFactory \ No newline at end of file +org.pitest.mutationtest.verify.KotlinVerifierFactory +org.pitest.mutationtest.verify.SpringVerifierFactory \ No newline at end of file diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java new file mode 100644 index 000000000..e3a937354 --- /dev/null +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java @@ -0,0 +1,59 @@ +package org.pitest.mutationtest.verify; + +import org.junit.Test; +import org.pitest.bytecode.analysis.ClassTree; +import org.pitest.classinfo.ClassName; +import org.pitest.verifier.interceptors.BuildVerifierVerifier; + +import static org.pitest.verifier.interceptors.BuildVerifierVerifier.aValidClass; +import static org.pitest.verifier.interceptors.BuildVerifierVerifier.codeSourceForClasses; +import static org.pitest.verifier.interceptors.BuildVerifierVerifier.codeSourceReturning; + +public class SpringVerifierFactoryTest { + BuildVerifierVerifier v = BuildVerifierVerifier.confirmFactory(new SpringVerifierFactory()); + + @Test + public void isOnChain() { + v.isOnChain(); + } + + @Test + public void doesNotDisplayMessageWhenSpringNotPresent() { + v.withCodeSource(codeSourceReturning(ClassName.fromString("not.relevant.Foo"))) + .issues() + .isEmpty(); + } + + @Test + public void displaysWarningWhenSpringPresentWithoutPlugin() { + ClassTree springMarker = aValidClass(); + springMarker.rawNode().name = "org.springframework.core.SpringVersion"; + + + ClassTree clientCode = aValidClass(); + clientCode.rawNode().name = "com.example.Foo"; + clientCode.rawNode().sourceFile = "Foo.kt"; + + v.withCodeSource(codeSourceForClasses(springMarker, clientCode)) + .issues() + .isNotEmpty(); + } + + @Test + public void doesNotDisplayWarningWhenPluginPresent() { + ClassTree springMarker = aValidClass(); + springMarker.rawNode().name = "org.springframework.core.SpringVersion"; + + ClassTree pluginMarker = aValidClass(); + pluginMarker.rawNode().name = "com.groupcdg.arcmutate.spring.PluginMarker"; + + ClassTree clientCode = aValidClass(); + clientCode.rawNode().name = "com.example.Foo"; + clientCode.rawNode().sourceFile = "Foo.kt"; + + v.withCodeSource(codeSourceForClasses(springMarker, pluginMarker, clientCode)) + .issues() + .isEmpty(); + } +} +