Skip to content

Commit

Permalink
Merge pull request #983 from therealryan/mergeup
Browse files Browse the repository at this point in the history
Mergeup of #625
  • Loading branch information
hcoles authored Feb 3, 2022
2 parents 5fd9bf3 + 888be38 commit 90d5df5
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 165 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package org.pitest.aggregate;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.pitest.classinfo.ClassName;
import org.pitest.coverage.BlockCoverage;
Expand All @@ -11,10 +21,13 @@

class BlockCoverageDataLoader extends DataLoader<BlockCoverage> {

private static final String BLOCK = "block";
private static final String TESTS = "tests";
private static final String TEST = "test";
private static final String NAME = "name";
private static final String METHOD = "method";
private static final String CLASSNAME = "classname";
private static final String NUMBER = "number";
private static final String TESTS = "tests";
private static final String FIRST_INSN = "firstInstruction";
private static final String LAST_INSN = "lastInstruction";

Expand All @@ -23,20 +36,61 @@ class BlockCoverageDataLoader extends DataLoader<BlockCoverage> {
BlockCoverageDataLoader(final Collection<File> filesToLoad) {
super(filesToLoad);
}

@Override
protected BlockCoverage mapToData(final Map<String, Object> map) {
final String method = (String) map.get(METHOD);
final Location location = new Location(ClassName.fromString((String) map.get(CLASSNAME)),
method.substring(0, method.indexOf(OPEN_PAREN)), method.substring(method.indexOf(OPEN_PAREN)));
protected Set<BlockCoverage> mapToData(XMLEventReader doc) throws XMLStreamException {
final Set<BlockCoverage> data = new HashSet<>();
List<String> tests = new ArrayList<>();
StartElement enclosingNode = null;
BlockLocation block = null;
while (doc.hasNext()) {
XMLEvent next = doc.peek();
if (next.isStartElement()) {
enclosingNode = next.asStartElement();
String nodeName = next.asStartElement().getName().getLocalPart();
if (nodeName.equals(BLOCK)) {
block = toBlockLocation(enclosingNode);
}
if (nodeName.equals(TESTS)) {
tests = new ArrayList<>();
}
if (nodeName.equals(TEST)) {
tests.add(getAttributeValue(enclosingNode, NAME));
}
}
if (next.isEndElement()) {
String nodeName = next.asEndElement().getName().getLocalPart();
if (nodeName.equals(BLOCK)) {
data.add(new BlockCoverage(block, tests.isEmpty() ? null : tests));
}
}
doc.next();
}
return data;
}

final BlockLocation blockLocation = new BlockLocation(location, Integer.parseInt((String) map.get(NUMBER)),
Integer.parseInt((String) map.get(FIRST_INSN)),Integer.parseInt((String) map.get(LAST_INSN)));
private BlockLocation toBlockLocation(StartElement enclosingNode) {
BlockLocation block;
ClassName className = ClassName.fromString(getAttributeValue(enclosingNode, CLASSNAME));
String method = getAttributeValue(enclosingNode, METHOD);
String methodName = method.substring(0, method.indexOf(OPEN_PAREN));
int blockNum = getAttributeValueAsInt(enclosingNode, NUMBER);
int firstInstruction = getAttributeValueAsInt(enclosingNode, FIRST_INSN);
int lastInstruction = getAttributeValueAsInt(enclosingNode, LAST_INSN);
String methodDesc = method.substring(method.indexOf(OPEN_PAREN));
Location location = new Location(className, methodName, methodDesc);
block = new BlockLocation(location, blockNum, firstInstruction, lastInstruction);
return block;
}

@SuppressWarnings("unchecked")
final Collection<String> tests = (Collection<String>) map.get(TESTS);
private String getAttributeValue(StartElement enclosingNode, String attributeName) {
Attribute attribute = enclosingNode.getAttributeByName(QName.valueOf(attributeName));
return attribute == null ? null : attribute.getValue();
}

return new BlockCoverage(blockLocation, tests);
private int getAttributeValueAsInt(StartElement enclosingNode, String attributeName) {
String value = getAttributeValue(enclosingNode, attributeName);
return value == null ? 0 : Integer.parseInt(value);
}

}
113 changes: 19 additions & 94 deletions pitest-aggregator/src/main/java/org/pitest/aggregate/DataLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,17 @@
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;

abstract class DataLoader<T> {

Expand All @@ -47,100 +38,34 @@ public Set<T> loadData() throws ReportAggregationException {
return data;
}

protected abstract T mapToData(Map<String, Object> map);
protected abstract Set<T> mapToData(XMLEventReader doc) throws XMLStreamException;

Set<T> loadData(final File dataLocation) throws ReportAggregationException {
if (!dataLocation.exists() || !dataLocation.isFile()) {
throw new ReportAggregationException(dataLocation.getAbsolutePath() + " does not exist or is not a file");
}
final Set<T> data = new HashSet<>();
try {
final InputStream inputStream = new BufferedInputStream(new FileInputStream(dataLocation));

final Document doc = readDocument(inputStream);

final Node docNode = doc.getFirstChild();
final NodeList nodeList = docNode.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
final Node itemNode = nodeList.item(i);
if (itemNode.getNodeType() == Node.ELEMENT_NODE) {
data.add(mapToData(nodeMap(itemNode)));
}
}
return data;
} catch (final IOException e) {
return loadData(new BufferedInputStream(new FileInputStream(dataLocation)), dataLocation);
} catch (FileNotFoundException e) {
throw new ReportAggregationException("Could not read file: " + dataLocation.getAbsolutePath(), e);
}
}

/**
* Reads the input stream into a document and closes the input stream when
* finished.
*/
static Document readDocument(final InputStream inputStream) throws ReportAggregationException {
DocumentBuilder docBuilder;

Set<T> loadData(final InputStream inputStream, final File dataLocation) throws ReportAggregationException {
try {
docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
return docBuilder.parse(inputStream);
} catch (final IOException | SAXException | ParserConfigurationException e) {
throw new ReportAggregationException(e.getMessage(), e);
final XMLEventReader doc = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
return mapToData(doc);
} catch (final XMLStreamException e) {
throw new ReportAggregationException("Could not parse file: " + dataLocation.getAbsolutePath(), e);
} finally {
try {
inputStream.close();
} catch (final IOException e) {
throw new ReportAggregationException(CANNOT_CLOSE_ERR, e);
}
}
}

// converts the contents of a node into a map
static Map<String, Object> nodeMap(final Node node) {
final HashMap<String, Object> map = new HashMap<>();

final NamedNodeMap attrs = node.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
final Node attr = attrs.item(i);
final String tc = attr.getTextContent().trim();

if (!tc.isEmpty()) {
map.put(attr.getNodeName(), tc);
}
}

final NodeList children = node.getChildNodes();

for (int i = 0; i < children.getLength(); i++) {
final Node child = children.item(i);

if (child.getNodeType() == Node.ELEMENT_NODE) {
final String tc = child.getTextContent().trim();
if (!tc.isEmpty()) {
map.put(child.getNodeName(), tc);
} else {
// may have test nodes
final List<String> tests = new ArrayList<>();
final NodeList testNodeList = child.getChildNodes();
for (int j = 0; j < testNodeList.getLength(); j++) {
final Node testNode = testNodeList.item(j);
if (testNode.getNodeType() == Node.ELEMENT_NODE) {
final NamedNodeMap testAttrs = testNode.getAttributes();
for (int k = 0; k < testAttrs.getLength(); k++) {
final Node attr = testAttrs.item(k);
final String tn = attr.getTextContent().trim();

if (!tn.isEmpty()) {
tests.add(tn);
}
}
}
}
if (!tests.isEmpty()) {
map.put(child.getNodeName(), tests);
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new ReportAggregationException(CANNOT_CLOSE_ERR, e);
}
}
}

return map;
}

}
Loading

0 comments on commit 90d5df5

Please sign in to comment.