Browse Source

SONAR-5931 Remove beta test API

tags/5.1-RC1
Julien HENRY 9 years ago
parent
commit
0f517d5244
30 changed files with 1 additions and 2547 deletions
  1. 0
    4
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
  2. 0
    113
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java
  3. 0
    112
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java
  4. 0
    109
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java
  5. 0
    109
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java
  6. 0
    56
      sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
  7. 0
    118
      sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java
  8. 0
    59
      sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java
  9. 0
    21
      sonar-batch/src/main/java/org/sonar/batch/scan2/package-info.java
  10. 0
    21
      sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
  11. 0
    41
      sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
  12. 0
    81
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java
  13. 0
    90
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java
  14. 0
    65
      sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java
  15. 0
    69
      sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java
  16. 0
    24
      sonar-batch/src/main/java/org/sonar/batch/test/package-info.java
  17. 0
    128
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java
  18. 1
    20
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
  19. 0
    6
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java
  20. 0
    103
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/Coverage.java
  21. 0
    77
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseCoverage.java
  22. 0
    125
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseExecution.java
  23. 0
    153
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultCoverage.java
  24. 0
    138
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseCoverage.java
  25. 0
    181
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseExecution.java
  26. 0
    22
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java
  27. 0
    22
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/package-info.java
  28. 0
    274
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultCoverageTest.java
  29. 0
    83
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseCoverageTest.java
  30. 0
    123
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseExecutionTest.java

+ 0
- 4
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java View File

@@ -20,12 +20,10 @@
package org.sonar.xoo;

import org.sonar.api.SonarPlugin;
import org.sonar.xoo.lang.CoveragePerTestSensor;
import org.sonar.xoo.lang.DependencySensor;
import org.sonar.xoo.lang.MeasureSensor;
import org.sonar.xoo.lang.SymbolReferencesSensor;
import org.sonar.xoo.lang.SyntaxHighlightingSensor;
import org.sonar.xoo.lang.TestCaseSensor;
import org.sonar.xoo.lang.XooCpdMapping;
import org.sonar.xoo.lang.XooTokenizer;
import org.sonar.xoo.rule.ChecksSensor;
@@ -76,8 +74,6 @@ public class XooPlugin extends SonarPlugin {
MeasureSensor.class,
SyntaxHighlightingSensor.class,
SymbolReferencesSensor.class,
TestCaseSensor.class,
CoveragePerTestSensor.class,
DependencySensor.class,
ChecksSensor.class,
RandomAccessSensor.class,

+ 0
- 113
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java View File

@@ -1,113 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.xoo.lang;

import com.google.common.base.Splitter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
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.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.xoo.Xoo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* Parse files *.xoo.coveragePerTest
*/
public class CoveragePerTestSensor implements Sensor {

private static final Logger LOG = Loggers.get(CoveragePerTestSensor.class);

private static final String COVER_PER_TEST_EXTENSION = ".coveragePerTest";

private void processCoveragePerTest(InputFile inputFile, SensorContext context) {
File ioFile = inputFile.file();
File coverPerTestFile = new File(ioFile.getParentFile(), ioFile.getName() + COVER_PER_TEST_EXTENSION);
if (coverPerTestFile.exists()) {
LOG.debug("Processing " + coverPerTestFile.getAbsolutePath());
try {
List<String> lines = FileUtils.readLines(coverPerTestFile, context.fileSystem().encoding().name());
int lineNumber = 0;
for (String line : lines) {
lineNumber++;
if (StringUtils.isBlank(line) || line.startsWith("#")) {
continue;
}
processLine(coverPerTestFile, lineNumber, context, line, inputFile);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}

private void processLine(File coverPerTest, int lineNumber, SensorContext context, String line, InputFile testFile) {
try {
Iterator<String> split = Splitter.on(":").split(line).iterator();
String testCaseName = split.next();
String mainFileRelativePath = split.next();
FileSystem fs = context.fileSystem();
InputFile mainFile = fs.inputFile(fs.predicates().hasRelativePath(mainFileRelativePath));
if (mainFile == null) {
throw new IllegalStateException("Unable to find file " + mainFileRelativePath);
}
List<Integer> coveredLines = new ArrayList<Integer>();
Iterator<String> lines = Splitter.on(",").split(split.next()).iterator();
while (lines.hasNext()) {
coveredLines.add(Integer.parseInt(lines.next()));
}
context.newTestCaseCoverage()
.testFile(testFile)
.testName(testCaseName)
.cover(mainFile)
.onLines(coveredLines)
.save();
} catch (Exception e) {
throw new IllegalStateException("Error processing line " + lineNumber + " of file " + coverPerTest.getAbsolutePath(), e);
}
}

@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo Coverage Per Test Sensor")
.onlyOnLanguages(Xoo.KEY)
.onlyOnFileType(InputFile.Type.TEST);
}

@Override
public void execute(SensorContext context) {
FileSystem fs = context.fileSystem();
FilePredicates p = fs.predicates();
for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(InputFile.Type.TEST)))) {
processCoveragePerTest(file, context);
}
}
}

+ 0
- 112
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java View File

@@ -1,112 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.xoo.lang;

import com.google.common.base.Splitter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
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.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.xoo.Xoo;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

/**
* Parse files *.xoo.testplan
*/
public class TestCaseSensor implements Sensor {

private static final Logger LOG = Loggers.get(TestCaseSensor.class);

private static final String TESTPLAN_EXTENSION = ".testplan";

private void processFileTestPlan(InputFile inputFile, SensorContext context) {
File ioFile = inputFile.file();
File testPlanFile = new File(ioFile.getParentFile(), ioFile.getName() + TESTPLAN_EXTENSION);
if (testPlanFile.exists()) {
LOG.debug("Processing " + testPlanFile.getAbsolutePath());
try {
List<String> lines = FileUtils.readLines(testPlanFile, context.fileSystem().encoding().name());
int lineNumber = 0;
for (String line : lines) {
lineNumber++;
if (StringUtils.isBlank(line) || line.startsWith("#")) {
continue;
}
processLine(testPlanFile, lineNumber, line, context, inputFile);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}

private void processLine(File testplanFile, int lineNumber, String line, SensorContext context, InputFile testFile) {
try {
Iterator<String> split = Splitter.on(":").split(line).iterator();
String name = split.next();
String type = split.next();
String status = split.next();
String message = split.next();
String stack = split.next();
String durationStr = StringUtils.trimToNull(split.next());
TestCaseExecution test = context.newTestCaseExecution()
.inTestFile(testFile)
.name(name)
.ofType(TestCaseExecution.Type.valueOf(type))
.status(TestCaseExecution.Status.valueOf(status))
.message(StringUtils.trimToNull(message))
.stackTrace(StringUtils.trimToNull(stack));
if (durationStr != null) {
test.durationInMs(Long.parseLong(durationStr));
}
test.save();
} catch (Exception e) {
throw new IllegalStateException("Error processing line " + lineNumber + " of file " + testplanFile.getAbsolutePath(), e);
}
}

@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo TestPlan Sensor")
.onlyOnLanguages(Xoo.KEY)
.onlyOnFileType(InputFile.Type.TEST);
}

@Override
public void execute(SensorContext context) {
FileSystem fs = context.fileSystem();
FilePredicates p = fs.predicates();
for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(InputFile.Type.TEST)))) {
processFileTestPlan(file, context);
}
}
}

+ 0
- 109
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CoveragePerTestSensorTest.java View File

