@@ -19,8 +19,6 @@ | |||
*/ | |||
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; | |||
@@ -58,8 +56,8 @@ public class FileHashSensorTest { | |||
@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); | |||
@@ -72,8 +70,8 @@ public class FileHashSensorTest { | |||
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); |
@@ -63,11 +63,10 @@ public class JavaCpdEngineTest { | |||
@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); | |||
@@ -135,7 +134,7 @@ public class JavaCpdEngineTest { | |||
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)) | |||
)); |
@@ -20,10 +20,12 @@ | |||
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; | |||
@@ -55,6 +57,8 @@ public class XooPlugin extends SonarPlugin { | |||
SyntaxHighlightingSensor.class, | |||
SymbolReferencesSensor.class, | |||
XooTokenizerSensor.class, | |||
TestCaseSensor.class, | |||
CoveragePerTestSensor.class, | |||
OneIssuePerLineSensor.class, | |||
OneIssueOnDirPerFileSensor.class, |
@@ -0,0 +1,110 @@ | |||
/* | |||
* 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); | |||
} | |||
} | |||
} |
@@ -30,7 +30,6 @@ import org.sonar.api.batch.sensor.SensorContext; | |||
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; | |||
@@ -88,7 +87,6 @@ public class SymbolReferencesSensor implements Sensor { | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor | |||
.name("Xoo Symbol Reference Sensor") | |||
.provides(CoreMetrics.LINES) | |||
.workOnLanguages(Xoo.KEY) | |||
.workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST); | |||
} |
@@ -30,7 +30,6 @@ import org.sonar.api.batch.sensor.SensorContext; | |||
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; | |||
@@ -86,7 +85,6 @@ public class SyntaxHighlightingSensor implements Sensor { | |||
public void describe(SensorDescriptor descriptor) { | |||
descriptor | |||
.name("Xoo Highlighting Sensor") | |||
.provides(CoreMetrics.LINES) | |||
.workOnLanguages(Xoo.KEY) | |||
.workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST); | |||
} |
@@ -0,0 +1,108 @@ | |||
/* | |||
* 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); | |||
} | |||
} | |||
} |
@@ -27,6 +27,6 @@ public class XooPluginTest { | |||
@Test | |||
public void provide_extensions() { | |||
assertThat(new XooPlugin().getExtensions()).hasSize(11); | |||
assertThat(new XooPlugin().getExtensions()).hasSize(13); | |||
} | |||
} |
@@ -72,7 +72,7 @@ public class MeasureSensorTest { | |||
@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); | |||
} | |||
@@ -81,7 +81,7 @@ public class MeasureSensorTest { | |||
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) | |||
@@ -108,7 +108,7 @@ public class MeasureSensorTest { | |||
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()); |
@@ -63,7 +63,7 @@ public class SymbolReferencesSensorTest { | |||
@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); | |||
} | |||
@@ -72,7 +72,7 @@ public class SymbolReferencesSensorTest { | |||
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); |
@@ -63,7 +63,7 @@ public class SyntaxHighlightingSensorTest { | |||
@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); | |||
} | |||
@@ -72,7 +72,7 @@ public class SyntaxHighlightingSensorTest { | |||
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); |
@@ -70,7 +70,7 @@ public class XooTokenizerSensorTest { | |||
@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); | |||
@@ -81,7 +81,7 @@ public class XooTokenizerSensorTest { | |||
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); |
@@ -34,6 +34,7 @@ import org.sonar.api.batch.sensor.highlighting.TypeOfText; | |||
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; | |||
@@ -57,6 +58,8 @@ import org.sonar.batch.scan2.AnalyzerMeasureCache; | |||
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; | |||
@@ -66,6 +69,7 @@ import javax.annotation.CheckForNull; | |||
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; | |||
@@ -226,6 +230,8 @@ public class BatchMediumTester { | |||
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) { | |||
@@ -265,6 +271,27 @@ public class BatchMediumTester { | |||
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() { | |||
@@ -287,6 +314,29 @@ public class BatchMediumTester { | |||
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 |
@@ -19,16 +19,20 @@ | |||
*/ | |||
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; | |||
@@ -40,15 +44,21 @@ import org.sonar.api.measures.SumChildDistributionFormula; | |||
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. | |||
@@ -209,4 +219,71 @@ public class SensorContextAdaptor extends BaseSensorContext { | |||
.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; | |||
} | |||
} |
@@ -34,6 +34,7 @@ class DefaultInputFileValueCoder implements ValueCoder { | |||
@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()); | |||
@@ -45,7 +46,6 @@ class DefaultInputFileValueCoder implements ValueCoder { | |||
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) { | |||
@@ -58,7 +58,8 @@ class DefaultInputFileValueCoder implements ValueCoder { | |||
@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()); | |||
@@ -69,7 +70,6 @@ class DefaultInputFileValueCoder implements ValueCoder { | |||
file.setStatus(InputFile.Status.valueOf(value.getString())); | |||
file.setHash(value.getString()); | |||
file.setLines(value.getInt()); | |||
file.setKey(value.getString()); | |||
return file; | |||
} | |||
@@ -171,9 +171,8 @@ public class FileIndexer implements BatchComponent { | |||
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); | |||
} | |||
} |
@@ -82,7 +82,7 @@ class InputFileBuilder { | |||
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; | |||
@@ -94,7 +94,6 @@ class InputFileBuilder { | |||
@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); |
@@ -26,6 +26,7 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; | |||
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. | |||
@@ -35,8 +36,8 @@ public class AnalyzerMeasureCache implements BatchComponent { | |||
// 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"); | |||
} | |||
@@ -35,6 +35,8 @@ import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder; | |||
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; | |||
@@ -147,4 +149,9 @@ public abstract class BaseSensorContext implements SensorContext { | |||
} | |||
} | |||
@Override | |||
public TestCaseBuilder testCaseBuilder(InputFile testFile, String testCaseName) { | |||
return new DefaultTestCaseBuilder(testFile, testCaseName); | |||
} | |||
} |
@@ -23,25 +23,35 @@ 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.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()); | |||
} | |||
@@ -49,8 +59,10 @@ class DefaultMeasureValueCoder implements ValueCoder { | |||
@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(); |
@@ -19,10 +19,12 @@ | |||
*/ | |||
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; | |||
@@ -30,6 +32,8 @@ import org.sonar.api.batch.sensor.issue.Issue; | |||
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; | |||
@@ -38,9 +42,12 @@ import org.sonar.batch.duplication.DuplicationCache; | |||
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 { | |||
@@ -49,16 +56,20 @@ 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 | |||
@@ -129,4 +140,24 @@ public class DefaultSensorContext extends BaseSensorContext { | |||
} | |||
} | |||
@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); | |||
} | |||
} |
@@ -47,6 +47,8 @@ import org.sonar.batch.scan.ProjectSettings; | |||
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) { | |||
@@ -107,12 +109,17 @@ public class ProjectScanContainer extends ComponentContainer { | |||
// issues | |||
AnalyzerIssueCache.class, | |||
// Syntax highlighting and symbols | |||
ComponentDataCache.class, | |||
// Duplications | |||
BlockCache.class, | |||
DuplicationCache.class, | |||
// Tests | |||
TestCaseCache.class, | |||
CoveragePerTestCache.class, | |||
ScanTaskObservers.class); | |||
} | |||
@@ -0,0 +1,66 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,77 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,69 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,27 @@ | |||
/* | |||
* 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; |
@@ -44,7 +44,10 @@ import static com.google.common.collect.Lists.newArrayList; | |||
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 { | |||
@@ -71,7 +74,7 @@ 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"))); | |||
@@ -85,12 +85,10 @@ public class ResourceKeyMigrationTest extends AbstractDbUnitTestCase { | |||
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); | |||
} | |||
@@ -40,7 +40,10 @@ import java.io.IOException; | |||
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 { | |||
@@ -101,15 +104,13 @@ 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); | |||
@@ -126,15 +127,13 @@ public class IssueExclusionsLoaderTest { | |||
@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(); | |||
@@ -149,10 +148,9 @@ public class IssueExclusionsLoaderTest { | |||
@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); |
@@ -137,7 +137,7 @@ public class IssuesMediumTest { | |||
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(); | |||
} |
@@ -84,7 +84,7 @@ public class IssuesOnDirMediumTest { | |||
.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")); | |||
} | |||
@@ -97,7 +97,7 @@ public class MeasuresMediumTest { | |||
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()); | |||
@@ -140,13 +140,13 @@ public class MeasuresMediumTest { | |||
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()); | |||
} |
@@ -0,0 +1,130 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -107,7 +107,7 @@ public class SensorContextAdapterTest { | |||
@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(); | |||
@@ -122,7 +122,7 @@ public class SensorContextAdapterTest { | |||
@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); | |||
@@ -140,7 +140,7 @@ public class SensorContextAdapterTest { | |||
@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); | |||
@@ -39,10 +39,10 @@ public class AdditionalFilePredicatesTest { | |||
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(); | |||
} | |||
@@ -50,10 +50,10 @@ public class AdditionalFilePredicatesTest { | |||
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(); | |||
} | |||
@@ -62,10 +62,10 @@ public class AdditionalFilePredicatesTest { | |||
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(); | |||
} | |||
@@ -73,10 +73,10 @@ public class AdditionalFilePredicatesTest { | |||
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(); | |||
} | |||
} |
@@ -161,7 +161,7 @@ public class ComponentIndexerTest { | |||
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")); | |||
@@ -186,7 +186,7 @@ public class ComponentIndexerTest { | |||
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")); | |||
@@ -212,7 +212,7 @@ public class ComponentIndexerTest { | |||
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) |
@@ -163,8 +163,8 @@ public class DefaultModuleFileSystemTest { | |||
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(); |
@@ -49,7 +49,7 @@ public class DeprecatedFileFiltersTest { | |||
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(); | |||
} | |||
@@ -59,7 +59,7 @@ public class DeprecatedFileFiltersTest { | |||
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) |
@@ -43,7 +43,7 @@ public class ExclusionFiltersTest { | |||
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(); | |||
} | |||
@@ -56,10 +56,10 @@ public class ExclusionFiltersTest { | |||
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(); | |||
} | |||
@@ -73,10 +73,10 @@ public class ExclusionFiltersTest { | |||
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(); | |||
} | |||
@@ -91,14 +91,14 @@ public class ExclusionFiltersTest { | |||
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(); | |||
} | |||
@@ -114,10 +114,10 @@ public class ExclusionFiltersTest { | |||
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(); | |||
} | |||
@@ -55,9 +55,9 @@ public class InputPathCacheTest { | |||
@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") | |||
@@ -67,7 +67,6 @@ public class InputPathCacheTest { | |||
.setStatus(Status.ADDED) | |||
.setHash("xyz") | |||
.setLines(1) | |||
.setKey("foo") | |||
.setFile(temp.newFile("Bar.java"))); | |||
assertThat(cache.getFile("struts", "src/main/java/Foo.java").relativePath()) |
@@ -183,7 +183,7 @@ public class LanguageDetectionTest { | |||
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 { |
@@ -87,10 +87,8 @@ public class JsonReportTest { | |||
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)); |
@@ -19,8 +19,6 @@ | |||
*/ | |||
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; | |||
@@ -30,7 +28,9 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
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 { | |||
@@ -59,7 +59,7 @@ 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(); | |||
} | |||
@@ -69,10 +69,10 @@ public class AnalyzerOptimizerTest { | |||
.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(); | |||
} | |||
@@ -83,11 +83,11 @@ public class AnalyzerOptimizerTest { | |||
.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(); | |||
} | |||
@@ -41,7 +41,7 @@ public class ComponentKeysTest { | |||
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"); | |||
} | |||
@@ -22,8 +22,6 @@ package org.sonar.api.batch.fs.internal; | |||
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; | |||
@@ -33,10 +31,11 @@ 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); | |||
} | |||
@@ -45,12 +44,7 @@ public class DefaultInputDir implements InputDir, Serializable { | |||
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; | |||
} | |||
@@ -63,13 +57,12 @@ public class DefaultInputDir implements InputDir, Serializable { | |||
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) { | |||
@@ -82,11 +75,6 @@ public class DefaultInputDir implements InputDir, Serializable { | |||
return this; | |||
} | |||
public DefaultInputDir setKey(String s) { | |||
this.key = s; | |||
return this; | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
@@ -97,16 +85,16 @@ public class DefaultInputDir implements InputDir, Serializable { | |||
} | |||
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 + "]"; | |||
} | |||
} |
@@ -31,15 +31,16 @@ import java.io.Serializable; | |||
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); | |||
} | |||
@@ -95,7 +96,11 @@ public class DefaultInputFile implements InputFile, Serializable { | |||
* 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) { | |||
@@ -133,11 +138,6 @@ public class DefaultInputFile implements InputFile, Serializable { | |||
return this; | |||
} | |||
public DefaultInputFile setKey(String s) { | |||
this.key = s; | |||
return this; | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
@@ -148,16 +148,16 @@ public class DefaultInputFile implements InputFile, Serializable { | |||
} | |||
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 + "]"; | |||
} | |||
} |
@@ -37,8 +37,8 @@ public class DeprecatedDefaultInputFile extends DefaultInputFile implements org. | |||
private String sourceDirAbsolutePath; | |||
private String pathRelativeToSourceDir; | |||
public DeprecatedDefaultInputFile(String relativePath) { | |||
super(relativePath); | |||
public DeprecatedDefaultInputFile(String moduleKey, String relativePath) { | |||
super(moduleKey, relativePath); | |||
} | |||
/** |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.api.batch.rule; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.rule.RuleKey; | |||
import javax.annotation.CheckForNull; | |||
@@ -28,7 +29,7 @@ import java.util.Collection; | |||
/** | |||
* @since 4.2 | |||
*/ | |||
public interface Rules { | |||
public interface Rules extends BatchComponent { | |||
@CheckForNull | |||
Rule find(RuleKey key); |
@@ -33,6 +33,8 @@ import org.sonar.api.batch.sensor.issue.IssueBuilder; | |||
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; | |||
@@ -149,7 +151,43 @@ public interface SensorContext { | |||
/** | |||
* 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); | |||
} |
@@ -0,0 +1,69 @@ | |||
/* | |||
* 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(); | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* 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(); | |||
} |
@@ -0,0 +1,137 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -0,0 +1,86 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@javax.annotation.ParametersAreNonnullByDefault | |||
package org.sonar.api.batch.sensor.test.internal; |
@@ -0,0 +1,21 @@ | |||
/* | |||
* 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; |
@@ -19,10 +19,16 @@ | |||
*/ | |||
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); | |||
@@ -19,8 +19,13 @@ | |||
*/ | |||
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); |
@@ -19,8 +19,13 @@ | |||
*/ | |||
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 { | |||
} |
@@ -21,6 +21,10 @@ package org.sonar.api.test; | |||
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; |
@@ -21,6 +21,10 @@ package org.sonar.api.test; | |||
import org.sonar.api.component.Perspective; | |||
/** | |||
* @deprecated since 5.0 | |||
*/ | |||
@Deprecated | |||
public interface TestPlan<T extends TestCase> extends Perspective { | |||
Iterable<T> testCases(); | |||
@@ -19,12 +19,17 @@ | |||
*/ | |||
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(); |
@@ -45,7 +45,7 @@ public class DefaultFilePredicatesTest { | |||
@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); |
@@ -80,12 +80,12 @@ public class DefaultFileSystemTest { | |||
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(); | |||
@@ -119,8 +119,8 @@ public class DefaultFileSystemTest { | |||
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()); | |||
} | |||
@@ -128,7 +128,7 @@ public class DefaultFileSystemTest { | |||
@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(); |
@@ -35,11 +35,10 @@ public class DefaultInputDirTest { | |||
@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(); | |||
@@ -50,22 +49,20 @@ public class DefaultInputDirTest { | |||
@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="); | |||
} | |||
@@ -35,9 +35,8 @@ public class DefaultInputFileTest { | |||
@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") | |||
@@ -57,9 +56,9 @@ public class DefaultInputFileTest { | |||
@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); | |||
@@ -73,7 +72,7 @@ public class DefaultInputFileTest { | |||
@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]"); | |||
} | |||
} |
@@ -36,11 +36,10 @@ public class DeprecatedDefaultInputFileTest { | |||
@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") | |||
@@ -62,9 +61,9 @@ public class DeprecatedDefaultInputFileTest { | |||
@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); | |||
@@ -78,7 +77,7 @@ public class DeprecatedDefaultInputFileTest { | |||
@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]"); | |||
} | |||
} |
@@ -38,16 +38,16 @@ public class PathPatternTest { | |||
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(); | |||
} | |||
@@ -56,11 +56,11 @@ public class PathPatternTest { | |||
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(); | |||
} | |||
@@ -70,16 +70,16 @@ public class PathPatternTest { | |||
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(); | |||
} | |||
@@ -89,17 +89,17 @@ public class PathPatternTest { | |||
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" | |||
}); |
@@ -32,13 +32,13 @@ public class DefaultDuplicationBuilderTest { | |||
@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); |
@@ -36,14 +36,14 @@ public class DefaultIssueTest { | |||
@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); | |||
@@ -72,7 +72,7 @@ public class DefaultIssueTest { | |||
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) |
@@ -37,11 +37,11 @@ public class DefaultMeasureTest { | |||
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); | |||
} | |||
@@ -65,7 +65,7 @@ public class DefaultMeasureTest { | |||
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(); | |||
} |
@@ -0,0 +1,71 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -0,0 +1,63 @@ | |||
/* | |||
* 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()); | |||
} | |||
} |