private static MutationDetails makeCombinedMutant( final Collection<MutationDetails> value) { final MutationDetails first = value.iterator().next(); final Set<Integer> indexes = new HashSet<>(); mapTo(value, mutationToIndex(), indexes); final MutationIdentifier id = new MutationIdentifier(first.getId() .getLocation(), indexes, first.getId().getMutator()); return new MutationDetails(id, first.getFilename(), first.getDescription(), first.getLineNumber(), first.getBlock()); }
private void processMutation(final Reporter r, final TimeOutDecoratedTestSource testSource, final MutationDetails mutationDetails) throws IOException { final MutationIdentifier mutationId = mutationDetails.getId(); final Mutant mutatedClass = this.mutater.getMutation(mutationId); // For the benefit of mocking frameworks such as PowerMock // mess with the internals of Javassist so our mutated class // bytes are returned JavassistInterceptor.setMutant(mutatedClass); if (DEBUG) { LOG.fine("mutating method " + mutatedClass.getDetails().getMethod()); } final List<TestUnit> relevantTests = testSource .translateTests(mutationDetails.getTestsInOrder()); r.describe(mutationId); final MutationStatusTestPair mutationDetected = handleMutation( mutationDetails, mutatedClass, relevantTests); r.report(mutationId, mutationDetected); if (DEBUG) { LOG.fine("Mutation " + mutationId + " detected = " + mutationDetected); } }
@Override public void handleMutationResult(final ClassMutationResults metaData) { try { for (final MutationResult mutation : metaData.getMutations()) { this.out.write(makeCsv(mutation.getDetails().getFilename(), mutation .getDetails().getClassName().asJavaName(), mutation.getDetails() .getMutator(), mutation.getDetails().getMethod(), mutation .getDetails().getLineNumber(), mutation.getStatus(), createKillingTestDesc(mutation.getKillingTest())) + System.getProperty("line.separator")); } } catch (final IOException ex) { throw Unchecked.translateCheckedException(ex); } }
private static Predicate<MutationDetails> isKotlinJunkMutation() { return a -> a.getFilename().toLowerCase().endsWith(".kt") && (a.getLineNumber() == 0); } }
private static Function<MutationDetails, LineMutatorPair> toLineMutatorPair() { return a -> new LineMutatorPair(a.getLineNumber(), a.getMutator()); }
private String makeMutationNode(final MutationResult mutation) { final MutationDetails details = mutation.getDetails(); return makeNode(clean(details.getFilename()), sourceFile) + makeNode(clean(details.getClassName().asJavaName()), mutatedClass) + makeNode(clean(details.getMethod().name()), mutatedMethod) + makeNode(clean(details.getId().getLocation().getMethodDesc()), methodDescription) + makeNode("" + details.getLineNumber(), lineNumber) + makeNode(clean(details.getMutator()), mutator) + makeNode("" + details.getFirstIndex(), index) + makeNode("" + details.getBlock(), block) + makeNodeWhenConditionSatisfied(!fullMutationMatrix, createKillingTestDesc(mutation.getKillingTest()), killingTest) + makeNodeWhenConditionSatisfied(fullMutationMatrix, createTestDesc(mutation.getKillingTests()), killingTests) + makeNodeWhenConditionSatisfied(fullMutationMatrix, createTestDesc(mutation.getSucceedingTests()), succeedingTests) + makeNode(clean(details.getDescription()), description); }
public MutationDetails withDescription(String desc) { return new MutationDetails(this.id, this.filename, desc, this.lineNumber, this.block, this.isInFinallyBlock, this.poison); }
String method = details.getMethod().name(); String methodDescription = details.getId().getLocation().getMethodDesc(); report.writeAttribute("detected", status.isDetected()); report.writeAttribute("status", status.name()); report.writeAttribute("mutator", details.getMutator()); report.writeAttribute("class", details.getClassName().getNameWithoutPackage().asJavaName()); report.writeAttribute("package", details.getClassName().getPackage().asJavaName()); report.endObject(); details.getTestsInOrder()) { report.write(info.getName());
private List<MutationDetails> filter( List<MutationDetails> inEquals, Mutater m) { final Location equalsMethod = inEquals.get(0).getId().getLocation(); final Optional<MethodTree> maybeEquals = this.currentClass.methods().stream() .filter(MethodMatchers.forLocation(equalsMethod)) .findFirst(); return inEquals.stream() .filter(isShortcutEquals(maybeEquals.get(), m).negate()) .collect(Collectors.toList()); }
@Override public boolean test(MutationDetails a) { if (!MUTATOR_ID.equals(a.getMutator())) { return false; } final MethodTree method = NullReturnsFilter.this.currentClass.methods().stream() .filter(MethodMatchers.forLocation(a.getId().getLocation())) .findFirst() .get(); final int mutatedInstruction = a.getInstructionIndex(); return returnsNull(method, mutatedInstruction); }
private void initialize(MutationResult mutation) { mutationResults.add(mutation); location = mutation.getDetails().getId().getLocation(); classification = statusToClassification(mutation.getStatus()); fileName = mutation.getDetails().getFilename(); lineNumber = mutation.getDetails().getLineNumber(); }
public static String methodKey(MutationResult mutation) { String className = mutation.getDetails().getClassName().asJavaName(); String methodName = mutation.getDetails().getMethod().name(); String methodDescription = mutation.getDetails().getId().getLocation().getMethodDesc(); return className + "." + methodName + methodDescription; }
private static Function<MutationDetails, ClassName> byClass() { return a -> a.getClassName(); }
private static Comparator<MutationDetails> compareLineNumbers() { return (arg0, arg1) -> arg0.getLineNumber() - arg1.getLineNumber(); }
private static Predicate<MutationDetails> hasNoCoverage() { return a -> a.getTestsInOrder().isEmpty(); }
private Boolean shortCutEquals(MethodTree tree, MutationDetails a, Mutater m) { if (!mutatesAConditionalJump(tree, a.getInstructionIndex())) { return false; } final ClassTree mutant = ClassTree.fromBytes(m.getMutation(a.getId()).getBytes()); final MethodTree mutantEquals = mutant.methods().stream() .filter(MethodMatchers.forLocation(tree.asLocation())) .findFirst() .get(); return ALWAYS_FALSE.matches(mutantEquals.instructions()); }
public MutationDetails makeMutant(final String clazz, final int index) { final MutationIdentifier id = aMutationId() .withLocation(aLocation().withClass(ClassName.fromString(clazz))) .withIndex(index).withMutator("mutator").build(); final MutationDetails md = new MutationDetails(id, "sourceFile", "desc", 42, 0); when(this.mutater.getMutation(md.getId())).thenReturn( new Mutant(md, new byte[0])); return md; }
private MutationStatusTestPair handleCoveredMutation( final MutationDetails mutationId, final Mutant mutatedClass, final List<TestUnit> relevantTests) { final MutationStatusTestPair mutationDetected; if (DEBUG) { LOG.fine("" + relevantTests.size() + " relevant test for " + mutatedClass.getDetails().getMethod()); } final Container c = createNewContainer(); final long t0 = System.currentTimeMillis(); if (this.hotswap.apply(mutationId.getClassName(), this.loader, mutatedClass.getBytes())) { if (DEBUG) { LOG.fine("replaced class with mutant in " + (System.currentTimeMillis() - t0) + " ms"); } mutationDetected = doTestsDetectMutation(c, relevantTests); } else { LOG.warning("Mutation " + mutationId + " was not viable "); mutationDetected = MutationStatusTestPair.notAnalysed(0, DetectionStatus.NON_VIABLE); } return mutationDetected; }
private Collection<TestInfo> pickTests(MutationDetails mutation) { if (!mutation.isInStaticInitializer()) { return this.coverage.getTestsForClassLine(mutation.getClassLine()); } else { LOG.warning("Using untargetted tests"); return this.coverage.getTestsForClass(mutation.getClassName()); } }
private void assertOnlyClinitMethodsMarked(Collection<MutationDetails> actual) { for (final MutationDetails each : actual ) { if (each.isInStaticInitializer()) { if (!each.getId().getLocation().getMethodName().name().equals("<clinit>")) { fail("Expected no mutants to be marked as for static initialization but " + each + " was"); } } } }