@@ -1,109 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.xoo.lang;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class CoveragePerTestSensorTest {

private CoveragePerTestSensor sensor;
private SensorContext context = mock(SensorContext.class);
private DefaultFileSystem fileSystem;

@Rule
public TemporaryFolder temp = new TemporaryFolder();
private File baseDir;

@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
sensor = new CoveragePerTestSensor();
fileSystem = new DefaultFileSystem(baseDir.toPath());
when(context.fileSystem()).thenReturn(fileSystem);
}

@Test
public void testDescriptor() {
sensor.describe(new DefaultSensorDescriptor());
}

@Test
public void testNoExecutionIfCoveragePerTestFile() {
DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setLanguage("xoo")
.setType(Type.TEST);
fileSystem.add(testFile);
sensor.execute(context);
}

@Test
public void testExecution() throws IOException {
File coverPerTest = new File(baseDir, "test/fooTest.xoo.coveragePerTest");
FileUtils.write(coverPerTest, "test1:src/foo.xoo:1,2,3,4\ntest2:src/foo.xoo:5,6,7\n\n#comment");
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setLanguage("xoo")
.setType(Type.TEST);
fileSystem.add(inputFile);
fileSystem.add(testFile);

final SensorStorage sensorStorage = mock(SensorStorage.class);

when(context.newTestCaseCoverage()).thenAnswer(new Answer<TestCaseCoverage>() {
@Override
public TestCaseCoverage answer(InvocationOnMock invocation) throws Throwable {
return new DefaultTestCaseCoverage(sensorStorage);
}
});

sensor.execute(context);

verify(sensorStorage).store(new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("test1")
.cover(inputFile)
.onLines(Arrays.asList(1, 2, 3, 4)));
verify(sensorStorage).store(new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("test2")
.cover(inputFile)
.onLines(Arrays.asList(5, 6, 7)));
}
}

+ 0
- 109
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/TestCaseSensorTest.java View File

@@ -1,109 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.xoo.lang;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;

import java.io.File;
import java.io.IOException;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class TestCaseSensorTest {

private TestCaseSensor sensor;
private SensorContext context = mock(SensorContext.class);
private DefaultFileSystem fileSystem;

@Rule
public TemporaryFolder temp = new TemporaryFolder();
private File baseDir;

@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
sensor = new TestCaseSensor();
fileSystem = new DefaultFileSystem(baseDir.toPath());
when(context.fileSystem()).thenReturn(fileSystem);
}

@Test
public void testDescriptor() {
sensor.describe(new DefaultSensorDescriptor());
}

@Test
public void testNoExecutionIfNoTestFile() {
DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setLanguage("xoo")
.setType(Type.TEST);
fileSystem.add(testFile);
sensor.execute(context);
}

@Test
public void testExecution() throws IOException {
File testPlan = new File(baseDir, "test/fooTest.xoo.testplan");
FileUtils.write(testPlan, "test1:UNIT:OK:::10\ntest2:INTEGRATION:ERROR:message:stack:15\n\n#comment");
DefaultInputFile testFile = new DefaultInputFile("foo", "test/fooTest.xoo").setLanguage("xoo")
.setType(Type.TEST);
fileSystem.add(testFile);

final SensorStorage sensorStorage = mock(SensorStorage.class);

when(context.newTestCaseExecution()).thenAnswer(new Answer<TestCaseExecution>() {
@Override
public TestCaseExecution answer(InvocationOnMock invocation) throws Throwable {
return new DefaultTestCaseExecution(sensorStorage);
}
});

sensor.execute(context);

verify(sensorStorage).store(new DefaultTestCaseExecution(null)
.inTestFile(testFile)
.name("test1")
.durationInMs(10));
verify(sensorStorage).store(new DefaultTestCaseExecution(null)
.inTestFile(testFile)
.name("test2")
.ofType(TestCaseExecution.Type.INTEGRATION)
.status(TestCaseExecution.Status.ERROR)
.message("message")
.stackTrace("stack")
.durationInMs(15));
}

}

+ 0
- 56
sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java View File

@@ -31,8 +31,6 @@ import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.Symbol;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.measures.Measure;
@@ -47,8 +45,6 @@ import org.sonar.batch.scan.ProjectScanContainer;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.measure.MeasureCache;
import org.sonar.batch.symbol.SymbolData;
import org.sonar.batch.test.TestCaseCoverageCache;
import org.sonar.batch.test.TestCaseExecutionCache;
import org.sonar.core.source.SnapshotDataTypes;

import javax.annotation.CheckForNull;
@@ -73,8 +69,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
private Map<String, InputDir> inputDirs = new HashMap<>();
private Map<InputFile, SyntaxHighlightingData> highlightingPerFile = new HashMap<>();
private Map<InputFile, SymbolData> symbolTablePerFile = new HashMap<>();
private Map<String, Map<String, TestCaseExecution>> testCasesPerFile = new HashMap<>();
private Map<String, Map<String, Map<String, List<Integer>>>> coveragePerTest = new HashMap<>();
private Map<String, Map<String, Integer>> dependencies = new HashMap<>();

@Override
@@ -114,33 +108,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
}
}

private void storeCoveragePerTest(ProjectScanContainer container) {
TestCaseCoverageCache testCaseCoverageCache = container.getComponentByType(TestCaseCoverageCache.class);
for (Entry<TestCaseCoverage> entry : testCaseCoverageCache.entries()) {
String testFileKey = entry.key()[0].toString();
if (!coveragePerTest.containsKey(testFileKey)) {
coveragePerTest.put(testFileKey, new HashMap<String, Map<String, List<Integer>>>());
}
String testName = entry.key()[1].toString();
if (!coveragePerTest.get(testFileKey).containsKey(testName)) {
coveragePerTest.get(testFileKey).put(testName, new HashMap<String, List<Integer>>());
}
TestCaseCoverage value = entry.value();
coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), value != null ? value.coveredLines() : null);
}
}

private void storeTestCases(ProjectScanContainer container) {
TestCaseExecutionCache testCaseCache = container.getComponentByType(TestCaseExecutionCache.class);
for (Entry<TestCaseExecution> entry : testCaseCache.entries()) {
String effectiveKey = entry.key()[0].toString();
if (!testCasesPerFile.containsKey(effectiveKey)) {
testCasesPerFile.put(effectiveKey, new HashMap<String, TestCaseExecution>());
}
testCasesPerFile.get(effectiveKey).put(entry.value().name(), entry.value());
}
}

