diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-25 00:16:09 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-25 07:44:16 +0100 |
commit | d4beaec49895945d23d509d1502790794b008d56 (patch) | |
tree | e10aef01542a6de8a4b00b985870dfdcdbc3a700 /plugins/sonar-cobertura-plugin | |
parent | 2dc09dd0800e0fca575133775e4b97dc5f711104 (diff) | |
download | sonarqube-d4beaec49895945d23d509d1502790794b008d56.tar.gz sonarqube-d4beaec49895945d23d509d1502790794b008d56.zip |
SONAR-2218 Add CoverageMeasuresBuilder to API + add Metric.Builder, first step to get an immutable Metric class
Diffstat (limited to 'plugins/sonar-cobertura-plugin')
2 files changed, 47 insertions, 128 deletions
diff --git a/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/api/AbstractCoberturaParser.java b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/api/AbstractCoberturaParser.java index bd095688fb0..3507795e693 100644 --- a/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/api/AbstractCoberturaParser.java +++ b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/api/AbstractCoberturaParser.java @@ -19,36 +19,31 @@ */ package org.sonar.plugins.cobertura.api; -import static java.util.Locale.ENGLISH; -import static org.sonar.api.utils.ParsingUtils.parseNumber; -import static org.sonar.api.utils.ParsingUtils.scaleValue; - +import com.google.common.collect.Maps; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.batch.SensorContext; -import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.CoverageMeasuresBuilder; import org.sonar.api.measures.Measure; -import org.sonar.api.measures.PersistenceMode; -import org.sonar.api.measures.PropertiesBuilder; import org.sonar.api.resources.Resource; import org.sonar.api.utils.StaxParser; import org.sonar.api.utils.XmlParserException; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import java.util.Map; -import javax.xml.stream.XMLStreamException; +import static java.util.Locale.ENGLISH; +import static org.sonar.api.utils.ParsingUtils.parseNumber; /** * @since 2.4 */ public abstract class AbstractCoberturaParser { + public void parseReport(File xmlFile, final SensorContext context) { try { StaxParser parser = new StaxParser(new StaxParser.XmlStreamHandler() { @@ -70,110 +65,57 @@ public abstract class AbstractCoberturaParser { private void collectPackageMeasures(SMInputCursor pack, SensorContext context) throws ParseException, XMLStreamException { while (pack.getNext() != null) { - Map<String, FileData> fileDataPerFilename = new HashMap<String, FileData>(); - collectFileMeasures(pack.descendantElementCursor("class"), fileDataPerFilename); - for (FileData cci : fileDataPerFilename.values()) { - if (isFileExist(context, cci.getFile())) { - for (Measure measure : cci.getMeasures()) { - context.saveMeasure(cci.getFile(), measure); + Map<String, CoverageMeasuresBuilder> builderByFilename = Maps.newHashMap(); + collectFileMeasures(pack.descendantElementCursor("class"), builderByFilename); + for (Map.Entry<String, CoverageMeasuresBuilder> entry : builderByFilename.entrySet()) { + String filename = sanitizeFilename(entry.getKey()); + Resource file = getResource(filename); + if (fileExists(context, file)) { + for (Measure measure : entry.getValue().createMeasures()) { + System.out.println(file + " -> " + measure); + context.saveMeasure(file, measure); } } } } } - private boolean isFileExist(SensorContext context, Resource<?> file) { + private boolean fileExists(SensorContext context, Resource file) { return context.getResource(file) != null; } - private void collectFileMeasures(SMInputCursor clazz, Map<String, FileData> dataPerFilename) throws ParseException, XMLStreamException { + private void collectFileMeasures(SMInputCursor clazz, Map<String, CoverageMeasuresBuilder> builderByFilename) throws ParseException, XMLStreamException { while (clazz.getNext() != null) { - String fileName = FilenameUtils.removeExtension(clazz.getAttrValue("filename")); - fileName = fileName.replace('/', '.').replace('\\', '.'); - FileData data = dataPerFilename.get(fileName); - if (data == null) { - data = new FileData(getResource(fileName)); - dataPerFilename.put(fileName, data); + String fileName = clazz.getAttrValue("filename"); + CoverageMeasuresBuilder builder = builderByFilename.get(fileName); + if (builder==null) { + builder = CoverageMeasuresBuilder.create(); + builderByFilename.put(fileName, builder); } - collectFileData(clazz, data); + collectFileData(clazz, builder); } } - private void collectFileData(SMInputCursor clazz, FileData data) throws ParseException, XMLStreamException { + private void collectFileData(SMInputCursor clazz, CoverageMeasuresBuilder builder) throws ParseException, XMLStreamException { SMInputCursor line = clazz.childElementCursor("lines").advance().childElementCursor("line"); while (line.getNext() != null) { - String lineId = line.getAttrValue("number"); - data.addLine(lineId, (int) parseNumber(line.getAttrValue("hits"), ENGLISH)); + int lineId = Integer.parseInt(line.getAttrValue("number")); + builder.setHits(lineId, (int) parseNumber(line.getAttrValue("hits"), ENGLISH)); String isBranch = line.getAttrValue("branch"); String text = line.getAttrValue("condition-coverage"); if (StringUtils.equals(isBranch, "true") && StringUtils.isNotBlank(text)) { String[] conditions = StringUtils.split(StringUtils.substringBetween(text, "(", ")"), "/"); - data.addConditionLine(lineId, Integer.parseInt(conditions[0]), Integer.parseInt(conditions[1]), StringUtils.substringBefore(text, " ")); - } - } - } - - private class FileData { - - private int lines = 0; - private int conditions = 0; - private int coveredLines = 0; - private int coveredConditions = 0; - - private Resource<?> file; - private PropertiesBuilder<String, Integer> lineHitsBuilder = new PropertiesBuilder<String, Integer>(CoreMetrics.COVERAGE_LINE_HITS_DATA); - private PropertiesBuilder<String, String> branchHitsBuilder = new PropertiesBuilder<String, String>(CoreMetrics.BRANCH_COVERAGE_HITS_DATA); - - public void addLine(String lineId, int lineHits) { - lines++; - if (lineHits > 0) { - coveredLines++; - } - lineHitsBuilder.add(lineId, lineHits); - } - - public void addConditionLine(String lineId, int coveredConditions, int conditions, String label) { - this.conditions += conditions; - this.coveredConditions += coveredConditions; - branchHitsBuilder.add(lineId, label); - } - - public FileData(Resource<?> file) { - this.file = file; - } - - public List<Measure> getMeasures() { - List<Measure> measures = new ArrayList<Measure>(); - if (lines > 0) { - measures.add(new Measure(CoreMetrics.COVERAGE, calculateCoverage(coveredLines + coveredConditions, lines + conditions))); - - measures.add(new Measure(CoreMetrics.LINE_COVERAGE, calculateCoverage(coveredLines, lines))); - measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines)); - measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) lines - coveredLines)); - measures.add(lineHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); - - if (conditions > 0) { - measures.add(new Measure(CoreMetrics.BRANCH_COVERAGE, calculateCoverage(coveredConditions, conditions))); - measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions)); - measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) conditions - coveredConditions)); - measures.add(branchHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); - } + builder.setConditions(lineId, Integer.parseInt(conditions[1]), Integer.parseInt(conditions[0])); } - return measures; - } - - public Resource<?> getFile() { - return file; } } - private double calculateCoverage(int coveredElements, int elements) { - if (elements > 0) { - return scaleValue(100.0 * ((double) coveredElements / (double) elements)); - } - return 0.0; + private String sanitizeFilename(String s) { + String fileName = FilenameUtils.removeExtension(s); + fileName = fileName.replace('/', '.').replace('\\', '.'); + return fileName; } - protected abstract Resource<?> getResource(String fileName); + protected abstract Resource getResource(String fileName); } diff --git a/plugins/sonar-cobertura-plugin/src/test/java/org/sonar/plugins/cobertura/CoberturaSensorTest.java b/plugins/sonar-cobertura-plugin/src/test/java/org/sonar/plugins/cobertura/CoberturaSensorTest.java index 0b57c57523c..8b5c57f7e3f 100644 --- a/plugins/sonar-cobertura-plugin/src/test/java/org/sonar/plugins/cobertura/CoberturaSensorTest.java +++ b/plugins/sonar-cobertura-plugin/src/test/java/org/sonar/plugins/cobertura/CoberturaSensorTest.java @@ -23,9 +23,7 @@ import org.junit.Test; import org.sonar.api.batch.SensorContext; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; -import org.sonar.api.resources.JavaFile; -import org.sonar.api.resources.JavaPackage; -import org.sonar.api.resources.Resource; +import org.sonar.api.resources.*; import org.sonar.api.test.IsMeasure; import org.sonar.api.test.IsResource; @@ -37,10 +35,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyDouble; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class CoberturaSensorTest { @@ -103,7 +98,6 @@ public class CoberturaSensorTest { new CoberturaSensor().parseReport(getCoverageReport(), context); final JavaFile file = new JavaFile("org.apache.commons.chain.config.ConfigParser"); - // verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.LINE_COVERAGE, 83.3))); verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.LINES_TO_COVER, 30.0))); verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.UNCOVERED_LINES, 5.0))); } @@ -115,7 +109,6 @@ public class CoberturaSensorTest { new CoberturaSensor().parseReport(getCoverageReport(), context); final JavaFile file = new JavaFile("org.apache.commons.chain.config.ConfigParser"); - verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.BRANCH_COVERAGE, 66.7))); verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.CONDITIONS_TO_COVER, 6.0))); verify(context).saveMeasure(eq(file), argThat(new IsMeasure(CoreMetrics.UNCOVERED_CONDITIONS, 2.0))); } @@ -153,56 +146,40 @@ public class CoberturaSensorTest { when(context.getResource(any(Resource.class))).thenReturn(new JavaFile("org.sonar.MyClass")); new CoberturaSensor().parseReport(coverage, context); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), - argThat(new IsMeasure(CoreMetrics.LINE_COVERAGE, 37.1))); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), + verify(context).saveMeasure(argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass")), argThat(new IsMeasure(CoreMetrics.LINES_TO_COVER, 35.0))); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), + verify(context).saveMeasure(argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_LINES, 22.0))); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), - argThat(new IsMeasure(CoreMetrics.BRANCH_COVERAGE, 25.0))); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), + verify(context).saveMeasure(argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass")), argThat(new IsMeasure(CoreMetrics.CONDITIONS_TO_COVER, 4.0))); - verify(context).saveMeasure(argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass")), + verify(context).saveMeasure(argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_CONDITIONS, 3.0))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), - argThat(new IsMeasure(CoreMetrics.LINE_COVERAGE))); - verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), - argThat(new IsMeasure(CoreMetrics.BRANCH_COVERAGE))); - verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), argThat(new IsMeasure(CoreMetrics.LINES_TO_COVER))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), argThat(new IsMeasure(CoreMetrics.CONDITIONS_TO_COVER))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_CONDITIONS))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.InnerClass$InnerClassInside")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_LINES))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), - argThat(new IsMeasure(CoreMetrics.LINE_COVERAGE))); - verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), - argThat(new IsMeasure(CoreMetrics.BRANCH_COVERAGE))); - verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.PrivateClass")), argThat(new IsMeasure(CoreMetrics.LINES_TO_COVER))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.PrivateClass")), argThat(new IsMeasure(CoreMetrics.CONDITIONS_TO_COVER))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.PrivateClass")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_CONDITIONS))); verify(context, never()).saveMeasure( - argThat(new IsResource(Resource.SCOPE_ENTITY, Resource.QUALIFIER_CLASS, "org.sonar.samples.PrivateClass")), + argThat(new IsResource(Scopes.FILE, Qualifiers.CLASS, "org.sonar.samples.PrivateClass")), argThat(new IsMeasure(CoreMetrics.UNCOVERED_LINES))); verify(context) @@ -221,7 +198,7 @@ public class CoberturaSensorTest { verify(context).saveMeasure( eq(new JavaFile("org.apache.commons.chain.impl.CatalogBase")), argThat(new IsMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA, - "111=18;121=0;122=0;125=0;126=0;127=0;128=0;131=0;133=0;48=117;56=234;66=0;67=0;68=0;84=999;86=999;98=318"))); + "48=117;56=234;66=0;67=0;68=0;84=999;86=999;98=318;111=18;121=0;122=0;125=0;126=0;127=0;128=0;131=0;133=0"))); } @Test |