From 9a98ba2467eae486dbac58831b53744cd96aa131 Mon Sep 17 00:00:00 2001 From: Michael Klein Date: Mon, 10 Nov 2014 13:30:30 +0100 Subject: [PATCH] Implement Surefire directly into the plugin remove old Surefire dependency --- pom.xml | 6 - .../scala/surefire/ScalaSurefireParser.java | 165 ++++++++++++++++++ .../scala/surefire/SurefireSensor.java | 28 +-- .../scala/surefire/SurefireStaxHandler.java | 112 ++++++++++++ .../plugins/scala/surefire/SurefireUtils.java | 72 ++++++++ .../scala/surefire/UnitTestClassReport.java | 93 ++++++++++ .../plugins/scala/surefire/UnitTestIndex.java | 50 ++++++ .../scala/surefire/UnitTestResult.java | 107 ++++++++++++ .../scala/surefire/SurefireSensorTest.java | 45 ++--- 9 files changed, 618 insertions(+), 60 deletions(-) create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/ScalaSurefireParser.java create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/SurefireStaxHandler.java create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/SurefireUtils.java create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/UnitTestClassReport.java create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/UnitTestIndex.java create mode 100644 src/main/java/org/sonar/plugins/scala/surefire/UnitTestResult.java diff --git a/pom.xml b/pom.xml index e155b5d..6450aea 100644 --- a/pom.xml +++ b/pom.xml @@ -55,12 +55,6 @@ sonar-plugin-api ${sonar.version} - - org.codehaus.sonar-plugins.java - sonar-surefire-plugin - 2.3 - provided - org.codehaus.sonar-plugins.java sonar-java-plugin diff --git a/src/main/java/org/sonar/plugins/scala/surefire/ScalaSurefireParser.java b/src/main/java/org/sonar/plugins/scala/surefire/ScalaSurefireParser.java new file mode 100644 index 0000000..1a21046 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/ScalaSurefireParser.java @@ -0,0 +1,165 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Map; + +import javax.xml.stream.XMLStreamException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.ParsingUtils; +import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.StaxParser; + +public class ScalaSurefireParser { + + private static final Logger LOG = LoggerFactory.getLogger(ScalaSurefireParser.class); + private final FileSystem fileSystem; + + public ScalaSurefireParser(FileSystem fileSystem){ + this.fileSystem = fileSystem; + } + + public void collect(Project project, SensorContext context, File reportsDir) { + File[] xmlFiles = getReports(reportsDir); + + if (xmlFiles.length == 0) { + // See http://jira.codehaus.org/browse/SONAR-2371 + if (project.getModules().isEmpty()) { + context.saveMeasure(CoreMetrics.TESTS, 0.0); + } + } else { + parseFiles(context, xmlFiles); + } + } + + private File[] getReports(File dir) { + if (dir == null) { + return new File[0]; + } else if (!dir.isDirectory()) { + LOG.warn("Reports path not found: " + dir.getAbsolutePath()); + return new File[0]; + } + File[] unitTestResultFiles = findXMLFilesStartingWith(dir, "TEST-"); + if (unitTestResultFiles.length == 0) { + // maybe there's only a test suite result file + unitTestResultFiles = findXMLFilesStartingWith(dir, "TESTS-"); + } + return unitTestResultFiles; + } + + private File[] findXMLFilesStartingWith(File dir, final String fileNameStart) { + return dir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith(fileNameStart) && name.endsWith(".xml"); + } + }); + } + + private void parseFiles(SensorContext context, File[] reports) { + UnitTestIndex index = new UnitTestIndex(); + parseFiles(reports, index); + save(index, context); + } + + private void parseFiles(File[] reports, UnitTestIndex index) { + SurefireStaxHandler staxParser = new SurefireStaxHandler(index); + StaxParser parser = new StaxParser(staxParser, false); + for (File report : reports) { + try { + parser.parse(report); + } catch (XMLStreamException e) { + throw new SonarException("Fail to parse the Surefire report: " + report, e); + } + } + } + + private void save(UnitTestIndex index, SensorContext context) { + long negativeTimeTestNumber = 0; + for (Map.Entry entry : index.getIndexByClassname().entrySet()) { + UnitTestClassReport report = entry.getValue(); + if (report.getTests() > 0) { + negativeTimeTestNumber += report.getNegativeTimeTestNumber(); + InputFile resource = getUnitTestResource(entry.getKey()); + if (resource != null) { + save(report, resource, context); + } else { + LOG.warn("Resource not found: {}", entry.getKey()); + } + } + } + if (negativeTimeTestNumber > 0) { + LOG.warn("There is {} test(s) reported with negative time by surefire, total duration may not be accurate.", negativeTimeTestNumber); + } + } + + private void save(UnitTestClassReport report, InputFile resource, SensorContext context) { + double testsCount = report.getTests() - report.getSkipped(); + saveMeasure(context, resource, CoreMetrics.SKIPPED_TESTS, report.getSkipped()); + saveMeasure(context, resource, CoreMetrics.TESTS, testsCount); + saveMeasure(context, resource, CoreMetrics.TEST_ERRORS, report.getErrors()); + saveMeasure(context, resource, CoreMetrics.TEST_FAILURES, report.getFailures()); + saveMeasure(context, resource, CoreMetrics.TEST_EXECUTION_TIME, report.getDurationMilliseconds()); + double passedTests = testsCount - report.getErrors() - report.getFailures(); + if (testsCount > 0) { + double percentage = passedTests * 100d / testsCount; + saveMeasure(context, resource, CoreMetrics.TEST_SUCCESS_DENSITY, ParsingUtils.scaleValue(percentage)); + } + saveResults(context, resource, report); + } + + private void saveMeasure(SensorContext context, InputFile resource, Metric metric, double value) { + if (!Double.isNaN(value)) { + context.saveMeasure(resource, metric, value); + } + } + + private void saveResults(SensorContext context, InputFile resource, UnitTestClassReport report) { + context.saveMeasure(resource, new Measure(CoreMetrics.TEST_DATA, report.toXml())); + } + + private InputFile getUnitTestResource(String classKey){ + String filename = classKey.replace('.', '/') + ".scala"; + FilePredicates filePredicates = fileSystem.predicates(); + + return fileSystem.inputFile(filePredicates. matchesPathPattern("**/*" + filename)); + } + +// for(InputFile inputFile : inputFiles){ +////System.out.println("inputFile: " + inputFile.absolutePath()); +////System.out.println("filename: " + filename); +//if (inputFile.absolutePath().endsWith(filename)){ +// return inputFile; +//} +//} + +} diff --git a/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java b/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java index 1d6812e..d992a2e 100644 --- a/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java +++ b/src/main/java/org/sonar/plugins/scala/surefire/SurefireSensor.java @@ -19,39 +19,37 @@ */ package org.sonar.plugins.scala.surefire; +import java.io.File; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.CoreProperties; import org.sonar.api.batch.CoverageExtension; import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; import org.sonar.plugins.scala.language.Scala; -import org.sonar.plugins.surefire.api.AbstractSurefireParser; -import org.sonar.plugins.surefire.api.SurefireUtils; - -import java.io.File; public class SurefireSensor implements Sensor { private static final Logger LOG = LoggerFactory.getLogger(SurefireSensor.class); private final Settings settings; + private final FileSystem fileSystem; @DependsUpon public Class dependsUponCoverageSensors() { return CoverageExtension.class; } - public SurefireSensor (Settings settings){ + public SurefireSensor (Settings settings, FileSystem fileSystem){ this.settings = settings; + this.fileSystem = fileSystem; } public boolean shouldExecuteOnProject(Project project) { - return project.getAnalysisType().isDynamic(true) && Scala.KEY.equals(project.getLanguageKey()); + return fileSystem.hasFiles(fileSystem.predicates().hasLanguage(Scala.KEY)); } public void analyse(Project project, SensorContext context) { @@ -61,19 +59,9 @@ public void analyse(Project project, SensorContext context) { protected void collect(Project project, SensorContext context, File reportsDir) { LOG.info("parsing {}", reportsDir); - SUREFIRE_PARSER.collect(project, context, reportsDir); + new ScalaSurefireParser(fileSystem).collect(project, context, reportsDir); } - private static final AbstractSurefireParser SUREFIRE_PARSER = new AbstractSurefireParser() { - @Override - protected Resource getUnitTestResource(String classKey) { - String filename = classKey.replace('.', '/') + ".scala"; - org.sonar.api.resources.File sonarFile = new org.sonar.api.resources.File(filename); - sonarFile.setQualifier(Qualifiers.UNIT_TEST_FILE); - return sonarFile; - } - }; - @Override public String toString() { return "Scala SurefireSensor"; diff --git a/src/main/java/org/sonar/plugins/scala/surefire/SurefireStaxHandler.java b/src/main/java/org/sonar/plugins/scala/surefire/SurefireStaxHandler.java new file mode 100644 index 0000000..4a78677 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/SurefireStaxHandler.java @@ -0,0 +1,112 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import org.codehaus.staxmate.in.ElementFilter; +import org.codehaus.staxmate.in.SMEvent; +import org.codehaus.staxmate.in.SMHierarchicCursor; +import org.codehaus.staxmate.in.SMInputCursor; +import org.sonar.api.utils.ParsingUtils; +import org.sonar.api.utils.StaxParser; + +import javax.xml.stream.XMLStreamException; +import java.text.ParseException; +import java.util.Locale; + +public class SurefireStaxHandler implements StaxParser.XmlStreamHandler { + + private UnitTestIndex index; + + public SurefireStaxHandler(UnitTestIndex index) { + this.index = index; + } + + @Override + public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { + SMInputCursor testSuite = rootCursor.constructDescendantCursor(new ElementFilter("testsuite")); + SMEvent testSuiteEvent; + while ((testSuiteEvent = testSuite.getNext()) != null) { + if (testSuiteEvent.compareTo(SMEvent.START_ELEMENT) == 0) { + String testSuiteClassName = testSuite.getAttrValue("name"); + SMInputCursor testCase = testSuite.childCursor(new ElementFilter("testcase")); + SMEvent event; + while ((event = testCase.getNext()) != null) { + if (event.compareTo(SMEvent.START_ELEMENT) == 0) { + UnitTestClassReport classReport = index.index(testSuiteClassName); + parseTestCase(testCase, classReport); + } + } + } + } + } + + private void parseTestCase(SMInputCursor testCaseCursor, UnitTestClassReport report) throws XMLStreamException { + report.add(parseTestResult(testCaseCursor)); + } + + private void setStackAndMessage(UnitTestResult result, SMInputCursor stackAndMessageCursor) throws XMLStreamException { + result.setMessage(stackAndMessageCursor.getAttrValue("message")); + String stack = stackAndMessageCursor.collectDescendantText(); + result.setStackTrace(stack); + } + + private UnitTestResult parseTestResult(SMInputCursor testCaseCursor) throws XMLStreamException { + UnitTestResult detail = new UnitTestResult(); + detail.setName(testCaseCursor.getAttrValue("name")); + + String status = UnitTestResult.STATUS_OK; + long duration = getTimeAttributeInMS(testCaseCursor); + + SMInputCursor childNode = testCaseCursor.descendantElementCursor(); + if (childNode.getNext() != null) { + String elementName = childNode.getLocalName(); + if ("skipped".equals(elementName)) { + status = UnitTestResult.STATUS_SKIPPED; + // bug with surefire reporting wrong time for skipped tests + duration = 0L; + + } else if ("failure".equals(elementName)) { + status = UnitTestResult.STATUS_FAILURE; + setStackAndMessage(detail, childNode); + + } else if ("error".equals(elementName)) { + status = UnitTestResult.STATUS_ERROR; + setStackAndMessage(detail, childNode); + } + } + while (childNode.getNext() != null) { + // make sure we loop till the end of the elements cursor + } + detail.setDurationMilliseconds(duration); + detail.setStatus(status); + return detail; + } + + private long getTimeAttributeInMS(SMInputCursor testCaseCursor) throws XMLStreamException { + // hardcoded to Locale.ENGLISH see http://jira.codehaus.org/browse/SONAR-602 + try { + Double time = ParsingUtils.parseNumber(testCaseCursor.getAttrValue("time"), Locale.ENGLISH); + return !Double.isNaN(time) ? new Double(ParsingUtils.scaleValue(time * 1000, 3)).longValue() : 0L; + } catch (ParseException e) { + throw new XMLStreamException(e); + } + } + +} diff --git a/src/main/java/org/sonar/plugins/scala/surefire/SurefireUtils.java b/src/main/java/org/sonar/plugins/scala/surefire/SurefireUtils.java new file mode 100644 index 0000000..60a5547 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/SurefireUtils.java @@ -0,0 +1,72 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import java.io.File; + +import org.sonar.api.batch.maven.MavenPlugin; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; + +/** + * @since 2.4 + */ +public final class SurefireUtils { + + public static final String SUREFIRE_REPORTS_PATH_PROPERTY = "sonar.junit.reportsPath"; + + public static File getReportsDirectory(Settings settings, Project project) { + File dir = getReportsDirectoryFromProperty(settings, project); + if (dir == null) { + dir = getReportsDirectoryFromPluginConfiguration(project); + } + if (dir == null) { + dir = getReportsDirectoryFromDefaultConfiguration(project); + } + return dir; + } + + private static File getReportsDirectoryFromProperty(Settings settings, Project project) { + String path = settings.getString(SUREFIRE_REPORTS_PATH_PROPERTY); + if (path != null) { + return project.getFileSystem().resolvePath(path); + } + return null; + } + + private static File getReportsDirectoryFromPluginConfiguration(Project project) { + MavenPlugin plugin = null; //MavenPlugin.getPlugin(project.getPom(), MavenSurefireUtils.GROUP_ID, MavenSurefireUtils.ARTIFACT_ID); + if (plugin != null) { + String path = plugin.getParameter("reportsDirectory"); + if (path != null) { + return project.getFileSystem().resolvePath(path); + } + } + return null; + } + + private static File getReportsDirectoryFromDefaultConfiguration(Project project) { + return new File(project.getFileSystem().getBuildDir(), "surefire-reports"); + } + + private SurefireUtils() { + } + +} diff --git a/src/main/java/org/sonar/plugins/scala/surefire/UnitTestClassReport.java b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestClassReport.java new file mode 100644 index 0000000..bfa875b --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestClassReport.java @@ -0,0 +1,93 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import com.google.common.collect.Lists; + +import java.util.List; + +public final class UnitTestClassReport { + private long errors = 0L; + private long failures = 0L; + private long skipped = 0L; + private long tests = 0L; + private long durationMilliseconds = 0L; + private long negativeTimeTestNumber = 0L; + + private List results = null; + + public UnitTestClassReport add(UnitTestResult result) { + initResults(); + results.add(result); + if (result.getStatus().equals(UnitTestResult.STATUS_SKIPPED)) { + skipped += 1; + + } else if (result.getStatus().equals(UnitTestResult.STATUS_FAILURE)) { + failures += 1; + + } else if (result.getStatus().equals(UnitTestResult.STATUS_ERROR)) { + errors += 1; + } + tests += 1; + durationMilliseconds += result.getDurationMilliseconds(); + return this; + } + + private void initResults() { + if (results == null) { + results = Lists.newArrayList(); + } + } + + public long getErrors() { + return errors; + } + + public long getFailures() { + return failures; + } + + public long getSkipped() { + return skipped; + } + + public long getTests() { + return tests; + } + + public long getDurationMilliseconds() { + return durationMilliseconds; + } + + public long getNegativeTimeTestNumber() { + return negativeTimeTestNumber; + } + + public String toXml() { + StringBuilder sb = new StringBuilder(256); + sb.append(""); + for (UnitTestResult result : results) { + result.appendXml(sb); + } + sb.append(""); + return sb.toString(); + } + +} diff --git a/src/main/java/org/sonar/plugins/scala/surefire/UnitTestIndex.java b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestIndex.java new file mode 100644 index 0000000..c40b3cb --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestIndex.java @@ -0,0 +1,50 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public class UnitTestIndex { + + private Map indexByClassname; + + public UnitTestIndex() { + this.indexByClassname = Maps.newHashMap(); + } + + public UnitTestClassReport index(String classname) { + UnitTestClassReport classReport = indexByClassname.get(classname); + if (classReport == null) { + classReport = new UnitTestClassReport(); + indexByClassname.put(classname, classReport); + } + return classReport; + } + public Map getIndexByClassname() { + return indexByClassname; + } + + public int size() { + return indexByClassname.size(); + } + +} diff --git a/src/main/java/org/sonar/plugins/scala/surefire/UnitTestResult.java b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestResult.java new file mode 100644 index 0000000..9bc1d98 --- /dev/null +++ b/src/main/java/org/sonar/plugins/scala/surefire/UnitTestResult.java @@ -0,0 +1,107 @@ +/* + * Sonar Scala Plugin + * Copyright (C) 2011 - 2014 All contributors + * dev@sonar.codehaus.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.scala.surefire; + +import org.apache.commons.lang.StringEscapeUtils; + +public final class UnitTestResult { + public static final String STATUS_OK = "ok"; + public static final String STATUS_ERROR = "error"; + public static final String STATUS_FAILURE = "failure"; + public static final String STATUS_SKIPPED = "skipped"; + + private String name, status, stackTrace, message; + private long durationMilliseconds = 0L; + + public String getName() { + return name; + } + + public UnitTestResult setName(String name) { + this.name = name; + return this; + } + + public String getStatus() { + return status; + } + + public UnitTestResult setStatus(String status) { + this.status = status; + return this; + } + + public UnitTestResult setStackTrace(String stackTrace) { + this.stackTrace = stackTrace; + return this; + } + + public String getMessage() { + return message; + } + + public UnitTestResult setMessage(String message) { + this.message = message; + return this; + } + + public long getDurationMilliseconds() { + return durationMilliseconds; + } + + public UnitTestResult setDurationMilliseconds(long l) { + this.durationMilliseconds = l; + return this; + } + + public boolean isErrorOrFailure() { + return STATUS_ERROR.equals(status) || STATUS_FAILURE.equals(status); + } + + public boolean isError() { + return STATUS_ERROR.equals(status); + } + public StringBuilder appendXml(StringBuilder sb) { + sb + .append("") + .append(isError() ? "") + .append("") + .append(isError() ? "" : "") + .append(""); + } else { + sb.append("/>"); + } + return sb; + } +} diff --git a/src/test/java/org/sonar/plugins/scala/surefire/SurefireSensorTest.java b/src/test/java/org/sonar/plugins/scala/surefire/SurefireSensorTest.java index c0a454a..d797b00 100644 --- a/src/test/java/org/sonar/plugins/scala/surefire/SurefireSensorTest.java +++ b/src/test/java/org/sonar/plugins/scala/surefire/SurefireSensorTest.java @@ -19,55 +19,32 @@ */ package org.sonar.plugins.scala.surefire; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + import org.junit.Before; +import org.junit.Test; import org.sonar.api.batch.CoverageExtension; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; -import org.sonar.plugins.scala.language.Scala; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class SurefireSensorTest { private SurefireSensor sensor; + private Settings settings; + private FileSystem fileSystem; private Project project; @Before public void setUp() { - sensor = new SurefireSensor(mock(Settings.class)); + this.settings = new Settings(); + this.fileSystem = new DefaultFileSystem(); + sensor = new SurefireSensor(settings, fileSystem); project = mock(Project.class); } - @Test - public void shouldExecuteOnReuseReports() { - when(project.getLanguageKey()).thenReturn(Scala.KEY); - when(project.getAnalysisType()).thenReturn(Project.AnalysisType.REUSE_REPORTS); - assertTrue(sensor.shouldExecuteOnProject(project)); - } - - @Test - public void shouldExecuteOnDynamicAnalysis() { - when(project.getLanguageKey()).thenReturn(Scala.KEY); - when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC); - assertTrue(sensor.shouldExecuteOnProject(project)); - } - - @Test - public void shouldNotExecuteIfStaticAnalysis() { - when(project.getLanguageKey()).thenReturn(Scala.KEY); - when(project.getAnalysisType()).thenReturn(Project.AnalysisType.STATIC); - assertFalse(sensor.shouldExecuteOnProject(project)); - } - - @Test - public void shouldNotExecuteOnJavaProject() { - when(project.getLanguageKey()).thenReturn("java"); - when(project.getAnalysisType()).thenReturn(Project.AnalysisType.DYNAMIC); - assertFalse(sensor.shouldExecuteOnProject(project)); - } @Test public void shouldDependOnCoverageSensors() {