private void storeDuplication(ProjectScanContainer container) {
DuplicationCache duplicationCache = container.getComponentByType(DuplicationCache.class);
for (String effectiveKey : duplicationCache.componentKeys()) {
@@ -214,29 +181,6 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
return duplications.get(((DefaultInputFile) inputFile).key());
}

public Collection<TestCaseExecution> testCasesFor(InputFile inputFile) {
String key = ((DefaultInputFile) inputFile).key();
if (testCasesPerFile.containsKey(key)) {
return testCasesPerFile.get(key).values();
} else {
return Collections.emptyList();
}
}

public TestCaseExecution testCase(InputFile inputFile, String testCaseName) {
return testCasesPerFile.get(((DefaultInputFile) inputFile).key()).get(testCaseName);
}

public List<Integer> coveragePerTest(InputFile testFile, String testCaseName, InputFile mainFile) {
String testKey = ((DefaultInputFile) testFile).key();
String mainKey = ((DefaultInputFile) mainFile).key();
if (coveragePerTest.containsKey(testKey) && coveragePerTest.get(testKey).containsKey(testCaseName) && coveragePerTest.get(testKey).get(testCaseName).containsKey(mainKey)) {
return coveragePerTest.get(testKey).get(testCaseName).get(mainKey);
} else {
return Collections.emptyList();
}
}

/**
* Get highlighting types at a given position in an inputfile
* @param charIndex 0-based offset in file

+ 0
- 118
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java View File

@@ -1,118 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.scan2;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.utils.KeyValueFormat;

import java.util.Map;

public class DefaultFileLinesContext implements FileLinesContext {

private final SensorStorage sensorStorage;
private final InputFile inputFile;

/**
* metric key -> line -> value
*/
private final Map<String, Map<Integer, Object>> map = Maps.newHashMap();
private MetricFinder metricFinder;

public DefaultFileLinesContext(MetricFinder metricFinder, SensorStorage sensorStorage, InputFile inputFile) {
this.metricFinder = metricFinder;
this.sensorStorage = sensorStorage;
this.inputFile = inputFile;
}

@Override
public void setIntValue(String metricKey, int line, int value) {
Preconditions.checkNotNull(metricKey);
Preconditions.checkArgument(line > 0);

setValue(metricKey, line, value);
}

@Override
public Integer getIntValue(String metricKey, int line) {
throw new UnsupportedOperationException();
}

@Override
public void setStringValue(String metricKey, int line, String value) {
Preconditions.checkNotNull(metricKey);
Preconditions.checkArgument(line > 0);
Preconditions.checkNotNull(value);

setValue(metricKey, line, value);
}

@Override
public String getStringValue(String metricKey, int line) {
throw new UnsupportedOperationException();
}

private Map<Integer, Object> getOrCreateLines(String metricKey) {
Map<Integer, Object> lines = map.get(metricKey);
if (lines == null) {
lines = Maps.newHashMap();
map.put(metricKey, lines);
}
return lines;
}

private void setValue(String metricKey, int line, Object value) {
getOrCreateLines(metricKey).put(line, value);
}

@Override
public void save() {
for (Map.Entry<String, Map<Integer, Object>> entry : map.entrySet()) {
String metricKey = entry.getKey();
org.sonar.api.batch.measure.Metric<String> metric = metricFinder.findByKey(metricKey);
if (metric == null) {
throw new IllegalStateException("Unable to find metric with key: " + metricKey);
}
Map<Integer, Object> lines = entry.getValue();
String data = KeyValueFormat.format(lines);
new DefaultMeasure<String>(sensorStorage)
.forMetric(metric)
.onFile(inputFile)
.withValue(data)
.save();
entry.setValue(ImmutableMap.copyOf(lines));
}
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("map", map)
.toString();
}

}

+ 0
- 59
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java View File

@@ -1,59 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.scan2;

import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.measures.FileLinesContextFactory;
import org.sonar.api.resources.Resource;
import org.sonar.batch.scan.filesystem.InputPathCache;

public class DefaultFileLinesContextFactory implements FileLinesContextFactory {

private final SensorStorage sensorStorage;
private final MetricFinder metricFinder;
private final ProjectDefinition def;
private final InputPathCache fileCache;

public DefaultFileLinesContextFactory(InputPathCache fileCache, MetricFinder metricFinder, SensorStorage sensorStorage,
ProjectDefinition def) {
this.fileCache = fileCache;
this.metricFinder = metricFinder;
this.sensorStorage = sensorStorage;
this.def = def;
}

@Override
public FileLinesContext createFor(Resource model) {
throw new UnsupportedOperationException();
}

@Override
public FileLinesContext createFor(InputFile inputFile) {
if (fileCache.getFile(def.getKey(), inputFile.relativePath()) == null) {
throw new IllegalStateException("InputFile is not indexed: " + inputFile);
}
return new DefaultFileLinesContext(metricFinder, sensorStorage, inputFile);
}

}

+ 0
- 21
sonar-batch/src/main/java/org/sonar/batch/scan2/package-info.java View File

@@ -1,21 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.batch.scan2;

+ 0
- 21
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java View File

@@ -36,12 +36,6 @@ import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
import org.sonar.api.batch.sensor.test.Coverage;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.batch.sensor.test.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
import org.sonar.api.config.Settings;
import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
import org.sonar.batch.index.ComponentDataCache;
@@ -113,21 +107,6 @@ public class DefaultSensorContext implements SensorContext {
return new DefaultDuplication(sensorStorage);
}

@Override
public Coverage newCoverage() {
return new DefaultCoverage(sensorStorage);
}

@Override
public TestCaseExecution newTestCaseExecution() {
return new DefaultTestCaseExecution(sensorStorage);
}

@Override
public TestCaseCoverage newTestCaseCoverage() {
return new DefaultTestCaseCoverage(sensorStorage);
}

