*/
package org.sonar.plugins.core.sensors;
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.junit.Rule;
import org.junit.Test;
@Test
public void store_file_hashes() throws Exception {
when(fileCache.filesByModule("struts")).thenReturn(Lists.<InputFile>newArrayList(
- new DeprecatedDefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
- new DeprecatedDefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
+ new DeprecatedDefaultInputFile("foo", "src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
+ new DeprecatedDefaultInputFile("foo", "src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
SensorContext sensorContext = mock(SensorContext.class);
sensor.analyse(project, sensorContext);
public void store_file_hashes_for_branches() throws Exception {
project = new Project("struts", "branch-2.x", "Struts 2.x");
when(fileCache.filesByModule("struts:branch-2.x")).thenReturn(Lists.<InputFile>newArrayList(
- new DeprecatedDefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
- new DeprecatedDefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
+ new DeprecatedDefaultInputFile("foo", "src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
+ new DeprecatedDefaultInputFile("foo", "src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
SensorContext sensorContext = mock(SensorContext.class);
sensor.analyse(project, sensorContext);
@Before
public void before() throws IOException {
when(context.measureBuilder()).thenReturn(new DefaultMeasureBuilder());
- inputFile = new DeprecatedDefaultInputFile("src/main/java/Foo.java");
+ inputFile = new DeprecatedDefaultInputFile("foo", "src/main/java/Foo.java");
duplicationBuilder = spy(new DefaultDuplicationBuilder(inputFile));
when(context.duplicationBuilder(any(InputFile.class))).thenReturn(duplicationBuilder);
inputFile.setFile(temp.newFile("Foo.java"));
- inputFile.setKey("key1");
contextFactory = mock(FileLinesContextFactory.class);
linesContext = mock(FileLinesContext.class);
when(contextFactory.createFor(inputFile)).thenReturn(linesContext);
inOrder.verify(duplicationBuilder).build();
verify(context).saveDuplications(inputFile, Arrays.asList(
- new DuplicationGroup(new DuplicationGroup.Block("key1", 5, 200))
+ new DuplicationGroup(new DuplicationGroup.Block("foo:src/main/java/Foo.java", 5, 200))
.addDuplicate(new DuplicationGroup.Block("key2", 15, 200))
.addDuplicate(new DuplicationGroup.Block("key3", 25, 200))
));
package org.sonar.xoo;
import org.sonar.api.SonarPlugin;
+import org.sonar.xoo.lang.CoveragePerTestSensor;
import org.sonar.xoo.lang.MeasureSensor;
import org.sonar.xoo.lang.ScmActivitySensor;
import org.sonar.xoo.lang.SymbolReferencesSensor;
import org.sonar.xoo.lang.SyntaxHighlightingSensor;
+import org.sonar.xoo.lang.TestCaseSensor;
import org.sonar.xoo.lang.XooTokenizerSensor;
import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor;
SyntaxHighlightingSensor.class,
SymbolReferencesSensor.class,
XooTokenizerSensor.class,
+ TestCaseSensor.class,
+ CoveragePerTestSensor.class,
OneIssuePerLineSensor.class,
OneIssueOnDirPerFileSensor.class,
--- /dev/null
+/*
+ * 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.TestCase;
+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 = LoggerFactory.getLogger(CoveragePerTestSensor.class);
+
+ private static final String COVER_PER_TEST_EXTENSION = ".coveragePerTest";
+
+ private void processCoveragePerTest(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File testPlanFile = new File(ioFile.getParentFile(), ioFile.getName() + COVER_PER_TEST_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, context, line, inputFile);
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ private void processLine(File testplanFile, 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));
+ List<Integer> coveredLines = new ArrayList<Integer>();
+ Iterator<String> lines = Splitter.on(",").split(split.next()).iterator();
+ while (lines.hasNext()) {
+ coveredLines.add(Integer.parseInt(lines.next()));
+ }
+ TestCase testCase = context.getTestCase(testFile, testCaseName);
+ if (testCase == null) {
+ throw new IllegalStateException("No test case with name " + testCaseName + " on file " + testFile);
+ }
+ context.saveCoveragePerTest(testCase, mainFile, coveredLines);
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + testplanFile.getAbsolutePath(), e);
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Coverage Per Test Sensor")
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(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);
+ }
+ }
+}
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.symbol.Symbol;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
-import org.sonar.api.measures.CoreMetrics;
import org.sonar.xoo.Xoo;
import java.io.File;
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo Symbol Reference Sensor")
- .provides(CoreMetrics.LINES)
.workOnLanguages(Xoo.KEY)
.workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
}
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-import org.sonar.api.measures.CoreMetrics;
import org.sonar.xoo.Xoo;
import java.io.File;
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo Highlighting Sensor")
- .provides(CoreMetrics.LINES)
.workOnLanguages(Xoo.KEY)
.workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
}
--- /dev/null
+/*
+ * 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.TestCase;
+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 = LoggerFactory.getLogger(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();
+ long duration = Long.parseLong(split.next());
+ context.addTestCase(context.testCaseBuilder(testFile, name)
+ .type(TestCase.Type.valueOf(type))
+ .status(TestCase.Status.valueOf(status))
+ .message(message)
+ .stackTrace(stack)
+ .durationInMs(duration)
+ .build());
+ } 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")
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(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);
+ }
+ }
+}
@Test
public void provide_extensions() {
- assertThat(new XooPlugin().getExtensions()).hasSize(11);
+ assertThat(new XooPlugin().getExtensions()).hasSize(13);
}
}
@Test
public void testNoExecutionIfNoMeasureFile() {
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
sensor.execute(context);
}
public void testExecution() throws IOException {
File measures = new File(baseDir, "src/foo.xoo.measures");
FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\ncomment_lines_data:1=1,2=1\n\n#comment");
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
Metric<Boolean> booleanMetric = new Metric.Builder("bool", "Bool", Metric.ValueType.BOOL)
public void failIfMetricNotFound() throws IOException {
File measures = new File(baseDir, "src/foo.xoo.measures");
FileUtils.write(measures, "unknow:12\n\n#comment");
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
when(context.measureBuilder()).thenReturn(new DefaultMeasureBuilder());
@Test
public void testNoExecutionIfNoSymbolFile() {
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
sensor.execute(context);
}
public void testExecution() throws IOException {
File symbol = new File(baseDir, "src/foo.xoo.symbol");
FileUtils.write(symbol, "1,4,7\n12,15,23\n\n#comment");
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
SymbolTableBuilder symbolTableBuilder = mock(SymbolTableBuilder.class);
when(context.symbolTableBuilder(inputFile)).thenReturn(symbolTableBuilder);
@Test
public void testNoExecutionIfNoSyntaxFile() {
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
sensor.execute(context);
}
public void testExecution() throws IOException {
File symbol = new File(baseDir, "src/foo.xoo.highlighting");
FileUtils.write(symbol, "1:4:k\n12:15:cppd\n\n#comment");
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
HighlightingBuilder builder = mock(HighlightingBuilder.class);
when(context.highlightingBuilder(inputFile)).thenReturn(builder);
@Test
public void testNoExecutionIfExclusion() {
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
settings.setProperty(CoreProperties.CPD_EXCLUSIONS, "**/foo.xoo");
sensor.execute(context);
public void testExecution() throws IOException {
File source = new File(baseDir, "src/foo.xoo");
FileUtils.write(source, "token1 token2 token3\ntoken4");
- DefaultInputFile inputFile = new DefaultInputFile("src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo");
fileSystem.add(inputFile);
DuplicationTokenBuilder builder = mock(DuplicationTokenBuilder.class);
when(context.duplicationTokenBuilder(inputFile)).thenReturn(builder);
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.symbol.Symbol;
+import org.sonar.api.batch.sensor.test.TestCase;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.batch.scan2.ProjectScanContainer;
import org.sonar.batch.scan2.ScanTaskObserver;
import org.sonar.batch.symbol.SymbolData;
+import org.sonar.batch.test.CoveragePerTestCache;
+import org.sonar.batch.test.TestCaseCache;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.RemotePlugin;
import org.sonar.core.source.SnapshotDataTypes;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
private List<InputDir> inputDirs = new ArrayList<InputDir>();
private Map<InputFile, SyntaxHighlightingData> highlightingPerFile = new HashMap<InputFile, SyntaxHighlightingData>();
private Map<InputFile, SymbolData> symbolTablePerFile = new HashMap<InputFile, SymbolData>();
+ private Map<String, Map<String, TestCase>> testCasesPerFile = new HashMap<String, Map<String, TestCase>>();
+ private Map<String, Map<String, Map<String, List<Integer>>>> coveragePerTest = new HashMap<String, Map<String, Map<String, List<Integer>>>>();
@Override
public void scanTaskCompleted(ProjectScanContainer container) {
duplications.put(effectiveKey, entry.value());
}
+ TestCaseCache testCaseCache = container.getComponentByType(TestCaseCache.class);
+ for (Entry<TestCase> entry : testCaseCache.entries()) {
+ String effectiveKey = entry.key()[0].toString();
+ if (!testCasesPerFile.containsKey(effectiveKey)) {
+ testCasesPerFile.put(effectiveKey, new HashMap<String, TestCase>());
+ }
+ testCasesPerFile.get(effectiveKey).put(entry.value().name(), entry.value());
+ }
+
+ CoveragePerTestCache coveragePerTestCache = container.getComponentByType(CoveragePerTestCache.class);
+ for (Entry<List<Integer>> entry : coveragePerTestCache.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>>());
+ }
+ coveragePerTest.get(testFileKey).get(testName).put(entry.key()[2].toString(), entry.value());
+ }
}
public List<Issue> issues() {
return duplications.get(((DefaultInputFile) inputFile).key());
}
+ public Collection<TestCase> testCasesFor(InputFile inputFile) {
+ String key = ((DefaultInputFile) inputFile).key();
+ if (testCasesPerFile.containsKey(key)) {
+ return testCasesPerFile.get(key).values();
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public TestCase 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
*/
package org.sonar.batch.scan;
+import com.google.common.base.Preconditions;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
+import org.sonar.api.batch.sensor.test.TestCase;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issuable;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
+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.BlockCache;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.scan2.BaseSensorContext;
import java.io.Serializable;
+import java.util.List;
/**
* Implements {@link SensorContext} but forward everything to {@link org.sonar.api.batch.SensorContext} for backward compatibility.
.build();
}
+ @Override
+ public void addTestCase(TestCase testCase) {
+ File testRes = getTestResource(((DefaultTestCase) testCase).testFile());
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
+ 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 TestCase getTestCase(InputFile testFile, String testCaseName) {
+ File testRes = getTestResource(testFile);
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
+ Iterable<MutableTestCase> testCases = testPlan.testCasesByName(testCaseName);
+ if (testCases.iterator().hasNext()) {
+ MutableTestCase testCase = testCases.iterator().next();
+ return new DefaultTestCase(testFile, testCaseName, testCase.durationInMs(), TestCase.Status.of(testCase.status().name()), testCase.message(), TestCase.Type.valueOf(testCase
+ .type()), testCase.stackTrace());
+ }
+ return null;
+ }
+
+ @Override
+ public void saveCoveragePerTest(TestCase testCase, InputFile coveredFile, List<Integer> coveredLines) {
+ Preconditions.checkArgument(coveredFile.type() == Type.MAIN, "Should be a main file: " + coveredFile);
+ File testRes = getTestResource(((DefaultTestCase) testCase).testFile());
+ File mainRes = getMainResource(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(testCase.name())) {
+ mutableTestCase.setCoverageBlock(testAbleFile, 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);
+ // Reload
+ testRes = sensorContext.getResource(testRes);
+ if (testRes == null) {
+ throw new IllegalArgumentException("Provided input file is not indexed or not a test file: " + testFile);
+ }
+ return testRes;
+ }
+
+ private File getMainResource(InputFile mainFile) {
+ File mainRes = File.create(mainFile.relativePath());
+ // Reload
+ mainRes = sensorContext.getResource(mainRes);
+ if (mainRes == null) {
+ throw new IllegalArgumentException("Provided input file is not indexed or not a main file: " + mainRes);
+ }
+ return mainRes;
+ }
+
}
@Override
public void put(Value value, Object object, CoderContext context) {
DeprecatedDefaultInputFile f = (DeprecatedDefaultInputFile) object;
+ putUTFOrNull(value, f.moduleKey());
putUTFOrNull(value, f.relativePath());
value.putString(f.getFileBaseDir().toString());
putUTFOrNull(value, f.deprecatedKey());
value.putString(f.status().name());
putUTFOrNull(value, f.hash());
value.put(f.lines());
- putUTFOrNull(value, f.key());
}
private void putUTFOrNull(Value value, @Nullable String utfOrNull) {
@Override
public Object get(Value value, Class clazz, CoderContext context) {
- DeprecatedDefaultInputFile file = new DeprecatedDefaultInputFile(value.getString());
+ String moduleKey = value.getString();
+ DeprecatedDefaultInputFile file = new DeprecatedDefaultInputFile(moduleKey, value.getString());
file.setBasedir(new File(value.getString()));
file.setDeprecatedKey(value.getString());
file.setSourceDirAbsolutePath(value.getString());
file.setStatus(InputFile.Status.valueOf(value.getString()));
file.setHash(value.getString());
file.setLines(value.getInt());
- file.setKey(value.getString());
return file;
}
File parentDir = inputFile.file().getParentFile();
String relativePath = new PathResolver().relativePath(fs.baseDir(), parentDir);
if (relativePath != null) {
- DefaultInputDir inputDir = new DefaultInputDir(relativePath);
+ DefaultInputDir inputDir = new DefaultInputDir(fs.moduleKey(), relativePath);
inputDir.setFile(parentDir);
- inputDir.setKey(new StringBuilder().append(fs.moduleKey()).append(":").append(inputDir.relativePath()).toString());
status.markAsIndexed(inputDir);
}
}
LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.getAbsolutePath(), fs.baseDir());
return null;
}
- DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile(relativePath);
+ DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile(moduleKey, relativePath);
inputFile.setBasedir(fs.baseDir());
inputFile.setFile(file);
return inputFile;
@CheckForNull
DeprecatedDefaultInputFile complete(DeprecatedDefaultInputFile inputFile, InputFile.Type type) {
inputFile.setType(type);
- inputFile.setKey(new StringBuilder().append(moduleKey).append(":").append(inputFile.relativePath()).toString());
inputFile.setBasedir(fs.baseDir());
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(inputFile.file(), fs.encoding());
inputFile.setLines(metadata.lines);
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;
/**
* Cache of all measures. This cache is shared amongst all project modules.
// project key -> component key -> metric key -> measure
private final Cache<DefaultMeasure> cache;
- public AnalyzerMeasureCache(Caches caches, MetricFinder metricFinder) {
- caches.registerValueCoder(DefaultMeasure.class, new DefaultMeasureValueCoder(metricFinder));
+ public AnalyzerMeasureCache(Caches caches, MetricFinder metricFinder, InputPathCache inputPathCache) {
+ caches.registerValueCoder(DefaultMeasure.class, new DefaultMeasureValueCoder(metricFinder, inputPathCache));
cache = caches.createCache("measures");
}
import org.sonar.api.batch.sensor.measure.MeasureBuilder;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.batch.sensor.test.TestCaseBuilder;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseBuilder;
import org.sonar.api.config.Settings;
import org.sonar.batch.duplication.BlockCache;
import org.sonar.batch.duplication.DefaultTokenBuilder;
}
}
+ @Override
+ public TestCaseBuilder testCaseBuilder(InputFile testFile, String testCaseName) {
+ return new DefaultTestCaseBuilder(testFile, testCaseName);
+ }
+
}
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.measure.Metric;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import java.io.Serializable;
class DefaultMeasureValueCoder implements ValueCoder {
- private MetricFinder metricFinder;
+ private final MetricFinder metricFinder;
+ private final InputPathCache inputPathCache;
- public DefaultMeasureValueCoder(MetricFinder metricFinder) {
+ public DefaultMeasureValueCoder(MetricFinder metricFinder, InputPathCache inputPathCache) {
this.metricFinder = metricFinder;
+ this.inputPathCache = inputPathCache;
}
@Override
public void put(Value value, Object object, CoderContext context) {
DefaultMeasure m = (DefaultMeasure) object;
- value.put(m.inputFile());
+ DefaultInputFile inputFile = (DefaultInputFile) m.inputFile();
+ if (inputFile != null) {
+ value.putString(inputFile.moduleKey());
+ value.putString(inputFile.relativePath());
+ } else {
+ value.putNull();
+ }
value.putUTF(m.metric().key());
value.put(m.value());
}
@Override
public Object get(Value value, Class clazz, CoderContext context) {
DefaultMeasureBuilder builder = new DefaultMeasureBuilder();
- InputFile f = (InputFile) value.get();
- if (f != null) {
+ String moduleKey = value.getString();
+ if (moduleKey != null) {
+ String relativePath = value.getString();
+ InputFile f = inputPathCache.getFile(moduleKey, relativePath);
builder.onFile(f);
} else {
builder.onProject();
*/
package org.sonar.batch.scan2;
+import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.batch.sensor.test.TestCase;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
import org.sonar.api.config.Settings;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.issue.IssueFilters;
import org.sonar.batch.scan.SensorContextAdaptor;
+import org.sonar.batch.test.CoveragePerTestCache;
+import org.sonar.batch.test.TestCaseCache;
import org.sonar.core.component.ComponentKeys;
import java.io.Serializable;
+import java.util.List;
public class DefaultSensorContext extends BaseSensorContext {
private final ProjectDefinition def;
private final ActiveRules activeRules;
private final IssueFilters issueFilters;
+ private final TestCaseCache testCaseCache;
+ private final CoveragePerTestCache coveragePerTestCache;
public DefaultSensorContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, AnalyzerIssueCache issueCache,
Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache,
- BlockCache blockCache, DuplicationCache duplicationCache) {
+ BlockCache blockCache, DuplicationCache duplicationCache, TestCaseCache testCaseCache, CoveragePerTestCache coveragePerTestCache) {
super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache);
this.def = def;
this.measureCache = measureCache;
this.issueCache = issueCache;
this.activeRules = activeRules;
this.issueFilters = issueFilters;
+ this.testCaseCache = testCaseCache;
+ this.coveragePerTestCache = coveragePerTestCache;
}
@Override
}
}
+ @Override
+ public void addTestCase(TestCase testCase) {
+ if (testCaseCache.contains(((DefaultTestCase) testCase).testFile(), testCase.name())) {
+ throw new IllegalArgumentException("There is already a test case with the same name: " + testCase.name());
+ }
+ testCaseCache.put(((DefaultTestCase) testCase).testFile(), testCase);
+ }
+
+ @Override
+ public TestCase getTestCase(InputFile testFile, String testCaseName) {
+ return testCaseCache.get(testFile, testCaseName);
+ }
+
+ @Override
+ public void saveCoveragePerTest(TestCase testCase, InputFile coveredFile, List<Integer> coveredLines) {
+ Preconditions.checkNotNull(testCase);
+ Preconditions.checkArgument(coveredFile.type() == Type.MAIN, "Should be a main file: " + coveredFile);
+ coveragePerTestCache.put(testCase, coveredFile, coveredLines);
+ }
+
}
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
+import org.sonar.batch.test.CoveragePerTestCache;
+import org.sonar.batch.test.TestCaseCache;
public class ProjectScanContainer extends ComponentContainer {
public ProjectScanContainer(ComponentContainer taskContainer) {
// issues
AnalyzerIssueCache.class,
+ // Syntax highlighting and symbols
ComponentDataCache.class,
// Duplications
BlockCache.class,
DuplicationCache.class,
+ // Tests
+ TestCaseCache.class,
+ CoveragePerTestCache.class,
+
ScanTaskObservers.class);
}
--- /dev/null
+/*
+ * 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.TestCase;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
+import org.sonar.batch.index.Cache;
+import org.sonar.batch.index.Cache.Entry;
+import org.sonar.batch.index.Caches;
+
+import javax.annotation.CheckForNull;
+
+import java.util.List;
+
+/**
+ * Cache of coverage per test. This cache is shared amongst all project modules.
+ */
+public class CoveragePerTestCache implements BatchComponent {
+
+ private final Cache<List<Integer>> cache;
+
+ public CoveragePerTestCache(Caches caches) {
+ cache = caches.createCache("coveragePerTest");
+ }
+
+ public Iterable<Entry<List<Integer>>> entries() {
+ return cache.entries();
+ }
+
+ @CheckForNull
+ public List<Integer> getCoveredLines(InputFile testFile, String testCaseName, InputFile mainFile) {
+ Preconditions.checkNotNull(testFile);
+ Preconditions.checkNotNull(testCaseName);
+ return cache.get(((DefaultInputFile) testFile).key(), testCaseName, ((DefaultInputFile) mainFile).key());
+ }
+
+ public CoveragePerTestCache put(TestCase testCase, InputFile mainFile, List<Integer> coveredLines) {
+ Preconditions.checkNotNull(testCase);
+ Preconditions.checkNotNull(mainFile);
+ Preconditions.checkNotNull(coveredLines);
+ cache.put(((DefaultInputFile) ((DefaultTestCase) testCase).testFile()).key(), testCase.name(), ((DefaultInputFile) mainFile).key(), coveredLines);
+ return this;
+ }
+
+}
--- /dev/null
+/*
+ * 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.TestCase;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
+import org.sonar.batch.scan.filesystem.InputPathCache;
+
+import javax.annotation.Nullable;
+
+class DefaultTestCaseValueCoder implements ValueCoder {
+
+ private InputPathCache inputPathCache;
+
+ public DefaultTestCaseValueCoder(InputPathCache inputPathCache) {
+ this.inputPathCache = inputPathCache;
+ }
+
+ public void put(Value value, Object object, CoderContext context) {
+ DefaultTestCase t = (DefaultTestCase) 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();
+ }
+ }
+
+ 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();
+ TestCase.Type type = TestCase.Type.values()[value.getInt()];
+ TestCase.Status status = TestCase.Status.values()[value.getInt()];
+ return new DefaultTestCase(testFile, name, duration != -1 ? duration : null, status, message, type, stack);
+ }
+}
--- /dev/null
+/*
+ * 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.TestCase;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
+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 TestCaseCache implements BatchComponent {
+
+ private final Cache<TestCase> cache;
+
+ public TestCaseCache(Caches caches, InputPathCache inputPathCache) {
+ caches.registerValueCoder(DefaultTestCase.class, new DefaultTestCaseValueCoder(inputPathCache));
+ cache = caches.createCache("testCases");
+ }
+
+ public Iterable<Entry<TestCase>> entries() {
+ return cache.entries();
+ }
+
+ @CheckForNull
+ public TestCase get(InputFile testFile, String testCaseName) {
+ Preconditions.checkNotNull(testFile);
+ Preconditions.checkNotNull(testCaseName);
+ return cache.get(((DefaultInputFile) testFile).key(), testCaseName);
+ }
+
+ public TestCaseCache put(InputFile testFile, TestCase 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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.
+ */
+/**
+ *
+ */
+/**
+ * @author julien
+ *
+ */
+package org.sonar.batch.test;
\ No newline at end of file
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class SqaleRatingDecoratorTest {
settings = new Settings();
fs = new DefaultFileSystem();
- fs.add(new DefaultInputFile(file.getPath())
+ fs.add(new DefaultInputFile("foo", file.getPath())
.setLanguage("java")
.setFile(temp.newFile("Foo.java")));
private DefaultInputFile newInputFile(Project module, String path, String deprecatedKey, boolean isTest) {
File file = new File(baseDir, path);
- String effectiveKey = module.getKey() + ":" + path;
String deprecatedEffectiveKey = module.getKey() + ":" + deprecatedKey;
- return new DeprecatedDefaultInputFile(path)
+ return new DeprecatedDefaultInputFile(module.getKey(), path)
.setDeprecatedKey(deprecatedEffectiveKey)
.setFile(file)
- .setKey(effectiveKey)
.setType(isTest ? InputFile.Type.TEST : InputFile.Type.MAIN);
}
import static com.google.common.base.Charsets.UTF_8;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
public class IssueExclusionsLoaderTest {
@Test
public void shouldAnalyzeProject() throws IOException {
File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
- fs.add(new DeprecatedDefaultInputFile("src/main/java/Foo.java")
+ fs.add(new DeprecatedDefaultInputFile("polop", "src/main/java/Foo.java")
.setFile(javaFile1)
- .setType(InputFile.Type.MAIN)
- .setKey("polop:src/main/java/Foo.java"));
+ .setType(InputFile.Type.MAIN));
File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
- fs.add(new DeprecatedDefaultInputFile("src/test/java/FooTest.java")
+ fs.add(new DeprecatedDefaultInputFile("polop", "src/test/java/FooTest.java")
.setFile(javaTestFile1)
- .setType(InputFile.Type.TEST)
- .setKey("polop:src/test/java/FooTest.java"));
+ .setType(InputFile.Type.TEST));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
@Test
public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException {
File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
- fs.add(new DeprecatedDefaultInputFile("src/main/java/Foo.java")
+ fs.add(new DeprecatedDefaultInputFile("polop", "src/main/java/Foo.java")
.setFile(javaFile1)
- .setType(InputFile.Type.MAIN)
- .setKey("polop:src/main/java/Foo.java"));
+ .setType(InputFile.Type.MAIN));
File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
- fs.add(new DeprecatedDefaultInputFile("src/test/java/FooTest.java")
+ fs.add(new DeprecatedDefaultInputFile("polop", "src/test/java/FooTest.java")
.setFile(javaTestFile1)
- .setType(InputFile.Type.TEST)
- .setKey("polop:src/test/java/FooTest.java"));
+ .setType(InputFile.Type.TEST));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
scanner.execute();
@Test
public void shouldReportFailure() throws IOException {
File phpFile1 = new File(baseDir, "src/Foo.php");
- fs.add(new DeprecatedDefaultInputFile("src/Foo.php")
+ fs.add(new DeprecatedDefaultInputFile("polop", "src/Foo.php")
.setFile(phpFile1)
- .setType(InputFile.Type.MAIN)
- .setKey("polop:src/Foo.php"));
+ .setType(InputFile.Type.MAIN));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
for (Issue issue : result.issues()) {
if (issue.line() == 1) {
foundIssueAtLine1 = true;
- assertThat(issue.inputPath()).isEqualTo(new DefaultInputFile("src/sample.xoo"));
+ assertThat(issue.inputPath()).isEqualTo(new DefaultInputFile("com.foo.project", "src/sample.xoo"));
assertThat(issue.message()).isEqualTo("This issue is generated on each line");
assertThat(issue.effortToFix()).isNull();
}
.start();
assertThat(result.issues()).hasSize(2);
- assertThat(result.issues().iterator().next().inputPath()).isEqualTo(new DefaultInputDir("src"));
+ assertThat(result.issues().iterator().next().inputPath()).isEqualTo(new DefaultInputDir("com.foo.project", "src"));
}
assertThat(result.measures()).contains(new DefaultMeasureBuilder<Integer>()
.forMetric(CoreMetrics.LINES)
- .onFile(new DefaultInputFile("src/sample.xoo"))
+ .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo"))
.withValue(20)
.build());
assertThat(result.measures()).contains(new DefaultMeasureBuilder<Integer>()
.forMetric(CoreMetrics.LINES)
- .onFile(new DefaultInputFile("src/sample.xoo"))
+ .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo"))
.withValue(5)
.build());
assertThat(result.measures()).contains(new DefaultMeasureBuilder<String>()
.forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE)
- .onFile(new DefaultInputFile("src/sample.xoo"))
+ .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo"))
.withValue("1=julien;2=julien;3=julien;4=julien;5=simon")
.build());
}
--- /dev/null
+/*
+ * 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.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+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")
+ .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+ .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:::3\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);
+ }
+}
@Test
public void shouldRedirectFileMeasuresToSensorContext() {
- InputFile file = new DefaultInputFile("src/Foo.php");
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
Measure<Integer> measure = adaptor.getMeasure(file, CoreMetrics.NCLOC_KEY);
assertThat(measure).isNull();
@Test
public void shouldAddMeasureToSensorContext() {
- InputFile file = new DefaultInputFile("src/Foo.php");
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
when(sensorContext.saveMeasure(eq(file), argumentCaptor.capture())).thenReturn(null);
@Test
public void shouldAddIssue() {
- InputFile file = new DefaultInputFile("src/Foo.php");
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
public void key() throws Exception {
FilePredicate predicate = new AdditionalFilePredicates.KeyPredicate("struts:Action.java");
- DefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setKey("struts:Action.java");
+ DefaultInputFile inputFile = new DeprecatedDefaultInputFile("struts", "Action.java");
assertThat(predicate.apply(inputFile)).isTrue();
- inputFile = new DeprecatedDefaultInputFile("Filter.java").setKey("struts:Filter.java");
+ inputFile = new DeprecatedDefaultInputFile("struts", "Filter.java");
assertThat(predicate.apply(inputFile)).isFalse();
}
public void deprecated_key() throws Exception {
FilePredicate predicate = new AdditionalFilePredicates.DeprecatedKeyPredicate("struts:Action.java");
- DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setDeprecatedKey("struts:Action.java");
+ DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("struts", "Action.java").setDeprecatedKey("struts:Action.java");
assertThat(predicate.apply(inputFile)).isTrue();
- inputFile = new DeprecatedDefaultInputFile("Filter.java").setDeprecatedKey("struts:Filter.java");
+ inputFile = new DeprecatedDefaultInputFile("struts", "Filter.java").setDeprecatedKey("struts:Filter.java");
assertThat(predicate.apply(inputFile)).isFalse();
}
File dir = temp.newFolder();
FilePredicate predicate = new AdditionalFilePredicates.SourceDirPredicate(dir.getAbsolutePath());
- DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setSourceDirAbsolutePath(dir.getAbsolutePath());
+ DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("struts", "Action.java").setSourceDirAbsolutePath(dir.getAbsolutePath());
assertThat(predicate.apply(inputFile)).isTrue();
- inputFile = new DeprecatedDefaultInputFile("Filter.java").setSourceDirAbsolutePath(temp.newFolder().getAbsolutePath());
+ inputFile = new DeprecatedDefaultInputFile("struts", "Filter.java").setSourceDirAbsolutePath(temp.newFolder().getAbsolutePath());
assertThat(predicate.apply(inputFile)).isFalse();
}
public void path_relative_to_source_dir() throws Exception {
FilePredicate predicate = new AdditionalFilePredicates.SourceRelativePathPredicate("foo/Bar.php");
- DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("src/php/foo/Bar.php").setPathRelativeToSourceDir("foo/Bar.php");
+ DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("foo", "src/php/foo/Bar.php").setPathRelativeToSourceDir("foo/Bar.php");
assertThat(predicate.apply(inputFile)).isTrue();
- inputFile = new DeprecatedDefaultInputFile("foo/Bar.php").setPathRelativeToSourceDir("Bar.php");
+ inputFile = new DeprecatedDefaultInputFile("foo", "foo/Bar.php").setPathRelativeToSourceDir("Bar.php");
assertThat(predicate.apply(inputFile)).isFalse();
}
}
File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
FileUtils.write(javaFile1, "\uFEFFpublic class Test", Charsets.UTF_8);
- fs.add(new DeprecatedDefaultInputFile("src/main/java/foo/bar/Foo.java")
+ fs.add(new DeprecatedDefaultInputFile("foo", "src/main/java/foo/bar/Foo.java")
.setPathRelativeToSourceDir("foo/bar/Foo.java")
.setFile(javaFile1)
.setLanguage("java"));
File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
FileUtils.copyFile(getFile(testFile), javaFile1);
- fs.add(new DeprecatedDefaultInputFile("src/main/java/foo/bar/Foo.java")
+ fs.add(new DeprecatedDefaultInputFile("foo", "src/main/java/foo/bar/Foo.java")
.setPathRelativeToSourceDir("foo/bar/Foo.java")
.setFile(javaFile1)
.setLanguage("java"));
private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest) throws IOException {
File file = new File(baseDir, path);
FileUtils.write(file, content);
- return new DeprecatedDefaultInputFile(path)
+ return new DeprecatedDefaultInputFile("foo", path)
.setPathRelativeToSourceDir(sourceRelativePath)
.setFile(file)
.setLanguage(languageKey)
new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
File mainFile = temp.newFile();
- InputFile mainInput = new DeprecatedDefaultInputFile("Main.java").setFile(mainFile).setType(InputFile.Type.MAIN);
- InputFile testInput = new DeprecatedDefaultInputFile("Test.java").setFile(temp.newFile()).setType(InputFile.Type.TEST);
+ InputFile mainInput = new DeprecatedDefaultInputFile("foo", "Main.java").setFile(mainFile).setType(InputFile.Type.MAIN);
+ InputFile testInput = new DeprecatedDefaultInputFile("foo", "Test.java").setFile(temp.newFile()).setType(InputFile.Type.TEST);
when(moduleInputFileCache.inputFiles()).thenReturn(Lists.newArrayList(mainInput, testInput));
fs.index();
public void no_filters() throws Exception {
DeprecatedFileFilters filters = new DeprecatedFileFilters();
- InputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile());
+ InputFile inputFile = new DeprecatedDefaultInputFile("foo", "src/main/java/Foo.java").setFile(temp.newFile());
assertThat(filters.accept(inputFile)).isTrue();
}
File basedir = temp.newFolder();
File file = temp.newFile();
- InputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/Foo.java")
+ InputFile inputFile = new DeprecatedDefaultInputFile("foo", "src/main/java/Foo.java")
.setSourceDirAbsolutePath(new File(basedir, "src/main/java").getAbsolutePath())
.setPathRelativeToSourceDir("Foo.java")
.setFile(file)
filter.prepare();
java.io.File file = temp.newFile();
- DefaultInputFile inputFile = new DefaultInputFile("src/main/java/com/mycompany/FooDao.java").setFile(file);
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue();
}
filter.prepare();
java.io.File file = temp.newFile();
- DefaultInputFile inputFile = new DefaultInputFile("src/main/java/com/mycompany/FooDao.java").setFile(file);
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
- inputFile = new DefaultInputFile("src/main/java/com/mycompany/Foo.java").setFile(file);
+ inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
}
java.io.File file = temp.newFile();
- DefaultInputFile inputFile = new DefaultInputFile("src/main/java/com/mycompany/Foo.java").setFile(file);
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
- inputFile = new DefaultInputFile("src/main/java/com/mycompany/FooDto.java").setFile(file);
+ inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDto.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
}
filter.prepare();
java.io.File file = temp.newFile();
- DefaultInputFile inputFile = new DefaultInputFile("src/main/java/com/mycompany/FooDao.java").setFile(file);
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
- inputFile = new DefaultInputFile("src/main/java/com/mycompany/Foo.java").setFile(file);
+ inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
// source exclusions do not apply to tests
- inputFile = new DefaultInputFile("src/test/java/com/mycompany/FooDao.java").setFile(file);
+ inputFile = new DefaultInputFile("foo", "src/test/java/com/mycompany/FooDao.java").setFile(file);
assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue();
}
filter.prepare();
- DefaultInputFile inputFile = new DefaultInputFile("src/main/java/org/bar/Foo.java").setFile(includedFile);
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Foo.java").setFile(includedFile);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue();
- inputFile = new DefaultInputFile("src/main/java/org/bar/Bar.java").setFile(excludedFile);
+ inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Bar.java").setFile(excludedFile);
assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse();
}
@Test
public void should_add_input_file() throws Exception {
InputPathCache cache = new InputPathCache(caches);
- DefaultInputFile fooFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java"));
+ DefaultInputFile fooFile = new DefaultInputFile("foo", "src/main/java/Foo.java").setFile(temp.newFile("Foo.java"));
cache.put("struts", fooFile);
- cache.put("struts-core", new DeprecatedDefaultInputFile("src/main/java/Bar.java")
+ cache.put("struts-core", new DeprecatedDefaultInputFile("foo", "src/main/java/Bar.java")
.setBasedir(temp.newFolder())
.setDeprecatedKey("foo")
.setSourceDirAbsolutePath("foo")
.setStatus(Status.ADDED)
.setHash("xyz")
.setLines(1)
- .setKey("foo")
.setFile(temp.newFile("Bar.java")));
assertThat(cache.getFile("struts", "src/main/java/Foo.java").relativePath())
private InputFile newInputFile(String path) throws IOException {
File basedir = temp.newFolder();
- return new DefaultInputFile(path).setFile(new File(basedir, path));
+ return new DefaultInputFile("foo", path).setFile(new File(basedir, path));
}
static class MockLanguage implements Language {
mode = mock(AnalysisMode.class);
when(mode.isPreview()).thenReturn(true);
userFinder = mock(UserFinder.class);
- DefaultInputDir inputDir = new DefaultInputDir("src/main/java/org/apache/struts");
- inputDir.setKey("struts:src/main/java/org/apache/struts");
- DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/org/apache/struts/Action.java");
- inputFile.setKey("struts:src/main/java/org/apache/struts/Action.java");
+ DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts");
+ DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("struts", "src/main/java/org/apache/struts/Action.java");
inputFile.setStatus(InputFile.Status.CHANGED);
InputPathCache fileCache = mock(InputPathCache.class);
when(fileCache.all()).thenReturn(Arrays.<InputPath>asList(inputDir, inputFile));
*/
package org.sonar.batch.scan2;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
+import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.api.rule.RuleKey;
+
import static org.fest.assertions.Assertions.assertThat;
public class AnalyzerOptimizerTest {
.workOnLanguages("java", "php");
assertThat(optimizer.shouldExecute(descriptor)).isFalse();
- fs.add(new DefaultInputFile("src/Foo.java").setLanguage("java"));
+ fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java"));
assertThat(optimizer.shouldExecute(descriptor)).isTrue();
}
.workOnFileTypes(InputFile.Type.MAIN);
assertThat(optimizer.shouldExecute(descriptor)).isFalse();
- fs.add(new DefaultInputFile("tests/FooTest.java").setType(InputFile.Type.TEST));
+ fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setType(InputFile.Type.TEST));
assertThat(optimizer.shouldExecute(descriptor)).isFalse();
- fs.add(new DefaultInputFile("src/Foo.java").setType(InputFile.Type.MAIN));
+ fs.add(new DefaultInputFile("foo", "src/Foo.java").setType(InputFile.Type.MAIN));
assertThat(optimizer.shouldExecute(descriptor)).isTrue();
}
.workOnFileTypes(InputFile.Type.MAIN);
assertThat(optimizer.shouldExecute(descriptor)).isFalse();
- fs.add(new DefaultInputFile("tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST));
- fs.add(new DefaultInputFile("src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN));
+ fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST));
+ fs.add(new DefaultInputFile("foo", "src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN));
assertThat(optimizer.shouldExecute(descriptor)).isFalse();
- fs.add(new DefaultInputFile("src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN));
+ fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN));
assertThat(optimizer.shouldExecute(descriptor)).isTrue();
}
Library library = new Library("junit:junit", "4.7");
assertThat(ComponentKeys.createEffectiveKey(project, library)).isEqualTo("junit:junit");
- InputFile file = new DefaultInputFile("foo/Bar.php");
+ InputFile file = new DefaultInputFile("foo", "foo/Bar.php");
assertThat(ComponentKeys.createEffectiveKey("my_project", file)).isEqualTo("my_project:foo/Bar.php");
}
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.utils.PathUtils;
-import javax.annotation.CheckForNull;
-
import java.io.File;
import java.io.Serializable;
public class DefaultInputDir implements InputDir, Serializable {
private final String relativePath;
+ private final String moduleKey;
private String absolutePath;
- private String key;
- public DefaultInputDir(String relativePath) {
+ public DefaultInputDir(String moduleKey, String relativePath) {
+ this.moduleKey = moduleKey;
this.relativePath = PathUtils.sanitize(relativePath);
}
return relativePath;
}
- /**
- * Marked as nullable just for the unit tests that do not call {@link #setFile(java.io.File)}
- * previously.
- */
@Override
- @CheckForNull
public String absolutePath() {
return absolutePath;
}
return new File(absolutePath);
}
- /**
- * Component key. It's marked as nullable just for the unit tests that
- * do not previously call {@link #setKey(String)}.
- */
- @CheckForNull
+ public String moduleKey() {
+ return moduleKey;
+ }
+
public String key() {
- return key;
+ return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString();
}
public DefaultInputDir setAbsolutePath(String s) {
return this;
}
- public DefaultInputDir setKey(String s) {
- this.key = s;
- return this;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
}
DefaultInputDir that = (DefaultInputDir) o;
- return relativePath.equals(that.relativePath);
+ return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath);
}
@Override
public int hashCode() {
- return relativePath.hashCode();
+ return moduleKey.hashCode() + relativePath.hashCode() * 13;
}
@Override
public String toString() {
- return "[relative=" + relativePath + ", abs=" + absolutePath + "]";
+ return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", abs=" + absolutePath + "]";
}
}
public class DefaultInputFile implements InputFile, Serializable {
private final String relativePath;
+ private final String moduleKey;
private String absolutePath;
private String language;
private Type type = Type.MAIN;
private Status status;
private String hash;
private int lines;
- private String key;
- public DefaultInputFile(String relativePath) {
+ public DefaultInputFile(String moduleKey, String relativePath) {
+ this.moduleKey = moduleKey;
this.relativePath = PathUtils.sanitize(relativePath);
}
* Component key.
*/
public String key() {
- return key;
+ return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString();
+ }
+
+ public String moduleKey() {
+ return moduleKey;
}
public DefaultInputFile setAbsolutePath(String s) {
return this;
}
- public DefaultInputFile setKey(String s) {
- this.key = s;
- return this;
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
}
DefaultInputFile that = (DefaultInputFile) o;
- return relativePath.equals(that.relativePath);
+ return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath);
}
@Override
public int hashCode() {
- return relativePath.hashCode();
+ return moduleKey.hashCode() + relativePath.hashCode() * 13;
}
@Override
public String toString() {
- return "[relative=" + relativePath + ", abs=" + absolutePath + "]";
+ return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", abs=" + absolutePath + "]";
}
}
private String sourceDirAbsolutePath;
private String pathRelativeToSourceDir;
- public DeprecatedDefaultInputFile(String relativePath) {
- super(relativePath);
+ public DeprecatedDefaultInputFile(String moduleKey, String relativePath) {
+ super(moduleKey, relativePath);
}
/**
*/
package org.sonar.api.batch.rule;
+import org.sonar.api.BatchComponent;
import org.sonar.api.rule.RuleKey;
import javax.annotation.CheckForNull;
/**
* @since 4.2
*/
-public interface Rules {
+public interface Rules extends BatchComponent {
@CheckForNull
Rule find(RuleKey key);
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.MeasureBuilder;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.batch.sensor.test.TestCase;
+import org.sonar.api.batch.sensor.test.TestCaseBuilder;
import org.sonar.api.config.Settings;
import javax.annotation.CheckForNull;
/**
* Register all duplications of an {@link InputFile}. Use {@link #duplicationBuilder(InputFile)} to create
* list of duplications.
+ * @since 4.5
*/
void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications);
+ // ------------ TESTS ------------
+
+ /**
+ * Create a new test case for the given test file.
+ * @param testFile An {@link InputFile} with type {@link InputFile.Type#TEST}
+ * @param testCaseName name of the test case
+ * @since 5.0
+ */
+ TestCaseBuilder testCaseBuilder(InputFile testFile, String testCaseName);
+
+ /**
+ * Add a new test case.
+ * Use {@link #testCaseBuilder(InputFile, String)} to create a new {@link TestCase}
+ * @throws IllegalArgumentException if a test case with same name was already added on the same file.
+ * @since 5.0
+ */
+ void addTestCase(TestCase testCase);
+
+ /**
+ * Get a {@link TestCase} that has been previously added to the context with {@link #addTestCase(TestCase)}.
+ * @since 5.0
+ */
+ @CheckForNull
+ TestCase getTestCase(InputFile testFile, String testCaseName);
+
+ /**
+ * Register coverage of a given test case on another main file. TestCase should have been registered using {@link #testPlanBuilder(InputFile)}
+ * @param testFile test file containing the test case
+ * @param testCaseName name of the test case
+ * @param coveredFile main file that is covered
+ * @param coveredLines list of covered lines
+ * @since 5.0
+ */
+ void saveCoveragePerTest(TestCase testCase, InputFile coveredFile, List<Integer> coveredLines);
+
}
--- /dev/null
+/*
+ * 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 javax.annotation.Nullable;
+
+/**
+ * Represents a single test in a test plan.
+ * @since 5.0
+ *
+ */
+public interface TestCase {
+ enum Status {
+ OK, FAILURE, ERROR, SKIPPED;
+
+ public static Status of(@Nullable String s) {
+ return s == null ? null : valueOf(s.toUpperCase());
+ }
+ }
+
+ enum Type {
+ UNIT, INTEGRATION;
+ }
+
+ /**
+ * Duration in milliseconds
+ */
+ Long durationInMs();
+
+ Type type();
+
+ /**
+ * Status of execution of the test.
+ */
+ Status status();
+
+ /**
+ * Name of this test case.
+ */
+ String name();
+
+ /**
+ * Message (usually in case of {@link Status#ERROR} or {@link Status#FAILURE}).
+ */
+ String message();
+
+ /**
+ * Stacktrace (usually in case of {@link Status#ERROR}).
+ */
+ String stackTrace();
+
+}
--- /dev/null
+/*
+ * 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.sensor.test.TestCase.Status;
+import org.sonar.api.batch.sensor.test.TestCase.Type;
+
+/**
+ * Builder to create a new TestCase on a test file.
+ * @since 5.0
+ */
+public interface TestCaseBuilder {
+
+ /**
+ * Duration in milliseconds
+ */
+ TestCaseBuilder durationInMs(long duration);
+
+ /**
+ * Status of execution of the test.
+ */
+ TestCaseBuilder status(Status status);
+
+ /**
+ * Message (usually in case of {@link Status#ERROR} or {@link Status#FAILURE}).
+ */
+ TestCaseBuilder message(String message);
+
+ /**
+ * Type of test.
+ */
+ TestCaseBuilder type(Type type);
+
+ /**
+ * Stacktrace (usually in case of {@link Status#ERROR}).
+ */
+ TestCaseBuilder stackTrace(String stackTrace);
+
+ /**
+ * Call this method only once when your are done with defining the test case.
+ */
+ TestCase build();
+
+}
--- /dev/null
+/*
+ * 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.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.test.TestCase;
+
+import javax.annotation.CheckForNull;
+
+public class DefaultTestCase implements TestCase {
+
+ private final InputFile testFile;
+ private final String name;
+ private final Long duration;
+ private final Status status;
+ private final String message;
+ private final Type type;
+ private final String stackTrace;
+
+ public DefaultTestCase(InputFile testFile, String name, Long duration, Status status, String message, Type type, String stackTrace) {
+ this.testFile = testFile;
+ this.name = name;
+ this.duration = duration;
+ this.status = status;
+ this.message = message;
+ this.type = type;
+ this.stackTrace = stackTrace;
+ }
+
+ 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;
+ }
+
+ // 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;
+ }
+ DefaultTestCase rhs = (DefaultTestCase) 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();
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append("file", testFile)
+ .append("name", name)
+ .append("duration", duration)
+ .append("status", status)
+ .append("message", message)
+ .append("type", type)
+ .append("stackTrace", stackTrace)
+ .toString();
+ }
+}
--- /dev/null
+/*
+ * 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.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.test.TestCase;
+import org.sonar.api.batch.sensor.test.TestCase.Status;
+import org.sonar.api.batch.sensor.test.TestCase.Type;
+import org.sonar.api.batch.sensor.test.TestCaseBuilder;
+
+import javax.annotation.Nullable;
+
+public class DefaultTestCaseBuilder implements TestCaseBuilder {
+
+ private final InputFile testFile;
+ private final String name;
+ private Long duration;
+ private TestCase.Status status = Status.OK;
+ private String message;
+ private TestCase.Type type = Type.UNIT;
+ private String stackTrace;
+
+ public DefaultTestCaseBuilder(InputFile testFile, String name) {
+ Preconditions.checkArgument(testFile.type() == InputFile.Type.TEST, "Should be a test file: " + testFile);
+ Preconditions.checkArgument(StringUtils.isNotBlank(name), "Test name should not be blank");
+ this.testFile = testFile;
+ this.name = name;
+ }
+
+ @Override
+ public TestCaseBuilder durationInMs(long duration) {
+ Preconditions.checkArgument(duration >= 0, "Test duration must be positive (got: " + duration + ")");
+ this.duration = duration;
+ return this;
+ }
+
+ @Override
+ public TestCaseBuilder status(TestCase.Status status) {
+ Preconditions.checkNotNull(status);
+ this.status = status;
+ return this;
+ }
+
+ @Override
+ public TestCaseBuilder message(@Nullable String message) {
+ this.message = message;
+ return this;
+ }
+
+ @Override
+ public TestCaseBuilder type(TestCase.Type type) {
+ this.type = type;
+ return this;
+ }
+
+ @Override
+ public TestCaseBuilder stackTrace(@Nullable String stackTrace) {
+ this.stackTrace = stackTrace;
+ return this;
+ }
+
+ @Override
+ public TestCase build() {
+ return new DefaultTestCase(this.testFile, this.name, this.duration, this.status, this.message, this.type, this.stackTrace);
+ }
+
+}
--- /dev/null
+/*
+ * 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;
\ No newline at end of file
--- /dev/null
+/*
+ * 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;
\ No newline at end of file
*/
package org.sonar.api.test;
+import org.sonar.api.batch.sensor.SensorContext;
+
import javax.annotation.Nullable;
import java.util.List;
+/**
+ * @deprecated since 5.0 use {@link SensorContext#testPlanBuilder(org.sonar.api.batch.fs.InputFile)}
+ */
+@Deprecated
public interface MutableTestCase extends TestCase {
MutableTestCase setStatus(@Nullable Status s);
*/
package org.sonar.api.test;
+import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.component.MutablePerspective;
+/**
+ * @deprecated since 5.0 use {@link SensorContext#testPlanBuilder(org.sonar.api.batch.fs.InputFile)}
+ */
+@Deprecated
public interface MutableTestPlan extends TestPlan<MutableTestCase>, MutablePerspective {
MutableTestCase addTestCase(String name);
*/
package org.sonar.api.test;
+import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.component.MutablePerspective;
+/**
+ * @deprecated since 5.0 use {@link SensorContext#testPlanBuilder(org.sonar.api.batch.fs.InputFile)}
+ */
+@Deprecated
public interface MutableTestable extends Testable, MutablePerspective {
}
import javax.annotation.Nullable;
+/**
+ * @deprecated since 5.0 see {@link org.sonar.api.batch.sensor.test.TestCase}
+ */
+@Deprecated
public interface TestCase {
enum Status {
OK, FAILURE, ERROR, SKIPPED;
import org.sonar.api.component.Perspective;
+/**
+ * @deprecated since 5.0
+ */
+@Deprecated
public interface TestPlan<T extends TestCase> extends Perspective {
Iterable<T> testCases();
*/
package org.sonar.api.test;
+import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.component.Perspective;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
+/**
+ * @deprecated since 5.0 use {@link SensorContext#testPlanBuilder(org.sonar.api.batch.fs.InputFile)}
+ */
+@Deprecated
public interface Testable extends Perspective {
List<TestCase> testCases();
@Before
public void before() throws IOException {
- javaFile = new DefaultInputFile("src/main/java/struts/Action.java")
+ javaFile = new DefaultInputFile("foo", "src/main/java/struts/Action.java")
.setFile(temp.newFile("Action.java"))
.setLanguage("java")
.setStatus(InputFile.Status.ADDED);
assertThat(fs.inputFiles(fs.predicates().all())).isEmpty();
- fs.add(new DefaultInputFile("src/Foo.php").setLanguage("php").setFile(temp.newFile()));
- fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile()));
- fs.add(new DefaultInputFile("src/Baz.java").setLanguage("java").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Foo.php").setLanguage("php").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java").setFile(temp.newFile()));
// no language
- fs.add(new DefaultInputFile("src/readme.txt").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/readme.txt").setFile(temp.newFile()));
assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNotNull();
assertThat(fs.inputFile(fs.predicates().hasRelativePath("does/not/exist"))).isNull();
thrown.expectMessage("expected one element");
DefaultFileSystem fs = new DefaultFileSystem();
- fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile()));
- fs.add(new DefaultInputFile("src/Baz.java").setLanguage("java").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Baz.java").setLanguage("java").setFile(temp.newFile()));
fs.inputFile(fs.predicates().all());
}
@Test
public void input_file_supports_non_indexed_predicates() throws Exception {
DefaultFileSystem fs = new DefaultFileSystem();
- fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile()));
+ fs.add(new DefaultInputFile("foo", "src/Bar.java").setLanguage("java").setFile(temp.newFile()));
// it would fail if more than one java file
assertThat(fs.inputFile(fs.predicates().hasLanguage("java"))).isNotNull();
@Test
public void test() throws Exception {
File dir = temp.newFolder("src");
- DefaultInputDir inputDir = new DefaultInputDir("src")
- .setFile(dir)
- .setKey("ABCDE");
+ DefaultInputDir inputDir = new DefaultInputDir("ABCDE", "src")
+ .setFile(dir);
- assertThat(inputDir.key()).isEqualTo("ABCDE");
+ assertThat(inputDir.key()).isEqualTo("ABCDE:src");
assertThat(inputDir.file().getAbsolutePath()).isEqualTo(dir.getAbsolutePath());
assertThat(inputDir.relativePath()).isEqualTo("src");
assertThat(new File(inputDir.relativePath())).isRelative();
@Test
public void testEqualsAndHashCode() throws Exception {
File dir1 = temp.newFolder("src");
- DefaultInputDir inputDir1 = new DefaultInputDir("src")
- .setFile(dir1)
- .setKey("ABCDE");
+ DefaultInputDir inputDir1 = new DefaultInputDir("ABCDE", "src")
+ .setFile(dir1);
File dir2 = temp.newFolder("src2");
- DefaultInputDir inputDir2 = new DefaultInputDir("src")
- .setFile(dir2)
- .setKey("ABCDE");
+ DefaultInputDir inputDir2 = new DefaultInputDir("ABCDE", "src")
+ .setFile(dir2);
assertThat(inputDir1.equals(inputDir1)).isTrue();
assertThat(inputDir1.equals(inputDir2)).isTrue();
assertThat(inputDir1.equals("foo")).isFalse();
- assertThat(inputDir1.hashCode()).isEqualTo(114148);
+ assertThat(inputDir1.hashCode()).isEqualTo(63545559);
- assertThat(inputDir1.toString()).contains("[relative=src, abs=");
+ assertThat(inputDir1.toString()).contains("[moduleKey=ABCDE, relative=src, abs=");
}
@Test
public void test() throws Exception {
- DefaultInputFile inputFile = new DefaultInputFile("src/Foo.php")
+ DefaultInputFile inputFile = new DefaultInputFile("ABCDE", "src/Foo.php")
.setFile(temp.newFile("Foo.php"))
- .setKey("ABCDE")
.setHash("1234")
.setLines(42)
.setLanguage("php")
@Test
public void test_equals_and_hashcode() throws Exception {
- DefaultInputFile f1 = new DefaultInputFile("src/Foo.php");
- DefaultInputFile f1a = new DefaultInputFile("src/Foo.php");
- DefaultInputFile f2 = new DefaultInputFile("src/Bar.php");
+ DefaultInputFile f1 = new DefaultInputFile("ABCDE", "src/Foo.php");
+ DefaultInputFile f1a = new DefaultInputFile("ABCDE", "src/Foo.php");
+ DefaultInputFile f2 = new DefaultInputFile("ABCDE", "src/Bar.php");
assertThat(f1).isEqualTo(f1);
assertThat(f1).isEqualTo(f1a);
@Test
public void test_toString() throws Exception {
- DefaultInputFile file = new DefaultInputFile("src/Foo.php").setAbsolutePath("/path/to/src/Foo.php");
- assertThat(file.toString()).isEqualTo("[relative=src/Foo.php, abs=/path/to/src/Foo.php]");
+ DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php").setAbsolutePath("/path/to/src/Foo.php");
+ assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, abs=/path/to/src/Foo.php]");
}
}
@Test
public void test() throws Exception {
- DeprecatedDefaultInputFile inputFile = (DeprecatedDefaultInputFile) new DeprecatedDefaultInputFile("src/Foo.php")
+ DeprecatedDefaultInputFile inputFile = (DeprecatedDefaultInputFile) new DeprecatedDefaultInputFile("ABCDE", "src/Foo.php")
.setPathRelativeToSourceDir("Foo.php")
.setDeprecatedKey("deprecated")
.setFile(temp.newFile("Foo.php"))
- .setKey("ABCDE")
.setHash("1234")
.setLines(42)
.setLanguage("php")
@Test
public void test_equals_and_hashcode() throws Exception {
- DefaultInputFile f1 = new DefaultInputFile("src/Foo.php");
- DefaultInputFile f1a = new DefaultInputFile("src/Foo.php");
- DefaultInputFile f2 = new DefaultInputFile("src/Bar.php");
+ DefaultInputFile f1 = new DefaultInputFile("ABCDE", "src/Foo.php");
+ DefaultInputFile f1a = new DefaultInputFile("ABCDE", "src/Foo.php");
+ DefaultInputFile f2 = new DefaultInputFile("ABCDE", "src/Bar.php");
assertThat(f1).isEqualTo(f1);
assertThat(f1).isEqualTo(f1a);
@Test
public void test_toString() throws Exception {
- DefaultInputFile file = new DefaultInputFile("src/Foo.php").setAbsolutePath("/path/to/src/Foo.php");
- assertThat(file.toString()).isEqualTo("[relative=src/Foo.php, abs=/path/to/src/Foo.php]");
+ DefaultInputFile file = new DefaultInputFile("ABCDE", "src/Foo.php").setAbsolutePath("/path/to/src/Foo.php");
+ assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, abs=/path/to/src/Foo.php]");
}
}
assertThat(pattern.toString()).isEqualTo("**/*Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.java");
- InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.java").setFile(file);
+ InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java").setFile(file);
assertThat(pattern.match(inputFile)).isTrue();
// case sensitive by default
file = new File(temp.newFolder(), "src/main/java/org/MyFoo.JAVA");
- inputFile = new DefaultInputFile("src/main/java/org/MyFoo.JAVA").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setFile(file);
assertThat(pattern.match(inputFile)).isFalse();
file = new File(temp.newFolder(), "src/main/java/org/Other.java");
- inputFile = new DefaultInputFile("src/main/java/org/Other.java").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setFile(file);
assertThat(pattern.match(inputFile)).isFalse();
}
PathPattern pattern = PathPattern.create("**/*Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.JAVA");
- InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.JAVA").setFile(file);
+ InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setFile(file);
assertThat(pattern.match(inputFile, false)).isTrue();
file = new File(temp.newFolder(), "src/main/java/org/Other.java");
- inputFile = new DefaultInputFile("src/main/java/org/Other.java").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setFile(file);
assertThat(pattern.match(inputFile, false)).isFalse();
}
assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.java");
- InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.java").setFile(file);
+ InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.java").setFile(file);
assertThat(pattern.match(inputFile)).isTrue();
// case sensitive by default
file = new File(temp.newFolder(), "src/main/java/org/MyFoo.JAVA");
- inputFile = new DefaultInputFile("src/main/java/org/MyFoo.JAVA").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setFile(file);
assertThat(pattern.match(inputFile)).isFalse();
file = new File(temp.newFolder(), "src/main/java/org/Other.java");
- inputFile = new DefaultInputFile("src/main/java/org/Other.java").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.java").setFile(file);
assertThat(pattern.match(inputFile)).isFalse();
}
assertThat(pattern.toString()).isEqualTo("file:**/src/main/**Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.JAVA");
- InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.JAVA").setFile(file);
+ InputFile inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/MyFoo.JAVA").setFile(file);
assertThat(pattern.match(inputFile, false)).isTrue();
file = new File(temp.newFolder(), "src/main/java/org/Other.JAVA");
- inputFile = new DefaultInputFile("src/main/java/org/Other.JAVA").setFile(file);
+ inputFile = new DefaultInputFile("ABCDE", "src/main/java/org/Other.JAVA").setFile(file);
assertThat(pattern.match(inputFile, false)).isFalse();
}
@Test
public void create_array_of_patterns() throws Exception {
- PathPattern[] patterns = PathPattern.create(new String[]{
+ PathPattern[] patterns = PathPattern.create(new String[] {
"**/src/main/**Foo.java",
"file:**/src/main/**Bar.java"
});
@Test
public void test() {
- DefaultDuplicationBuilder builder = new DefaultDuplicationBuilder(new DefaultInputFile("foo.php").setKey("foo:foo.php"));
+ DefaultDuplicationBuilder builder = new DefaultDuplicationBuilder(new DefaultInputFile("foo", "foo.php"));
List<DuplicationGroup> duplicationGroup = builder.originBlock(1, 11)
- .isDuplicatedBy(new DefaultInputFile("foo.php"), 40, 50)
- .isDuplicatedBy(new DefaultInputFile("foo2.php"), 1, 10)
+ .isDuplicatedBy(new DefaultInputFile("foo", "foo.php"), 40, 50)
+ .isDuplicatedBy(new DefaultInputFile("foo", "foo2.php"), 1, 10)
.originBlock(20, 30)
- .isDuplicatedBy(new DefaultInputFile("foo3.php"), 30, 40)
+ .isDuplicatedBy(new DefaultInputFile("foo", "foo3.php"), 30, 40)
.build();
assertThat(duplicationGroup).hasSize(2);
@Test
public void build_file_issue() {
Issue issue = new DefaultIssueBuilder()
- .onFile(new DefaultInputFile("src/Foo.php"))
+ .onFile(new DefaultInputFile("foo", "src/Foo.php"))
.ruleKey(RuleKey.of("repo", "rule"))
.atLine(1)
.effortToFix(10.0)
.message("Wrong way!")
.build();
- assertThat(issue.inputPath()).isEqualTo(new DefaultInputFile("src/Foo.php"));
+ assertThat(issue.inputPath()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
assertThat(issue.line()).isEqualTo(1);
assertThat(issue.effortToFix()).isEqualTo(10.0);
thrown.expectMessage("onProject already called");
new DefaultIssueBuilder()
.onProject()
- .onFile(new DefaultInputFile("src/Foo.php"))
+ .onFile(new DefaultInputFile("foo", "src/Foo.php"))
.ruleKey(RuleKey.of("repo", "rule"))
.atLine(1)
.effortToFix(10.0)
public void build_file_measure() {
Measure<Integer> issue = new DefaultMeasureBuilder<Integer>()
.forMetric(CoreMetrics.LINES)
- .onFile(new DefaultInputFile("src/Foo.php"))
+ .onFile(new DefaultInputFile("foo", "src/Foo.php"))
.withValue(3)
.build();
- assertThat(issue.inputFile()).isEqualTo(new DefaultInputFile("src/Foo.php"));
+ assertThat(issue.inputFile()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
assertThat(issue.metric()).isEqualTo(CoreMetrics.LINES);
assertThat(issue.value()).isEqualTo(3);
}
thrown.expectMessage("onProject already called");
new DefaultMeasureBuilder<Integer>()
.onProject()
- .onFile(new DefaultInputFile("src/Foo.php"))
+ .onFile(new DefaultInputFile("foo", "src/Foo.php"))
.withValue(3)
.build();
}
--- /dev/null
+/*
+ * 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.TestCase.Status;
+import org.sonar.api.batch.sensor.test.TestCase.Type;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DefaultTestCaseBuilderTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private InputFile parent = new DefaultInputFile("foo", "src/Foo.php").setType(InputFile.Type.TEST);
+
+ @Test
+ public void testBuilder() throws Exception {
+ DefaultTestCaseBuilder builder = new DefaultTestCaseBuilder(parent, "myTest");
+ assertThat(builder.durationInMs(1)
+ .message("message")
+ .stackTrace("stack")
+ .status(Status.ERROR)
+ .type(Type.UNIT)
+ .build()).isEqualTo(new DefaultTestCase(parent, "myTest", 1L, Status.ERROR, "message", Type.UNIT, "stack"));
+ }
+
+ @Test
+ public void testBuilderWithDefaultValues() throws Exception {
+ DefaultTestCaseBuilder builder = new DefaultTestCaseBuilder(parent, "myTest");
+ assertThat(builder.build()).isEqualTo(
+ new DefaultTestCase(parent, "myTest", null, Status.OK, null, Type.UNIT, null));
+ }
+
+ @Test
+ public void testInvalidDuration() throws Exception {
+ DefaultTestCaseBuilder builder = new DefaultTestCaseBuilder(parent, "myTest");
+
+ thrown.expect(IllegalArgumentException.class);
+
+ builder.durationInMs(-3)
+ .message("message")
+ .stackTrace("stack")
+ .status(Status.ERROR)
+ .type(Type.UNIT)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * 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.Test;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.test.TestCase.Status;
+import org.sonar.api.batch.sensor.test.TestCase.Type;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DefaultTestCaseTest {
+
+ private InputFile parent = new DefaultInputFile("foo", "src/Foo.php");
+
+ @Test
+ public void testDefaultTestCaseTest() {
+ DefaultTestCase testCase1 = new DefaultTestCase(parent, "myTest", 1L, Status.ERROR, "message", Type.UNIT, "stack");
+
+ assertThat(testCase1.name()).isEqualTo("myTest");
+ assertThat(testCase1.durationInMs()).isEqualTo(1L);
+ assertThat(testCase1.status()).isEqualTo(Status.ERROR);
+ assertThat(testCase1.message()).isEqualTo("message");
+ assertThat(testCase1.type()).isEqualTo(Type.UNIT);
+ assertThat(testCase1.stackTrace()).isEqualTo("stack");
+ }
+
+ @Test
+ public void testEqualsHashCodeToString() {
+ DefaultTestCase testCase1 = new DefaultTestCase(parent, "myTest", 1L, Status.ERROR, "message", Type.UNIT, "stack");
+ DefaultTestCase testCase1a = new DefaultTestCase(parent, "myTest", 1L, Status.ERROR, "message", Type.UNIT, "stack");
+ DefaultTestCase testCase2 = new DefaultTestCase(new DefaultInputFile("foo2", "src/Foo.php"), "myTest2", 2L, Status.FAILURE, "message2", Type.INTEGRATION, null);
+
+ assertThat(testCase1).isEqualTo(testCase1);
+ assertThat(testCase1).isEqualTo(testCase1a);
+ assertThat(testCase1).isNotEqualTo(testCase2);
+ assertThat(testCase1).isNotEqualTo(null);
+ assertThat(testCase1).isNotEqualTo("foo");
+
+ assertThat(testCase1.toString()).isEqualTo(
+ "DefaultTestCase[file=[moduleKey=foo, relative=src/Foo.php, abs=null],name=myTest,duration=1,status=ERROR,message=message,type=UNIT,stackTrace=stack]");
+ assertThat(testCase1.hashCode()).isEqualTo(testCase1a.hashCode());
+ }
+
+}