/* * Copyright 2012 Nicolas Rusconi * * Licensed under the Apache License, Version 2.0 ("the "License""); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. */ package org.pitest.ant; import static org.mockito.Matchers.startsWith; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import java.io.File; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.types.Commandline.Argument; import org.apache.tools.ant.types.Path; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.pitest.mutationtest.commandline.MutationCoverageReport; @RunWith(MockitoJUnitRunner.class) public class PitestTaskTest { private PitestTask pitestTask; @Mock private Java java; @Mock private Argument arg; @Mock private Project project; @Rule public ExpectedException exception = ExpectedException.none(); @Before public void setUp() { when(this.java.createArg()).thenReturn(this.arg); this.pitestTask = new PitestTask(); this.pitestTask.setClasspath("bin/"); this.pitestTask.setPitClasspath("foo/"); this.pitestTask.setTargetClasses("com.*"); this.pitestTask.setReportDir("report/"); this.pitestTask.setSourceDir("src/"); this.pitestTask.setProject(this.project); } @Test public void shouldPassAvoidCallsOptionToJavaTask() { this.pitestTask.setAvoidCallsTo("avoidCalls"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--avoidCallsTo=avoidCalls"); } @Test public void shouldPassDependencyDistanceOptionToJavaTask() { this.pitestTask.setDependencyDistance("distance"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--dependencyDistance=distance"); } @Test public void shouldPassExcludedClassesOptionToJavaTask() { this.pitestTask.setExcludedClasses("String"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--excludedClasses=String"); } @Test public void shouldPassExcludedMethodsOptionToJavaTask() { this.pitestTask.setExcludedMethods("toString"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--excludedMethods=toString"); } @Test public void shouldPassJvmArgsOptionToJavaTask() { this.pitestTask.setJvmArgs("-Da=a"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--jvmArgs=-Da=a"); } @Test public void shouldPassMaxMutationsPerClassOptionToJavaTask() { this.pitestTask.setMaxMutationsPerClass("10"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--maxMutationsPerClass=10"); } @Test public void shouldPassMutateStaticInitsOptionToJavaTask() { this.pitestTask.setMutateStaticInits("true"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutateStaticInits=true"); } @Test public void shouldNotPassMutateStaticInitsOptionToJavaTaskWhenNoValueSet() { this.pitestTask.execute(this.java); verify(this.arg, never()).setValue("--mutateStaticInits=true"); } @Test public void shouldPassMutateStaticInitsOptionToJavaTaskWhenValueIsFalse() { this.pitestTask.setMutateStaticInits("false"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutateStaticInits=false"); } @Test public void shouldPassDetectInlinedCodeOptionToJavaTask() { this.pitestTask.setDetectInlinedCode("true"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--detectInlinedCode=true"); } @Test public void shouldNotPassInlinedCodeOptionToJavaTaskWhenNoValueSet() { this.pitestTask.execute(this.java); verify(this.arg, never()).setValue("--detectInlinedCode=true"); } @Test public void shouldPassMutateInlinedCodeOptionToJavaTaskWhenValueIsFalse() { this.pitestTask.setDetectInlinedCode("false"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--detectInlinedCode=false"); } @Test public void shouldPassMutatorsOptionToJavaTask() { this.pitestTask.setMutators("a,b"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutators=a,b"); } @Test public void shouldPassOutputFormatsOptionToJavaTask() { this.pitestTask.setOutputFormats("XML"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--outputFormats=XML"); } @Test public void shouldPassReportDirOptionToJavaTask() { this.pitestTask.setReportDir("report/"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--reportDir=report/"); } @Test public void shouldPassTargetClassesOptionToJavaTask() { this.pitestTask.setTargetClasses("com.*"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--targetClasses=com.*"); } @Test public void shouldPassTargetTestsOptionToJavaTask() { this.pitestTask.setTargetTests("Test*"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--targetTests=Test*"); } @Test public void shouldPassThreadsOptionToJavaTask() { this.pitestTask.setThreads("4"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--threads=4"); } @Test public void shouldPassTimeoutConstsOptionToJavaTask() { this.pitestTask.setTimeoutConst("100"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--timeoutConst=100"); } @Test public void shouldPassTimeoutFactorOptionToJavaTask() { this.pitestTask.setTimeoutFactor("1.20"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--timeoutFactor=1.20"); } @Test public void shouldPassVerboseFlagToJavaTaskWhenValueIsTrue() { this.pitestTask.setVerbose("true"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--verbose=true"); } @Test public void shouldPassVerboseFlagToJavaTaskWhenValueIsFalse() { this.pitestTask.setVerbose("false"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--verbose=false"); } @Test public void shouldPassIncludedGroupsOptionToJavaTask() { this.pitestTask.setIncludedGroups("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--includedGroups=foo"); } @Test public void shouldPassExcludedGroupsOptionToJavaTask() { this.pitestTask.setExcludedGroups("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--excludedGroups=foo"); } @Test public void shouldPassMutableCodePathsToJavaTask() { this.pitestTask.setMutableCodePaths("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutableCodePaths=foo"); } @Test public void shouldOnlyPassTheSpecifiedOptions() throws Exception { this.pitestTask.setVerbose("true"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--verbose=true"); verify(this.arg).setValue("--targetClasses=com.*"); verify(this.arg).setValue("--reportDir=report/"); verify(this.arg).setValue("--sourceDirs=src/"); verify(this.arg).setValue("--includeLaunchClasspath=false"); verify(this.arg).setValue(startsWith("--classPath=")); verifyNoMoreInteractions(this.arg); } @Test public void shouldFailtOnError() throws Exception { this.pitestTask.execute(this.java); verify(this.java).setFailonerror(true); } @Test public void shouldForkWhenExecuted() throws Exception { this.pitestTask.execute(this.java); verify(this.java).setFork(true); } @Test public void shouldExecute() throws Exception { this.pitestTask.execute(this.java); verify(this.java).execute(); } @Test public void shouldExecutePitMainClass() throws Exception { this.pitestTask.execute(this.java); verify(this.java).setClassname( MutationCoverageReport.class.getCanonicalName()); } @Test public void shouldFailWhenNoClasspathSupplied() throws Exception { this.exception.expect(BuildException.class); this.exception.expectMessage("You must specify the classpath."); this.pitestTask = new PitestTask(); this.pitestTask.execute(this.java); } @Test public void shouldFailWhenNoTargetClassesSupplied() throws Exception { this.exception.expect(BuildException.class); this.exception.expectMessage("You must specify the targetClasses."); this.pitestTask = new PitestTask(); this.pitestTask.setClasspath("bin/"); this.pitestTask.setPitClasspath("foo/"); this.pitestTask.setProject(this.project); this.pitestTask.execute(this.java); } @Test public void shouldFailWhenNoReportDirSupplied() throws Exception { this.exception.expect(BuildException.class); this.exception.expectMessage("You must specify the reportDir."); this.pitestTask = new PitestTask(); this.pitestTask.setClasspath("bin/"); this.pitestTask.setPitClasspath("foo/"); this.pitestTask.setProject(this.project); this.pitestTask.setTargetClasses("com.*"); this.pitestTask.execute(this.java); } @Test public void shouldFailWhenNoSourceDirSupplied() throws Exception { this.exception.expect(BuildException.class); this.exception.expectMessage("You must specify the sourceDirs."); this.pitestTask = new PitestTask(); this.pitestTask.setClasspath("bin/"); this.pitestTask.setPitClasspath("foo/"); this.pitestTask.setProject(this.project); this.pitestTask.setTargetClasses("com.*"); this.pitestTask.setReportDir("report/"); this.pitestTask.execute(this.java); } @Test public void shouldSetPitClasspathOnJavaTask() throws Exception { final String classpath = "bin/" + File.pathSeparator + "lib/util.jar"; this.pitestTask.setPitClasspath(classpath); this.pitestTask.execute(this.java); verify(this.java).setClasspath(argThat(new PathMatcher(classpath))); } @Test public void shouldPassAnalysisClassPathToPit() throws Exception { this.pitestTask.setClasspath("Foo" + File.pathSeparator + "Bar"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--classPath=Foo,Bar"); } @Test public void shouldPassTimestampedDirectoryFlagToJavaTaskWhenValueIsTrue() throws Exception { this.pitestTask.setTimestampedReports("true"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--timestampedReports=true"); } @Test public void shouldPassTimestampedDirectoryFlagToJavaTaskWhenValueIsFalse() throws Exception { this.pitestTask.setTimestampedReports("false"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--timestampedReports=false"); } @Test public void shouldSetPitClasspathAntReferenceOnJavaTask() throws Exception { final String classpath = "app.classpath"; final Object reference = "antReference"; when(this.project.getReference(classpath)).thenReturn(reference); this.pitestTask.setPitClasspath(classpath); this.pitestTask.execute(this.java); verify(this.java).setClasspath( argThat(new PathMatcher(reference.toString()))); } @Test public void shouldPassClasspathAntReferenceToPit() throws Exception { final String classpath = "app.classpath"; final Object reference = "antReference"; when(this.project.getReference(classpath)).thenReturn(reference); this.pitestTask.setClasspath(classpath); this.pitestTask.execute(this.java); verify(this.arg).setValue("--classPath=" + reference.toString()); } @Test public void shouldPassHistoryInputLocationToJavaTask() { this.pitestTask.setHistoryInputLocation("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--historyInputLocation=foo"); } @Test public void shouldPassHistoryOutputLocationToJavaTask() { this.pitestTask.setHistoryOutputLocation("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--historyOutputLocation=foo"); } @Test public void shouldIgnoreEmptyListOfExcludedClasses() { this.pitestTask.setExcludedClasses(""); this.pitestTask.execute(this.java); verify(this.arg, never()).setValue("--excludedClasses="); } @Test public void shouldPassMutationThresholdToJavaTask() { this.pitestTask.setMutationThreshold("42"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutationThreshold=42"); } @Test public void shouldPassMaxSurvivorsToJavaTask() { this.pitestTask.setMaxSurviving("42"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--maxSurviving=42"); } @Test public void shouldPassCoverageThresholdToJavaTask() { this.pitestTask.setCoverageThreshold("42"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--coverageThreshold=42"); } @Test public void shouldPassMutationEngineToJavaTask() { this.pitestTask.setMutationEngine("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--mutationEngine=foo"); } @Test public void shouldPassJVMToJavaTask() { this.pitestTask.setJVM("foo"); this.pitestTask.execute(this.java); verify(this.arg).setValue("--jvmPath=foo"); } private static class PathMatcher extends ArgumentMatcher<Path> { private final String[] expectedPaths; public PathMatcher(final String path) { this.expectedPaths = path.split(File.pathSeparator); } @Override public boolean matches(final Object argument) { final Path argPath = (Path) argument; final String[] paths = argPath.toString().split(File.pathSeparator); final boolean matches = paths.length == this.expectedPaths.length; if (matches) { for (final String expectedPathElement : this.expectedPaths) { if (isNotPresent(paths, expectedPathElement)) { return false; } } } return matches; } private boolean isNotPresent(final String[] paths, final String expectedPathElement) { final String element = normalizePath(expectedPathElement); for (final String pathElement : paths) { if (pathElement.endsWith(element)) { return false; } } return true; } private String normalizePath(final String expectedPathElement) { String element = expectedPathElement; element = element.replace("/", File.separator); element = element.replace("\\", File.separator); if (element.endsWith(File.separator)) { element = element.substring(0, element.length() - 1); } return element; } } }