@Override
public NewDependency newDependency() {
return new DefaultDependency(sensorStorage);

+ 0
- 41
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java View File

@@ -33,9 +33,6 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.Issue.Severity;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.config.Settings;
import org.sonar.api.design.Dependency;
@@ -52,10 +49,6 @@ import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.Scopes;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.api.test.MutableTestable;
import org.sonar.api.test.Testable;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ComponentDataCache;
@@ -182,40 +175,6 @@ public class DefaultSensorStorage implements SensorStorage {
.build();
}

@Override
public void store(TestCaseExecution testCase) {
File testRes = getTestResource(((DefaultTestCaseExecution) testCase).testFile());
MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
if (testPlan != null) {
testPlan
.addTestCase(testCase.name())
.setDurationInMs(testCase.durationInMs())
.setType(testCase.type().name())
.setStatus(org.sonar.api.test.TestCase.Status.valueOf(testCase.status().name()))
.setMessage(testCase.message())
.setStackTrace(testCase.stackTrace());
}
}

@Override
public void store(TestCaseCoverage testCaseCoverage) {
File testRes = getTestResource(testCaseCoverage.testFile());
File mainRes = getMainResource(testCaseCoverage.coveredFile());
Testable testAbleFile = perspectives.as(MutableTestable.class, mainRes);
if (testAbleFile != null) {
MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
if (testPlan != null) {
for (MutableTestCase mutableTestCase : testPlan.testCasesByName(testCaseCoverage.testName())) {
mutableTestCase.setCoverageBlock(testAbleFile, testCaseCoverage.coveredLines());
}
} else {
throw new IllegalStateException("Unable to get MutableTestPlan perspective from " + testRes);
}
} else {
throw new IllegalStateException("Unable to get MutableTestable perspective from " + mainRes);
}
}

private File getTestResource(InputFile testFile) {
File testRes = File.create(testFile.relativePath());
testRes.setQualifier(Qualifiers.UNIT_TEST_FILE);

+ 0
- 81
sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseCoverageValueCoder.java View File

@@ -1,81 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.test;

import com.persistit.Value;
import com.persistit.encoding.CoderContext;
import com.persistit.encoding.ValueCoder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;
import org.sonar.batch.scan.filesystem.InputPathCache;

import java.util.ArrayList;
import java.util.List;

class DefaultTestCaseCoverageValueCoder implements ValueCoder {

private InputPathCache inputPathCache;

public DefaultTestCaseCoverageValueCoder(InputPathCache inputPathCache) {
this.inputPathCache = inputPathCache;
}

@Override
public void put(Value value, Object object, CoderContext context) {
DefaultTestCaseCoverage t = (DefaultTestCaseCoverage) object;
value.putUTF(((DefaultInputFile) t.testFile()).moduleKey());
value.putUTF(((DefaultInputFile) t.testFile()).relativePath());
value.putUTF(t.testName());
value.putUTF(((DefaultInputFile) t.coveredFile()).moduleKey());
value.putUTF(((DefaultInputFile) t.coveredFile()).relativePath());
value.put(t.coveredLines().size());
for (Integer line : t.coveredLines()) {
value.put(line.intValue());
}
}

@Override
public Object get(Value value, Class clazz, CoderContext context) {
String testModuleKey = value.getString();
String testRelativePath = value.getString();
InputFile testFile = inputPathCache.getFile(testModuleKey, testRelativePath);
if (testFile == null) {
throw new IllegalStateException("Unable to load InputFile " + testModuleKey + ":" + testRelativePath);
}
String name = value.getString();
String mainModuleKey = value.getString();
String mainRelativePath = value.getString();
InputFile mainFile = inputPathCache.getFile(mainModuleKey, mainRelativePath);
if (mainFile == null) {
throw new IllegalStateException("Unable to load InputFile " + mainModuleKey + ":" + mainRelativePath);
}
int size = value.getInt();
List<Integer> lines = new ArrayList<Integer>(size);
for (int i = 0; i < size; i++) {
lines.add(value.getInt());
}
return new DefaultTestCaseCoverage()
.testFile(testFile)
.testName(name)
.cover(mainFile)
.onLines(lines);
}
}

+ 0
- 90
sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseExecutionValueCoder.java View File

@@ -1,90 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.test;

import com.persistit.Value;
import com.persistit.encoding.CoderContext;
import com.persistit.encoding.ValueCoder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
import org.sonar.batch.scan.filesystem.InputPathCache;

import javax.annotation.Nullable;

class DefaultTestCaseExecutionValueCoder implements ValueCoder {

private InputPathCache inputPathCache;

public DefaultTestCaseExecutionValueCoder(InputPathCache inputPathCache) {
this.inputPathCache = inputPathCache;
}

@Override
public void put(Value value, Object object, CoderContext context) {
DefaultTestCaseExecution t = (DefaultTestCaseExecution) object;
value.putUTF(((DefaultInputFile) t.testFile()).moduleKey());
value.putUTF(((DefaultInputFile) t.testFile()).relativePath());
value.putUTF(t.name());
putUTFOrNull(value, t.message());
putUTFOrNull(value, t.stackTrace());
Long durationInMs = t.durationInMs();
value.put(durationInMs != null ? durationInMs.longValue() : -1);
value.put(t.type().ordinal());
value.put(t.status().ordinal());
}

private void putUTFOrNull(Value value, @Nullable String utfOrNull) {
if (utfOrNull != null) {
value.putUTF(utfOrNull);
} else {
value.putNull();
}
}

@Override
public Object get(Value value, Class clazz, CoderContext context) {
String moduleKey = value.getString();
String relativePath = value.getString();
InputFile testFile = inputPathCache.getFile(moduleKey, relativePath);
if (testFile == null) {
throw new IllegalStateException("Unable to load InputFile " + moduleKey + ":" + relativePath);
}
String name = value.getString();
String message = value.getString();
String stack = value.getString();
long duration = value.getLong();
TestCaseExecution.Type type = TestCaseExecution.Type.values()[value.getInt()];
TestCaseExecution.Status status = TestCaseExecution.Status.values()[value.getInt()];
DefaultTestCaseExecution testCaseExecution = new DefaultTestCaseExecution();
testCaseExecution
.inTestFile(testFile)
.ofType(type)
.name(name)
.status(status)
.message(message)
.stackTrace(stack);
if (duration != -1) {
testCaseExecution.durationInMs(duration);
}
return testCaseExecution;
}
}

+ 0
- 65
sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCoverageCache.java View File

@@ -1,65 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.test;

import com.google.common.base.Preconditions;
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.Caches;
import org.sonar.batch.scan.filesystem.InputPathCache;

import javax.annotation.CheckForNull;

/**
* Cache of coverage per test. This cache is shared amongst all project modules.
*/
public class TestCaseCoverageCache implements BatchComponent {

private final Cache<TestCaseCoverage> cache;

public TestCaseCoverageCache(Caches caches, InputPathCache inputPathCache) {
caches.registerValueCoder(DefaultTestCaseCoverage.class, new DefaultTestCaseCoverageValueCoder(inputPathCache));
cache = caches.createCache("testCaseCoverage");
}

public Iterable<Entry<TestCaseCoverage>> entries() {
return cache.entries();
}

@CheckForNull
public TestCaseCoverage getCoverage(InputFile testFile, String testCaseName, InputFile mainFile) {
Preconditions.checkNotNull(testFile);
Preconditions.checkNotNull(testCaseName);
Preconditions.checkNotNull(mainFile);
return cache.get(((DefaultInputFile) testFile).key(), testCaseName, ((DefaultInputFile) mainFile).key());
}

public TestCaseCoverageCache put(TestCaseCoverage coverage) {
Preconditions.checkNotNull(coverage);
cache.put(((DefaultInputFile) coverage.testFile()).key(), coverage.testName(), ((DefaultInputFile) coverage.coveredFile()).key(), coverage);
return this;
}

}

+ 0
- 69
sonar-batch/src/main/java/org/sonar/batch/test/TestCaseExecutionCache.java View File

@@ -1,69 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.test;

import com.google.common.base.Preconditions;
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.Caches;
import org.sonar.batch.scan.filesystem.InputPathCache;

import javax.annotation.CheckForNull;

/**
* Cache of all TestCases. This cache is shared amongst all project modules.
*/
public class TestCaseExecutionCache implements BatchComponent {

private final Cache<TestCaseExecution> cache;

public TestCaseExecutionCache(Caches caches, InputPathCache inputPathCache) {
caches.registerValueCoder(DefaultTestCaseExecution.class, new DefaultTestCaseExecutionValueCoder(inputPathCache));
cache = caches.createCache("testCaseExecutions");
}

public Iterable<Entry<TestCaseExecution>> entries() {
return cache.entries();
}

@CheckForNull
public TestCaseExecution get(InputFile testFile, String testCaseName) {
Preconditions.checkNotNull(testFile);
Preconditions.checkNotNull(testCaseName);
return cache.get(((DefaultInputFile) testFile).key(), testCaseName);
}

public TestCaseExecutionCache put(InputFile testFile, TestCaseExecution testCase) {
Preconditions.checkNotNull(testFile);
Preconditions.checkNotNull(testCase);
cache.put(((DefaultInputFile) testFile).key(), testCase.name(), testCase);
return this;
}

public boolean contains(InputFile testFile, String name) {
return cache.containsKey(((DefaultInputFile) testFile).key(), name);
}

}

+ 0
- 24
sonar-batch/src/main/java/org/sonar/batch/test/package-info.java View File

@@ -1,24 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
package org.sonar.batch.test;

import javax.annotation.ParametersAreNonnullByDefault;


+ 0
- 128
sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java View File

@@ -1,128 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.batch.mediumtest.test;

import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
import org.sonar.batch.mediumtest.BatchMediumTester;
import org.sonar.batch.mediumtest.TaskResult;
import org.sonar.xoo.XooPlugin;

import java.io.File;
import java.io.IOException;

public class TestMediumTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Rule
public TestName testName = new TestName();

public BatchMediumTester tester = BatchMediumTester.builder()
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
.build();

@Before
public void prepare() {
tester.start();
}

@After
public void stop() {
tester.stop();
}

@Test
public void populateTestCaseOnTempProject() throws IOException {

File baseDir = temp.newFolder();
File srcDir = new File(baseDir, "src");
srcDir.mkdir();
File testDir = new File(baseDir, "test");
testDir.mkdir();

File xooTestFile = new File(testDir, "sampleTest.xoo");
File xooTestPlanFile = new File(testDir, "sampleTest.xoo.testplan");
FileUtils.write(xooTestFile, "Sample test xoo\ncontent");
FileUtils.write(xooTestPlanFile, "test1:UNIT:OK:::\ntest2:INTEGRATION:ERROR:Assertion failure:A very long stack:12");

TaskResult result = tester.newTask()
.properties(ImmutableMap.<String, String>builder()
.put("sonar.task", "scan")
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.projectName", "Foo Project")
.put("sonar.projectVersion", "1.0-SNAPSHOT")
.put("sonar.projectDescription", "Description of Foo Project")
.put("sonar.sources", "src")
.put("sonar.tests", "test")
.build())
.start();

// assertThat(result.testCasesFor(new DefaultInputFile("com.foo.project", "test/sampleTest.xoo"))).hasSize(2);
}

@Test
public void populateTestCaseAndCoveragePerTestOnTempProject() throws IOException {

File baseDir = temp.newFolder();
File srcDir = new File(baseDir, "src");
srcDir.mkdir();
File testDir = new File(baseDir, "test");
testDir.mkdir();

File xooMainFile = new File(srcDir, "sample.xoo");
File xooTestFile = new File(testDir, "sampleTest.xoo");
File xooTestPlanFile = new File(testDir, "sampleTest.xoo.testplan");
File xooTestCoverageFile = new File(testDir, "sampleTest.xoo.coveragePerTest");
FileUtils.write(xooMainFile, "Sample xoo\ncontent");
FileUtils.write(xooTestFile, "Sample test xoo\ncontent");
FileUtils.write(xooTestPlanFile, "test1:UNIT:OK:::3\ntest2:INTEGRATION:ERROR:Assertion failure:A very long stack:12");
FileUtils.write(xooTestCoverageFile, "test1:src/sample.xoo:1,2,3,8,9,10\ntest2:src/sample.xoo:3,4");

// TaskResult result = tester.newTask()
// .properties(ImmutableMap.<String, String>builder()
// .put("sonar.task", "scan")
// .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
// .put("sonar.projectKey", "com.foo.project")
// .put("sonar.projectName", "Foo Project")
// .put("sonar.projectVersion", "1.0-SNAPSHOT")
// .put("sonar.projectDescription", "Description of Foo Project")
// .put("sonar.sources", "src")
// .put("sonar.tests", "test")
// .build())
// .start();
//
// assertThat(result.coveragePerTest(new DefaultInputFile("com.foo.project", "test/sampleTest.xoo"), "test1", new
// DefaultInputFile("com.foo.project", "src/sample.xoo")))
// .containsExactly(1, 2, 3, 8, 9, 10);
// assertThat(result.coveragePerTest(new DefaultInputFile("com.foo.project", "test/sampleTest.xoo"), "test2", new
// DefaultInputFile("com.foo.project", "src/sample.xoo")))
// .containsExactly(3, 4);
}
}

+ 1
- 20
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java View File

@@ -31,9 +31,6 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
import org.sonar.api.batch.sensor.test.Coverage;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;
import org.sonar.api.config.Settings;

import java.io.Serializable;
@@ -102,23 +99,7 @@ public interface SensorContext {

// ------------ TESTS ------------

/**
* Create a new coverage report.
* Don't forget to call {@link Coverage#save()} once all parameters are provided.
*/
Coverage newCoverage();

/**
* Create a new test case execution report.
* Don't forget to call {@link TestCaseExecution#save()} once all parameters are provided.
*/
TestCaseExecution newTestCaseExecution();

/**
* Create a new test case coverage report.
* Don't forget to call {@link TestCaseCoverage#save()} once all parameters are provided.
*/
TestCaseCoverage newTestCaseCoverage();
// TODO

// ------------ DEPENDENCIES ------------


+ 0
- 6
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java View File

@@ -23,8 +23,6 @@ import org.sonar.api.batch.sensor.dependency.Dependency;
import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;
import org.sonar.api.batch.sensor.test.TestCaseExecution;

/**
* Interface for storing data computed by sensors.
@@ -38,10 +36,6 @@ public interface SensorStorage {

void store(Duplication duplication);

void store(TestCaseExecution testCaseExecution);

void store(Dependency dependency);

void store(TestCaseCoverage testCaseCoverage);

}

+ 0
- 103
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/Coverage.java View File

@@ -1,103 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test;

import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.measures.CoreMetrics;

/**
* @since 5.0
*/
public interface Coverage {

public enum CoverageType {
UNIT(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.COVERAGE_LINE_HITS_DATA, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS,
CoreMetrics.CONDITIONS_BY_LINE, CoreMetrics.COVERED_CONDITIONS_BY_LINE),
INTEGRATION(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_COVERAGE_LINE_HITS_DATA, CoreMetrics.IT_CONDITIONS_TO_COVER,
CoreMetrics.IT_UNCOVERED_CONDITIONS, CoreMetrics.IT_CONDITIONS_BY_LINE, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE),
OVERALL(CoreMetrics.OVERALL_LINES_TO_COVER, CoreMetrics.OVERALL_UNCOVERED_LINES, CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA, CoreMetrics.OVERALL_CONDITIONS_TO_COVER,
CoreMetrics.OVERALL_UNCOVERED_CONDITIONS, CoreMetrics.OVERALL_CONDITIONS_BY_LINE, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE);

private Metric<Integer> linesToCover;
private Metric<Integer> uncoveredLines;
private Metric<String> lineHitsData;
private Metric<Integer> conditionsToCover;
private Metric<Integer> uncoveredConditions;
private Metric<String> conditionsByLine;
private Metric<String> coveredConditionsByLine;

private CoverageType(Metric<Integer> linesToCover, Metric<Integer> uncoveredLines, Metric<String> lineHitsData, Metric<Integer> conditionsToCover,
Metric<Integer> uncoveredConditions, Metric<String> conditionsByLine, Metric<String> coveredConditionsByLine) {
this.linesToCover = linesToCover;
this.uncoveredLines = uncoveredLines;
this.lineHitsData = lineHitsData;
this.conditionsToCover = conditionsToCover;
this.uncoveredConditions = uncoveredConditions;
this.conditionsByLine = conditionsByLine;
this.coveredConditionsByLine = coveredConditionsByLine;
}

public Metric<Integer> linesToCover() {
return linesToCover;
}

public Metric<Integer> uncoveredLines() {
return uncoveredLines;
}

public Metric<String> lineHitsData() {
return lineHitsData;
}

public Metric<Integer> conditionsToCover() {
return conditionsToCover;
}

public Metric<Integer> uncoveredConditions() {
return uncoveredConditions;
}

public Metric<String> conditionsByLine() {
return conditionsByLine;
}

public Metric<String> coveredConditionsByLine() {
return coveredConditionsByLine;
}
}

/**
* The file you are storing coverage on.
*/
Coverage onFile(InputFile inputFile);

Coverage ofType(CoverageType type);

Coverage lineHits(int line, int hits);

Coverage conditions(int line, int conditions, int coveredConditions);

/**
* Call this method only once when your are done with defining the test case coverage.
*/
void save();

}

+ 0
- 77
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseCoverage.java View File

@@ -1,77 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test;

import org.sonar.api.batch.fs.InputFile;

import java.util.List;

/**
* Represents line coverage produced by a single test in a test file on a single main file.
* @since 5.0
*/
public interface TestCaseCoverage {

/**
* InputFile where this test is located.
*/
InputFile testFile();

/**
* Set file where this test is located. Mandatory.
*/
TestCaseCoverage testFile(InputFile testFile);

/**
* Name of this test case.
*/
String testName();

/**
* Set name of this test. Name is mandatory.
*/
TestCaseCoverage testName(String name);

/**
* InputFile covered by this test.
*/
InputFile coveredFile();

/**
* Set file covered by this test. Mandatory.
*/
TestCaseCoverage cover(InputFile mainFile);

/**
* List of line numbers (1-based) covered by this test.
*/
List<Integer> coveredLines();

/**
* Set list of line numbers (1-based) covered by this test. Mandatory.
*/
TestCaseCoverage onLines(List<Integer> lines);

/**
* Call this method only once when your are done with defining the test case coverage.
*/
void save();

}

+ 0
- 125
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseExecution.java View File

@@ -1,125 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test;

import org.sonar.api.batch.fs.InputFile;

import javax.annotation.Nullable;

/**
* Represents result of execution of a single test in a test file.
* @since 5.0
*/
public interface TestCaseExecution {

/**
* Test execution status.
*/
enum Status {
OK, FAILURE, ERROR, SKIPPED;

public static Status of(@Nullable String s) {
return s == null ? null : valueOf(s.toUpperCase());
}
}

/**
* Test type.
*/
enum Type {
UNIT, INTEGRATION;
}

/**
* InputFile where this test is located.
*/
InputFile testFile();

/**
* Set file where this test is located. Mandatory.
*/
TestCaseExecution inTestFile(InputFile testFile);

/**
* Duration in milliseconds
*/
Long durationInMs();

/**
* Duration in milliseconds
*/
TestCaseExecution durationInMs(long duration);

/**
* Name of this test case.
*/
String name();

/**
* Set name of this test. Name is mandatory.
*/
TestCaseExecution name(String name);

/**
* Status of execution of the test.
*/
Status status();

/**
* Status of execution of the test.
*/
TestCaseExecution status(Status status);

/**
* Message (usually in case of {@link Status#ERROR} or {@link Status#FAILURE}).
*/
String message();

/**
* Message (usually in case of {@link Status#ERROR} or {@link Status#FAILURE}).
*/
TestCaseExecution message(String message);

/**
* Type of test.
*/
Type type();

/**
* Type of test.
*/
TestCaseExecution ofType(Type type);

/**
* Stacktrace (usually in case of {@link Status#ERROR}).
*/
String stackTrace();

/**
* Set stacktrace (usually in case of {@link Status#ERROR}).
*/
TestCaseExecution stackTrace(String stackTrace);

/**
* Call this method only once when your are done with defining the test case execution.
*/
void save();

}

+ 0
- 153
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultCoverage.java View File

@@ -1,153 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.test.Coverage;
import org.sonar.api.utils.KeyValueFormat;

import java.util.SortedMap;

public final class DefaultCoverage implements Coverage {

private static final String INPUT_FILE_SHOULD_BE_NON_NULL = "InputFile should be non null";

private InputFile file;
private CoverageType type;
private int totalCoveredLines = 0, totalConditions = 0, totalCoveredConditions = 0;
private SortedMap<Integer, Integer> hitsByLine = Maps.newTreeMap();
private SortedMap<Integer, Integer> conditionsByLine = Maps.newTreeMap();
private SortedMap<Integer, Integer> coveredConditionsByLine = Maps.newTreeMap();

protected final transient SensorStorage storage;
private transient boolean saved = false;

public DefaultCoverage() {
this.storage = null;
}

public DefaultCoverage(SensorStorage storage) {
this.storage = storage;
}

@Override
public DefaultCoverage lineHits(int lineId, int hits) {
Preconditions.checkArgument(lineId >= 1, "Line number should be positive and non zero [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(hits >= 0, "Hits should be positive [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(!hitsByLine.containsKey(lineId), "Hits already saved on line [" + file.relativePath() + ":" + lineId + "]");
hitsByLine.put(lineId, hits);
if (hits > 0) {
totalCoveredLines += 1;
}
return this;
}

@Override
public DefaultCoverage conditions(int lineId, int conditions, int coveredConditions) {
Preconditions.checkArgument(lineId >= 1, "Line number should be positive and non zero [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(conditions >= 0, "Number of conditions should be positive [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(coveredConditions >= 0, "Number of covered conditions should be positive [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(conditions >= coveredConditions, "Number of covered conditions can't exceed conditions [" + file.relativePath() + ":" + lineId + "]");
Preconditions.checkArgument(!conditionsByLine.containsKey(lineId), "Conditions already saved on line [" + file.relativePath() + ":" + lineId + "]");
totalConditions += conditions;
totalCoveredConditions += coveredConditions;
conditionsByLine.put(lineId, conditions);
coveredConditionsByLine.put(lineId, coveredConditions);
return this;
}

public InputFile file() {
return file;
}

@Override
public DefaultCoverage onFile(InputFile inputFile) {
Preconditions.checkNotNull(inputFile, INPUT_FILE_SHOULD_BE_NON_NULL);
Preconditions.checkArgument(inputFile.type() == Type.MAIN, "Coverage is only supported on main files [" + inputFile.relativePath() + "]");
this.file = inputFile;
return this;
}

public CoverageType type() {
return type;
}

@Override
public DefaultCoverage ofType(CoverageType type) {
Preconditions.checkNotNull(type);
this.type = type;
return this;
}

@Override
public void save() {
Preconditions.checkNotNull(this.storage, "No persister on this object");
Preconditions.checkState(!saved, "This object was already saved");
Preconditions.checkNotNull(this.file, "File is mandatory on Coverage");
Preconditions.checkNotNull(this.type, "Type is mandatory on Coverage");

if (!hitsByLine.isEmpty()) {
new DefaultMeasure<Integer>(storage)
.onFile(file)
.forMetric(type.linesToCover())
.withValue(hitsByLine.size())
.save();
new DefaultMeasure<Integer>(storage)
.onFile(file)
.forMetric(type.uncoveredLines())
.withValue(hitsByLine.size() - totalCoveredLines)
.save();
new DefaultMeasure<String>(storage)
.onFile(file)
.forMetric(type.lineHitsData())
.withValue(KeyValueFormat.format(hitsByLine))
.save();
}
if (totalConditions > 0) {
new DefaultMeasure<Integer>(storage)
.onFile(file)
.forMetric(type.conditionsToCover())
.withValue(totalConditions)
.save();
new DefaultMeasure<Integer>(storage)
.onFile(file)
.forMetric(type.uncoveredConditions())
.withValue(totalConditions - totalCoveredConditions)
.save();
new DefaultMeasure<String>(storage)
.onFile(file)
.forMetric(type.coveredConditionsByLine())
.withValue(KeyValueFormat.format(coveredConditionsByLine))
.save();
new DefaultMeasure<String>(storage)
.onFile(file)
.forMetric(type.conditionsByLine())
.withValue(KeyValueFormat.format(conditionsByLine))
.save();
}
this.saved = true;
}

}

+ 0
- 138
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseCoverage.java View File

@@ -1,138 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import com.google.common.base.Preconditions;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.test.TestCaseCoverage;

import java.util.Collections;
import java.util.List;

public class DefaultTestCaseCoverage extends DefaultStorable implements TestCaseCoverage {

private InputFile testFile;
private InputFile mainFile;
private String name;
private List<Integer> lines;

public DefaultTestCaseCoverage() {
super(null);
}

public DefaultTestCaseCoverage(SensorStorage storage) {
super(storage);
}

@Override
public InputFile testFile() {
return testFile;
}

@Override
public DefaultTestCaseCoverage testFile(InputFile testFile) {
Preconditions.checkNotNull(testFile, "TestFile cannot be null");
Preconditions.checkArgument(testFile.type() == InputFile.Type.TEST, "Should be a test file: " + testFile);
this.testFile = testFile;
return this;
}

@Override
public InputFile coveredFile() {
return mainFile;
}

@Override
public DefaultTestCaseCoverage cover(InputFile mainFile) {
Preconditions.checkNotNull(mainFile, "InputFile cannot be null");
Preconditions.checkArgument(mainFile.type() == InputFile.Type.MAIN, "Should be a main file: " + mainFile);
this.mainFile = mainFile;
return this;
}

@Override
public DefaultTestCaseCoverage testName(String name) {
Preconditions.checkArgument(StringUtils.isNotBlank(name), "Test name is mandatory and should not be blank");
this.name = name;
return this;
}

@Override
public String testName() {
return name;
}

@Override
public List<Integer> coveredLines() {
return Collections.unmodifiableList(lines);
}

@Override
public DefaultTestCaseCoverage onLines(List<Integer> lines) {
Preconditions.checkNotNull(lines, "Lines list cannot be null");
Preconditions.checkArgument(!lines.isEmpty(), "No need to register test coverage if no line is covered");
this.lines = lines;
return this;
}

@Override
public void doSave() {
Preconditions.checkNotNull(testFile, "TestFile is mandatory");
Preconditions.checkNotNull(mainFile, "MainFile is mandatory");
Preconditions.checkNotNull(name, "Test name is mandatory");
Preconditions.checkNotNull(lines, "Lines are mandatory");
storage.store(this);
}

// Just for unit tests
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
DefaultTestCaseCoverage rhs = (DefaultTestCaseCoverage) obj;
return new EqualsBuilder()
.append(testFile, rhs.testFile)
.append(name, rhs.name)
.append(mainFile, rhs.mainFile)
.append(lines.toArray(), rhs.lines.toArray())
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(13, 43)
.append(testFile)
.append(name)
.append(mainFile)
.toHashCode();
}
}

+ 0
- 181
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseExecution.java View File

@@ -1,181 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import com.google.common.base.Preconditions;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.test.TestCaseExecution;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

public class DefaultTestCaseExecution extends DefaultStorable implements TestCaseExecution {

private InputFile testFile;
private String name;
private Long duration;
private TestCaseExecution.Status status = Status.OK;
private String message;
private TestCaseExecution.Type type = Type.UNIT;
private String stackTrace;

public DefaultTestCaseExecution() {
super(null);
}

public DefaultTestCaseExecution(SensorStorage storage) {
super(storage);
}

@Override
public DefaultTestCaseExecution inTestFile(InputFile testFile) {
Preconditions.checkNotNull(testFile, "TestFile cannot be null");
Preconditions.checkArgument(testFile.type() == InputFile.Type.TEST, "Should be a test file: " + testFile);
this.testFile = testFile;
return this;
}

@Override
public DefaultTestCaseExecution name(String name) {
Preconditions.checkArgument(StringUtils.isNotBlank(name), "Test name is mandatory and should not be blank");
this.name = name;
return this;
}

@Override
public DefaultTestCaseExecution durationInMs(long duration) {
Preconditions.checkArgument(duration >= 0, "Test duration must be positive (got: " + duration + ")");
this.duration = duration;
return this;
}

@Override
public DefaultTestCaseExecution status(TestCaseExecution.Status status) {
Preconditions.checkNotNull(status);
this.status = status;
return this;
}

@Override
public DefaultTestCaseExecution message(@Nullable String message) {
this.message = message;
return this;
}

@Override
public DefaultTestCaseExecution ofType(TestCaseExecution.Type type) {
Preconditions.checkNotNull(type);
this.type = type;
return this;
}

@Override
public DefaultTestCaseExecution stackTrace(@Nullable String stackTrace) {
this.stackTrace = stackTrace;
return this;
}

@Override
public InputFile testFile() {
return testFile;
}

@CheckForNull
@Override
public Long durationInMs() {
return duration;
}

@Override
public Type type() {
return type;
}

@Override
public Status status() {
return status;
}

@Override
public String name() {
return name;
}

@CheckForNull
@Override
public String message() {
return message;
}

@CheckForNull
@Override
public String stackTrace() {
return stackTrace;
}

@Override
public void doSave() {
Preconditions.checkNotNull(testFile, "TestFile is mandatory");
Preconditions.checkNotNull(name, "Test name is mandatory");
storage.store(this);
}

// Just for unit tests
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
DefaultTestCaseExecution rhs = (DefaultTestCaseExecution) obj;
return new EqualsBuilder()
.append(testFile, rhs.testFile)
.append(name, rhs.name)
.append(duration, rhs.duration)
.append(status, rhs.status)
.append(message, rhs.message)
.append(type, rhs.type)
.append(stackTrace, rhs.stackTrace)
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(13, 43)
.append(testFile)
.append(name)
.append(duration)
.append(status)
.append(message)
.append(type)
.append(stackTrace)
.toHashCode();
}
}

+ 0
- 22
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java View File

@@ -1,22 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.api.batch.sensor.test.internal;


+ 0
- 22
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/package-info.java View File

@@ -1,22 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.api.batch.sensor.test;


+ 0
- 274
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultCoverageTest.java View File

@@ -1,274 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.test.Coverage.CoverageType;
import org.sonar.api.measures.CoreMetrics;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

public class DefaultCoverageTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

private InputFile main = new DefaultInputFile("foo", "src/Foo.php").setType(InputFile.Type.MAIN);

@Test
public void testCreation() {
DefaultCoverage coverage = new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, 2)
.lineHits(2, 5)
.conditions(1, 2, 1);

assertThat(coverage.file()).isEqualTo(main);
assertThat(coverage.type()).isEqualTo(CoverageType.UNIT);
}

@Test
public void testSaveLines() {
SensorStorage storage = mock(SensorStorage.class);
new DefaultCoverage(storage)
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, 2)
.lineHits(2, 5)
.lineHits(3, 0)
.lineHits(4, 0)
.save();

verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.LINES_TO_COVER)
.withValue(4));
verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.UNCOVERED_LINES)
.withValue(2));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA)
.withValue("1=2;2=5;3=0;4=0"));
verifyNoMoreInteractions(storage);
}

