소스 검색

SONAR-5389 New test API for batch 2.0

tags/5.0-RC1
Julien HENRY 9 년 전
부모
커밋
e1c3a70631
72개의 변경된 파일1544개의 추가작업 그리고 201개의 파일을 삭제
  1. 4
    6
      plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java
  2. 2
    3
      plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
  3. 4
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
  4. 110
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java
  5. 0
    2
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java
  6. 0
    2
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java
  7. 108
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java
  8. 1
    1
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
  9. 3
    3
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
  10. 2
    2
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java
  11. 2
    2
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java
  12. 2
    2
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/XooTokenizerSensorTest.java
  13. 50
    0
      sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
  14. 77
    0
      sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
  15. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultInputFileValueCoder.java
  16. 1
    2
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java
  17. 1
    2
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java
  18. 3
    2
      sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerMeasureCache.java
  19. 7
    0
      sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java
  20. 17
    5
      sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java
  21. 32
    1
      sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
  22. 7
    0
      sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
  23. 66
    0
      sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java
  24. 77
    0
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java
  25. 69
    0
      sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java
  26. 27
    0
      sonar-batch/src/main/java/org/sonar/batch/test/package-info.java
  27. 5
    2
      sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java
  28. 1
    3
      sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java
  29. 14
    16
      sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java
  30. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
  31. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java
  32. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java
  33. 130
    0
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java
  34. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
  35. 8
    8
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java
  36. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java
  37. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java
  38. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java
  39. 10
    10
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java
  40. 2
    3
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputPathCacheTest.java
  41. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java
  42. 2
    4
      sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java
  43. 8
    8
      sonar-batch/src/test/java/org/sonar/batch/scan2/AnalyzerOptimizerTest.java
  44. 1
    1
      sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
  45. 11
    23
      sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java
  46. 11
    11
      sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
  47. 2
    2
      sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DeprecatedDefaultInputFile.java
  48. 2
    1
      sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java
  49. 38
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
  50. 69
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCase.java
  51. 61
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseBuilder.java
  52. 137
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java
  53. 86
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseBuilder.java
  54. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java
  55. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/package-info.java
  56. 6
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestCase.java
  57. 5
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestPlan.java
  58. 5
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestable.java
  59. 4
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/TestCase.java
  60. 4
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/TestPlan.java
  61. 5
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java
  62. 1
    1
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java
  63. 7
    7
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java
  64. 9
    12
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputDirTest.java
  65. 6
    7
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
  66. 6
    7
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DeprecatedDefaultInputFileTest.java
  67. 11
    11
      sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java
  68. 4
    4
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplicationBuilderTest.java
  69. 3
    3
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
  70. 3
    3
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java
  71. 71
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseBuilderTest.java
  72. 63
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseTest.java

+ 4
- 6
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java 파일 보기

@@ -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);

+ 2
- 3
plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java 파일 보기

@@ -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))
));

+ 4
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java 파일 보기

@@ -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,

+ 110
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/CoveragePerTestSensor.java 파일 보기

@@ -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);
}
}
}

+ 0
- 2
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java 파일 보기

@@ -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);
}

+ 0
- 2
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java 파일 보기

@@ -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);
}

+ 108
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/TestCaseSensor.java 파일 보기

@@ -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);
}
}
}

+ 1
- 1
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java 파일 보기

@@ -27,6 +27,6 @@ public class XooPluginTest {

@Test
public void provide_extensions() {
assertThat(new XooPlugin().getExtensions()).hasSize(11);
assertThat(new XooPlugin().getExtensions()).hasSize(13);
}
}

+ 3
- 3
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java 파일 보기

@@ -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());

+ 2
- 2
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java 파일 보기

@@ -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);

+ 2
- 2
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java 파일 보기

@@ -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);

+ 2
- 2
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/XooTokenizerSensorTest.java 파일 보기

@@ -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);

+ 50
- 0
sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java 파일 보기

@@ -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

+ 77
- 0
sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java 파일 보기

@@ -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;
}

}

+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultInputFileValueCoder.java 파일 보기

@@ -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;
}


+ 1
- 2
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java 파일 보기

@@ -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);
}
}

+ 1
- 2
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java 파일 보기

