package org.pitest.mutationtest.incremental;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.pitest.mutationtest.LocationMother.aMutationId;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.pitest.classinfo.ClassIdentifier;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassInfoMother;
import org.pitest.classinfo.ClassInfoSource;
import org.pitest.classinfo.ClassName;
import org.pitest.classinfo.HierarchicalClassId;
import org.pitest.functional.Option;
import org.pitest.mutationtest.ClassHistory;
import org.pitest.mutationtest.DetectionStatus;
import org.pitest.mutationtest.MutationStatusTestPair;
import org.pitest.mutationtest.engine.MutationIdentifier;
public class DefaultCodeHistoryTest {
private DefaultCodeHistory testee;
@Mock
private ClassInfoSource classInfoSource;
private final Map<ClassName, ClassHistory> historicClassPath = new HashMap<ClassName, ClassHistory>();
private final Map<MutationIdentifier, MutationStatusTestPair> results = new HashMap<MutationIdentifier, MutationStatusTestPair>();
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.testee = new DefaultCodeHistory(this.classInfoSource, this.results,
this.historicClassPath);
}
@Test
public void shouldReturnNoneWhenNoMatchingHistoricResultExists() {
final MutationIdentifier id = aMutationId().build();
final Option<MutationStatusTestPair> actual = this.testee
.getPreviousResult(id);
assertEquals(Option.none(), actual);
}
@Test
public void shouldReturnHistoricResultWhenOneExists() {
final MutationIdentifier id = aMutationId().build();
final MutationStatusTestPair expected = new MutationStatusTestPair(0,
DetectionStatus.KILLED, "foo");
this.results.put(id, expected);
final Option<MutationStatusTestPair> actual = this.testee
.getPreviousResult(id);
assertEquals(Option.some(expected), actual);
}
@Test
public void shouldTreatNewClassAsChanged() {
assertTrue(this.testee
.hasClassChanged(ClassName.fromString("notInLastRun")));
}
@Test
public void shouldTreatClassesWithDifferentHashesAsChanged() {
final long currentHash = 42;
final ClassName foo = ClassName.fromString("foo");
final ClassIdentifier currentId = new ClassIdentifier(currentHash, foo);
setCurrentClassPath(ClassInfoMother.make(currentId));
this.historicClassPath.put(foo, makeHistory(new HierarchicalClassId(
currentHash + 1, foo, "0")));
assertTrue(this.testee.hasClassChanged(ClassName.fromString("foo")));
}
@Test
public void shouldTreatClassesWithModifiedParentAsChanged() {
final long currentHash = 42;
final ClassName foo = ClassName.fromString("foo");
final ClassInfo parent = ClassInfoMother.make("parent");
final ClassIdentifier currentId = new ClassIdentifier(currentHash, foo);
final ClassInfo currentFoo = ClassInfoMother.make(currentId, parent);
final ClassInfo modifiedParent = ClassInfoMother.make(new ClassIdentifier(
parent.getHash().longValue() + 1, ClassName.fromString("parent")));
final ClassInfo modifiedFoo = ClassInfoMother.make(currentId,
modifiedParent);
setCurrentClassPath(currentFoo);
this.historicClassPath.put(foo, makeHistory(modifiedFoo));
assertTrue(this.testee.hasClassChanged(foo));
}
@Test
public void shouldTreatClassesWithSameHashAsUnChanged() {
final ClassName foo = ClassName.fromString("foo");
final HierarchicalClassId currentId = new HierarchicalClassId(0, foo, "0");
setCurrentClassPath(currentId);
this.historicClassPath.put(foo, makeHistory(currentId));
assertFalse(this.testee.hasClassChanged(ClassName.fromString("foo")));
}
private void setCurrentClassPath(final HierarchicalClassId currentId) {
final ClassInfo currentClass = ClassInfoMother.make(currentId.getId());
when(this.classInfoSource.fetchClass(ClassName.fromString("foo")))
.thenReturn(Option.some(currentClass));
}
private void setCurrentClassPath(final ClassInfo info) {
when(this.classInfoSource.fetchClass(ClassName.fromString("foo")))
.thenReturn(Option.some(info));
}
private ClassHistory makeHistory(final HierarchicalClassId id) {
return new ClassHistory(id, "");
}
private ClassHistory makeHistory(final ClassInfo ci) {
return makeHistory(ci.getHierarchicalId());
}
}