@Test
public void testSaveConditions() {
SensorStorage storage = mock(SensorStorage.class);
new DefaultCoverage(storage)
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(1, 2, 1)
.save();

verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.CONDITIONS_TO_COVER)
.withValue(2));
verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.UNCOVERED_CONDITIONS)
.withValue(1));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
.withValue("1=1"));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.CONDITIONS_BY_LINE)
.withValue("1=2"));
verifyNoMoreInteractions(storage);
}

@Test
public void testSaveLinesAndConditions() {
SensorStorage storage = mock(SensorStorage.class);
new DefaultCoverage(storage)
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, 2)
.lineHits(2, 5)
.lineHits(3, 0)
.lineHits(4, 0)
.conditions(1, 2, 1)
.save();

verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.LINES_TO_COVER)
.withValue(4));
verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.UNCOVERED_LINES)
.withValue(2));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.COVERAGE_LINE_HITS_DATA)
.withValue("1=2;2=5;3=0;4=0"));
verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.CONDITIONS_TO_COVER)
.withValue(2));
verify(storage).store(new DefaultMeasure<Integer>()
.onFile(main)
.forMetric(CoreMetrics.UNCOVERED_CONDITIONS)
.withValue(1));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
.withValue("1=1"));
verify(storage).store(new DefaultMeasure<String>()
.onFile(main)
.forMetric(CoreMetrics.CONDITIONS_BY_LINE)
.withValue("1=2"));
verifyNoMoreInteractions(storage);
}