@@ -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);

+ 3
- 2
sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerMeasureCache.java 파일 보기

@@ -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");
}


+ 7
- 0
sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java 파일 보기

@@ -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);
}

}

+ 17
- 5
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java 파일 보기

@@ -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();

+ 32
- 1
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java 파일 보기

@@ -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);
}

}

+ 7
- 0
sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java 파일 보기

@@ -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);
}


+ 66
- 0
sonar-batch/src/main/java/org/sonar/batch/test/CoveragePerTestCache.java 파일 보기

@@ -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;
}

}

+ 77
- 0
sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCaseValueCoder.java 파일 보기

@@ -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);
}
}

+ 69
- 0
sonar-batch/src/main/java/org/sonar/batch/test/TestCaseCache.java 파일 보기

@@ -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);
}

}

+ 27
- 0
sonar-batch/src/main/java/org/sonar/batch/test/package-info.java 파일 보기

@@ -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;

+ 5
- 2
sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java 파일 보기

@@ -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")));


+ 1
- 3
sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.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);
}


+ 14
- 16
sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java 파일 보기

@@ -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);

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java 파일 보기

@@ -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();
}

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java 파일 보기

@@ -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"));

}


+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java 파일 보기

@@ -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());
}

+ 130
- 0
sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java 파일 보기

@@ -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);
}
}

+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java 파일 보기

@@ -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);


+ 8
- 8
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java 파일 보기

@@ -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();
}
}

+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java 파일 보기

@@ -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)

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java 파일 보기

@@ -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();

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java 파일 보기

@@ -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)

+ 10
- 10
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java 파일 보기

@@ -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();
}


+ 2
- 3
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputPathCacheTest.java 파일 보기

@@ -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())

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java 파일 보기

@@ -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 {

+ 2
- 4
sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java 파일 보기

@@ -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));

+ 8
- 8
sonar-batch/src/test/java/org/sonar/batch/scan2/AnalyzerOptimizerTest.java 파일 보기

@@ -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();
}


+ 1
- 1
sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java 파일 보기

@@ -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");
}


+ 11
- 23
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputDir.java 파일 보기

@@ -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 + "]";
}
}

+ 11
- 11
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java 파일 보기

@@ -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 + "]";
}
}

+ 2
- 2
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DeprecatedDefaultInputFile.java 파일 보기

@@ -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);
}

/**

+ 2
- 1
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/Rules.java 파일 보기

@@ -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);

+ 38
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java 파일 보기

@@ -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);

}

+ 69
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCase.java 파일 보기

@@ -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();

}

+ 61
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/TestCaseBuilder.java 파일 보기

@@ -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();

}

+ 137
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java 파일 보기

@@ -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();
}
}

+ 86
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseBuilder.java 파일 보기

@@ -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);
}

}

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/package-info.java 파일 보기

@@ -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;

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/package-info.java 파일 보기

@@ -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;

+ 6
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestCase.java 파일 보기

@@ -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);


+ 5
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestPlan.java 파일 보기

@@ -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);

+ 5
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestable.java 파일 보기

@@ -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 {

}

+ 4
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/TestCase.java 파일 보기

@@ -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;

+ 4
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/TestPlan.java 파일 보기

@@ -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();


+ 5
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java 파일 보기

@@ -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();

+ 1
- 1
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java 파일 보기

@@ -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);

+ 7
- 7
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java 파일 보기

@@ -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();

+ 9
- 12
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputDirTest.java 파일 보기

@@ -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=");

}


+ 6
- 7
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java 파일 보기

@@ -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]");
}
}

+ 6
- 7
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DeprecatedDefaultInputFileTest.java 파일 보기

@@ -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]");
}
}

+ 11
- 11
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/PathPatternTest.java 파일 보기

@@ -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"
});

+ 4
- 4
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/duplication/internal/DefaultDuplicationBuilderTest.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);

+ 3
- 3
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java 파일 보기

@@ -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)

+ 3
- 3
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java 파일 보기

@@ -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();
}

+ 71
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseBuilderTest.java 파일 보기

@@ -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();
}

}

+ 63
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCaseTest.java 파일 보기

@@ -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());
}

}

Loading…
취소
저장