/*
* Copyright 2011 Henry Coles
*
* 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.mutationtest.tooling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyCollection;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.pitest.classinfo.ClassByteArraySource;
import org.pitest.classinfo.ClassIdentifier;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassInfoMother;
import org.pitest.classinfo.ClassName;
import org.pitest.classinfo.HierarchicalClassId;
import org.pitest.classpath.CodeSource;
import org.pitest.coverage.CoverageDatabase;
import org.pitest.coverage.CoverageGenerator;
import org.pitest.functional.predicate.Predicate;
import org.pitest.help.Help;
import org.pitest.help.PitHelpError;
import org.pitest.mutationtest.HistoryStore;
import org.pitest.mutationtest.ListenerArguments;
import org.pitest.mutationtest.MutationEngineFactory;
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.MutationResultListenerFactory;
import org.pitest.mutationtest.config.PluginServices;
import org.pitest.mutationtest.config.ReportOptions;
import org.pitest.mutationtest.config.SettingsFactory;
import org.pitest.mutationtest.engine.Mutater;
import org.pitest.mutationtest.engine.MutationDetailsMother;
import org.pitest.mutationtest.engine.MutationEngine;
import org.pitest.mutationtest.engine.gregor.config.GregorEngineFactory;
import org.pitest.mutationtest.tooling.CombinedStatistics;
import org.pitest.mutationtest.tooling.MutationCoverage;
import org.pitest.mutationtest.tooling.MutationStrategies;
import org.pitest.mutationtest.verify.BuildVerifier;
import org.pitest.util.ResultOutputStrategy;
import org.pitest.util.Timings;
import org.pitest.util.Unchecked;
public class MutationCoverageReportTest {
private MutationCoverage testee;
private ReportOptions data;
@Mock
private MutationResultListenerFactory listenerFactory;
@Mock
private MutationResultListener listener;
@Mock
private CoverageDatabase coverageDb;
@Mock
private CoverageGenerator coverage;
@Mock
private CodeSource code;
@Mock
private HistoryStore history;
@Mock
private MutationEngineFactory mutationFactory;
@Mock
private BuildVerifier verifier;
@Mock
private MutationEngine engine;
@Mock
private Mutater mutater;
@Mock
private ResultOutputStrategy output;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.data = new ReportOptions();
this.data.setSourceDirs(Collections.<File> emptyList());
when(this.coverage.calculateCoverage()).thenReturn(this.coverageDb);
when(
this.listenerFactory.getListener(Matchers.<Properties> any(),
any(ListenerArguments.class))).thenReturn(this.listener);
mockMutationEngine();
}
@SuppressWarnings("unchecked")
private void mockMutationEngine() {
when(
this.mutationFactory.createEngine(anyBoolean(), any(Predicate.class),
anyCollection(), anyCollection(), anyBoolean())).thenReturn(
this.engine);
when(this.engine.createMutator(any(ClassByteArraySource.class)))
.thenReturn(this.mutater);
}
@Test
public void shouldReportErrorWhenNoMutationsFoundAndFlagSet() {
try {
this.data.setFailWhenNoMutations(true);
createAndRunTestee();
} catch (final PitHelpError phe) {
assertEquals(Help.NO_MUTATIONS_FOUND.toString(), phe.getMessage());
}
}
@Test
public void shouldNotReportErrorWhenNoMutationsFoundAndFlagNotSet() {
try {
this.data.setFailWhenNoMutations(false);
createAndRunTestee();
} catch (final PitHelpError phe) {
fail();
}
}
@SuppressWarnings("unchecked")
@Test
public void shouldRecordClassPath() {
final HierarchicalClassId fooId = new HierarchicalClassId(
new ClassIdentifier(0, ClassName.fromString("foo")), "0");
final ClassInfo foo = ClassInfoMother.make(fooId.getId());
when(this.code.getCodeUnderTestNames()).thenReturn(
Collections.singleton(ClassName.fromString("foo")));
when(this.code.getClassInfo(any(List.class))).thenReturn(
Collections.singletonList(foo));
createAndRunTestee();
verify(this.history).recordClassPath(Arrays.asList(fooId), this.coverageDb);
}
@Test
public void shouldCheckBuildSuitableForMutationTesting() {
createAndRunTestee();
verify(this.verifier).verify(any(CodeSource.class));
}
@Test
public void shouldReportNoMutationsFoundWhenNoneDetected() {
this.data.setFailWhenNoMutations(false);
final CombinedStatistics actual = createAndRunTestee();
assertEquals(0, actual.getMutationStatistics().getTotalMutations());
}
@Test
public void shouldReportMutationsFoundWhenSomeDetected() {
this.data.setFailWhenNoMutations(false);
final ClassName foo = ClassName.fromString("foo");
when(this.mutater.findMutations(foo)).thenReturn(
MutationDetailsMother.aMutationDetail().build(1));
when(this.code.getCodeUnderTestNames()).thenReturn(
Collections.singleton(foo));
final CombinedStatistics actual = createAndRunTestee();
assertEquals(1, actual.getMutationStatistics().getTotalMutations());
}
private CombinedStatistics createAndRunTestee() {
final MutationStrategies strategies = new MutationStrategies(
new GregorEngineFactory(), this.history, this.coverage,
this.listenerFactory, this.output).with(this.mutationFactory).with(
this.verifier);
this.testee = new MutationCoverage(strategies, null, this.code, this.data,
new SettingsFactory(this.data, PluginServices.makeForContextLoader()),
new Timings());
try {
return this.testee.runReport();
} catch (final IOException e) {
throw Unchecked.translateCheckedException(e);
}
}
}