@Test
public void dontSaveTwice() {
SensorStorage storage = mock(SensorStorage.class);
DefaultCoverage coverage = new DefaultCoverage(storage)
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, 2)
.lineHits(2, 5)
.lineHits(3, 0)
.lineHits(4, 0);
coverage.save();

thrown.expect(IllegalStateException.class);
thrown.expectMessage("This object was already saved");

coverage.save();
}

@Test
public void fileIsMain() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Coverage is only supported on main files [test/FooTest.php]");

new DefaultCoverage()
.onFile(new DefaultInputFile("foo", "test/FooTest.php").setType(InputFile.Type.TEST))
.ofType(CoverageType.UNIT);
}

@Test
public void lineHitsValidation() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Line number should be positive and non zero [src/Foo.php:0]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(0, 2);
}

@Test
public void hitsPositive() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Hits should be positive [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, -1);
}

@Test
public void hitsNoDuplicate() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Hits already saved on line [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.lineHits(1, 2)
.lineHits(1, 1);
}

@Test
public void lineConditionValidation() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Line number should be positive and non zero [src/Foo.php:0]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(0, 2, 2);
}

@Test
public void conditionsPositive() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Number of conditions should be positive [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(1, -1, 0);
}

@Test
public void coveredConditionsPositive() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Number of covered conditions should be positive [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(1, 1, -1);
}

@Test
public void coveredConditionsVsConditions() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Number of covered conditions can't exceed conditions [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(1, 2, 3);
}

@Test
public void conditionsNoDuplicate() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Conditions already saved on line [src/Foo.php:1]");

new DefaultCoverage()
.onFile(main)
.ofType(CoverageType.UNIT)
.conditions(1, 4, 3)
.conditions(1, 4, 2);
}

}

+ 0
- 83
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseCoverageTest.java View File

@@ -1,83 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;

import java.util.Arrays;

import static org.assertj.core.api.Assertions.assertThat;

public class DefaultTestCaseCoverageTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

private InputFile mainFile = new DefaultInputFile("foo", "src/Foo.php").setType(InputFile.Type.MAIN);
private InputFile testFile = new DefaultInputFile("foo", "test/FooTest.php").setType(InputFile.Type.TEST);

@Test
public void testCreation() throws Exception {
DefaultTestCaseCoverage testCaseCoverage = new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("myTest")
.cover(mainFile)
.onLines(Arrays.asList(1, 2, 3));

assertThat(testCaseCoverage.testName()).isEqualTo("myTest");
assertThat(testCaseCoverage.testFile()).isEqualTo(testFile);
assertThat(testCaseCoverage.coveredFile()).isEqualTo(mainFile);
assertThat(testCaseCoverage.coveredLines()).containsExactly(1, 2, 3);
}

@Test
public void testEqualsHashCodeToString() {
DefaultTestCaseCoverage testCaseCoverage1 = new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("myTest")
.cover(mainFile)
.onLines(Arrays.asList(1, 2, 3));
DefaultTestCaseCoverage testCaseCoverage1a = new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("myTest")
.cover(mainFile)
.onLines(Arrays.asList(1, 2, 3));
DefaultTestCaseCoverage testCaseCoverage2 = new DefaultTestCaseCoverage()
.testFile(testFile)
.testName("myTest2")
.cover(mainFile)
.onLines(Arrays.asList(1, 3, 3));

assertThat(testCaseCoverage1).isEqualTo(testCaseCoverage1);
assertThat(testCaseCoverage1).isEqualTo(testCaseCoverage1a);
assertThat(testCaseCoverage1).isNotEqualTo(testCaseCoverage2);
assertThat(testCaseCoverage1).isNotEqualTo(null);
assertThat(testCaseCoverage1).isNotEqualTo("foo");

assertThat(testCaseCoverage1.toString())
.isEqualTo(
"DefaultTestCaseCoverage[testFile=[moduleKey=foo, relative=test/FooTest.php, basedir=null],mainFile=[moduleKey=foo, relative=src/Foo.php, basedir=null],name=myTest,lines=[1, 2, 3]]");
assertThat(testCaseCoverage1.hashCode()).isEqualTo(testCaseCoverage1a.hashCode());
}
}

+ 0
- 123
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseExecutionTest.java View File

@@ -1,123 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.test.internal;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.test.TestCaseExecution.Status;
import org.sonar.api.batch.sensor.test.TestCaseExecution.Type;

import static org.assertj.core.api.Assertions.assertThat;

public class DefaultTestCaseExecutionTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

private InputFile parent = new DefaultInputFile("foo", "src/Foo.php").setType(InputFile.Type.TEST);

@Test
public void testCreation() throws Exception {
DefaultTestCaseExecution testCase = new DefaultTestCaseExecution(null)
.inTestFile(parent)
.name("myTest")
.durationInMs(1)
.message("message")
.stackTrace("stack")
.status(Status.ERROR)
.ofType(Type.UNIT);

assertThat(testCase.name()).isEqualTo("myTest");
assertThat(testCase.testFile()).isEqualTo(parent);
assertThat(testCase.durationInMs()).isEqualTo(1L);
assertThat(testCase.message()).isEqualTo("message");
assertThat(testCase.stackTrace()).isEqualTo("stack");
assertThat(testCase.status()).isEqualTo(Status.ERROR);
assertThat(testCase.type()).isEqualTo(Type.UNIT);
}

@Test
public void testCreationWithDefaultValues() throws Exception {
DefaultTestCaseExecution testCase = new DefaultTestCaseExecution(null)
.inTestFile(parent)
.name("myTest");

assertThat(testCase.name()).isEqualTo("myTest");
assertThat(testCase.testFile()).isEqualTo(parent);
assertThat(testCase.durationInMs()).isNull();
assertThat(testCase.message()).isNull();
assertThat(testCase.stackTrace()).isNull();
assertThat(testCase.status()).isEqualTo(Status.OK);
assertThat(testCase.type()).isEqualTo(Type.UNIT);
}

@Test
public void testInvalidDuration() throws Exception {
DefaultTestCaseExecution builder = new DefaultTestCaseExecution(null)
.inTestFile(parent)
.name("myTest");

thrown.expect(IllegalArgumentException.class);

builder.durationInMs(-3);
}

@Test
public void testEqualsHashCodeToString() {
DefaultTestCaseExecution testCase1 = new DefaultTestCaseExecution(null)
.inTestFile(parent)
.name("myTest")
.durationInMs(1)
.message("message")
.stackTrace("stack")
.status(Status.ERROR)
.ofType(Type.UNIT);
DefaultTestCaseExecution testCase1a = new DefaultTestCaseExecution(null)
.inTestFile(parent)
.name("myTest")
.durationInMs(1)
.message("message")
.stackTrace("stack")
.status(Status.ERROR)
.ofType(Type.UNIT);
DefaultTestCaseExecution testCase2 = new DefaultTestCaseExecution(null)
.inTestFile(new DefaultInputFile("foo2", "src/Foo.php").setType(InputFile.Type.TEST))
.name("myTest2")
.durationInMs(2)
.message("message2")
.stackTrace("null")
.status(Status.FAILURE)
.ofType(Type.INTEGRATION);

assertThat(testCase1).isEqualTo(testCase1);
assertThat(testCase1).isEqualTo(testCase1a);
assertThat(testCase1).isNotEqualTo(testCase2);
assertThat(testCase1).isNotEqualTo(null);
assertThat(testCase1).isNotEqualTo("foo");

assertThat(testCase1.toString()).isEqualTo(
"DefaultTestCaseExecution[testFile=[moduleKey=foo, relative=src/Foo.php, basedir=null],name=myTest,duration=1,status=ERROR,message=message,type=UNIT,stackTrace=stack]");
assertThat(testCase1.hashCode()).isEqualTo(testCase1a.hashCode());
}

}

Loading…
Cancel
Save