Parcourir la source

SONAR-7876 Add an API for Sensors to report files that can't be analyzed

tags/6.0-RC1
Duarte Meneses il y a 8 ans
Parent
révision
ae5a68d205
18 fichiers modifiés avec 610 ajouts et 3 suppressions
  1. 4
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
  2. 95
    0
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AnalysisErrorSensor.java
  3. 2
    2
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
  4. 79
    0
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java
  5. 7
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
  6. 50
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/AnalysisError.java
  7. 53
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/NewAnalysisError.java
  8. 86
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java
  9. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/package-info.java
  10. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/package-info.java
  11. 7
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
  12. 12
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
  13. 6
    1
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
  14. 78
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java
  15. 24
    0
      sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
  16. 8
    0
      sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java
  17. 6
    0
      sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
  18. 51
    0
      sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewAnalysisError.java

+ 4
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java Voir le fichier

@@ -32,6 +32,7 @@ import org.sonar.xoo.lang.SymbolReferencesSensor;
import org.sonar.xoo.lang.SyntaxHighlightingSensor;
import org.sonar.xoo.lang.XooCpdMapping;
import org.sonar.xoo.lang.XooTokenizer;
import org.sonar.xoo.rule.AnalysisErrorSensor;
import org.sonar.xoo.rule.ChecksSensor;
import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
import org.sonar.xoo.rule.CustomMessageSensor;
@@ -118,6 +119,9 @@ public class XooPlugin implements Plugin {
ItCoverageSensor.class,
OverallCoverageSensor.class,

// Analysis errors
AnalysisErrorSensor.class,

// Tests
TestExecutionSensor.class,
CoveragePerTestSensor.class,

+ 95
- 0
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AnalysisErrorSensor.java Voir le fichier

@@ -0,0 +1,95 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.xoo.rule;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.xoo.Xoo;

public class AnalysisErrorSensor implements Sensor {
private static final Logger LOG = Loggers.get(AnalysisErrorSensor.class);
private static final String ERROR_EXTENSION = ".error";

@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo Analysis Error Sensor")
.onlyOnLanguages(Xoo.KEY);
}

@Override
public void execute(SensorContext context) {
for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
processFileError(file, context);
}
}

private void processFileError(InputFile inputFile, SensorContext context) {
Path ioFile = inputFile.file().toPath();
Path errorFile = ioFile.resolveSibling(ioFile.getFileName() + ERROR_EXTENSION).toAbsolutePath();
if (Files.exists(errorFile) && Files.isRegularFile(errorFile)) {
LOG.debug("Processing " + errorFile.toString());
try {
List<String> lines = Files.readAllLines(errorFile, context.fileSystem().encoding());
for (String line : lines) {
if (StringUtils.isBlank(line) || line.startsWith("#")) {
continue;
}
processLine(line, inputFile, context);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}

private void processLine(String fileLine, InputFile inputFile, SensorContext context) {
String[] textPointer = fileLine.split(",");
if (textPointer.length != 3) {
throw new IllegalStateException("Invalid format in error file");
}

try {
int line = Integer.parseInt(textPointer[0]);
int lineOffset = Integer.parseInt(textPointer[1]);
String msg = textPointer[2];

context.newAnalysisError()
.onFile(inputFile)
.at(inputFile.newPointer(line, lineOffset))
.message(msg)
.save();

} catch (NumberFormatException e) {
throw new IllegalStateException("Invalid format in error file", e);
}
}

}

+ 2
- 2
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java Voir le fichier

@@ -35,10 +35,10 @@ public class XooPluginTest {
public void provide_extensions_for_5_5() {
Plugin.Context context = new Plugin.Context(new SonarRuntime(Version.parse("5.5"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER));
new XooPlugin().define(context);
assertThat(context.getExtensions()).hasSize(41).contains(CpdTokenizerSensor.class);
assertThat(context.getExtensions()).hasSize(42).contains(CpdTokenizerSensor.class);

context = new Plugin.Context(new SonarRuntime(Version.parse("5.4"), SonarProduct.SONARLINT, null));
new XooPlugin().define(context);
assertThat(context.getExtensions()).hasSize(40).doesNotContain(CpdTokenizerSensor.class);
assertThat(context.getExtensions()).hasSize(41).doesNotContain(CpdTokenizerSensor.class);
}
}

+ 79
- 0
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java Voir le fichier

@@ -0,0 +1,79 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.xoo.rule;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import static org.assertj.core.api.Assertions.*;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

public class AnalysisErrorSensorTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

private AnalysisErrorSensor sensor;
private SensorContextTester context;

@Before
public void setUp() {
sensor = new AnalysisErrorSensor();
}

private void createErrorFile(Path baseDir) throws IOException {
Path srcDir = baseDir.resolve("src");
Files.createDirectories(srcDir);
Path errorFile = srcDir.resolve("foo.xoo.error");

List<String> errors = new ArrayList<>();
errors.add("1,4,my error");

Files.write(errorFile, errors, StandardCharsets.UTF_8);
}

@Test
public void test() throws IOException {
Path baseDir = temp.newFolder().toPath().toAbsolutePath();
createErrorFile(baseDir);

DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo");
context = SensorContextTester.create(baseDir);
context.fileSystem().add(inputFile);

sensor.execute(context);
assertThat(context.allAnalysisErrors()).hasSize(1);
AnalysisError error = context.allAnalysisErrors().iterator().next();

assertThat(error.inputFile()).isEqualTo(inputFile);
assertThat(error.location()).isEqualTo(new DefaultTextPointer(1, 4));
assertThat(error.message()).isEqualTo("my error");
}
}

+ 7
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java Voir le fichier

@@ -26,6 +26,7 @@ import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
import org.sonar.api.batch.sensor.internal.SensorContextTester;
import org.sonar.api.batch.sensor.issue.Issue;
@@ -127,4 +128,10 @@ public interface SensorContext {
*/
NewCpdTokens newCpdTokens();

/**
* Builder to declare errors that happened while processing a source file.
* Don't forget to call {@link NewAnalisisError#save()}.
* @since 6.0
*/
NewAnalysisError newAnalysisError();
}

+ 50
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/AnalysisError.java Voir le fichier

@@ -0,0 +1,50 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.error;

import javax.annotation.CheckForNull;

import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.sensor.Sensor;

/**
* Represents an analysis error, such as a parsing error, reported by a {@link Sensor}.
*
* @since 6.0
*/
public interface AnalysisError {
/**
* The file that was being processed when the error occurred.
*/
InputFile inputFile();
/**
* A description of the error.
*/
@CheckForNull
String message();
/**
* Location of the error.
*/
@CheckForNull
TextPointer location();
}

+ 53
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/NewAnalysisError.java Voir le fichier

@@ -0,0 +1,53 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.error;

import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.sensor.Sensor;

/**
* Represents an analysis error, such as a parsing error, that occurs during the execution of a {@link Sensor}.
* Multiple analysis errors might be reported for the same file and issues may be created for a file which also has analysis errors reported.
* The handling of such situations is unspecified and might vary depending on the implementation.
*
* @since 6.0
*/
public interface NewAnalysisError {
/**
* The file that was being processed when the error occurred. This field must be set before saving the error.
*/
NewAnalysisError onFile(InputFile inputFile);

/**
* Message about the error. This field is optional.
*/
NewAnalysisError message(String message);

/**
* Location of this error. This field is optional.
*/
NewAnalysisError at(TextPointer location);

/**
* Save this error information.
*/
void save();
}

+ 86
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java Voir le fichier

@@ -0,0 +1,86 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.error.internal;

import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;

import com.google.common.base.Preconditions;

public class DefaultAnalysisError extends DefaultStorable implements NewAnalysisError, AnalysisError {
private InputFile inputFile;
private String message;
private TextPointer location;

public DefaultAnalysisError() {
super(null);
}

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

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

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

@Override
public TextPointer location() {
return location;
}

@Override
public NewAnalysisError onFile(InputFile inputFile) {
Preconditions.checkArgument(inputFile != null, "Cannot use a inputFile that is null");
Preconditions.checkState(this.inputFile == null, "onFile() already called");
this.inputFile = inputFile;
return this;
}

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

@Override
public NewAnalysisError at(TextPointer location) {
Preconditions.checkState(this.location == null, "at() already called");
this.location = location;
return this;
}

@Override
protected void doSave() {
Preconditions.checkNotNull(this.inputFile, "inputFile is mandatory on AnalysisError");
storage.store(this);
}

}

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/package-info.java Voir le fichier

@@ -0,0 +1,21 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.api.batch.sensor.error.internal;

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/package-info.java Voir le fichier

@@ -0,0 +1,21 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.api.batch.sensor.error;

+ 7
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java Voir le fichier

@@ -28,6 +28,7 @@ import java.util.Map;
import org.sonar.api.batch.sensor.coverage.CoverageType;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
@@ -39,6 +40,7 @@ class InMemorySensorStorage implements SensorStorage {
Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create();

Collection<Issue> allIssues = new ArrayList<>();
Collection<AnalysisError> allAnalysisErrors = new ArrayList<>();

Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>();
@@ -101,4 +103,9 @@ class InMemorySensorStorage implements SensorStorage {
symbolsPerComponent.put(fileKey, symbolTable);
}

@Override
public void store(AnalysisError analysisError) {
allAnalysisErrors.add(analysisError);
}

}

+ 12
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java Voir le fichier

@@ -47,6 +47,9 @@ import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.error.internal.DefaultAnalysisError;
import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
@@ -192,6 +195,10 @@ public class SensorContextTester implements SensorContext {
public Collection<Issue> allIssues() {
return sensorStorage.allIssues;
}
public Collection<AnalysisError> allAnalysisErrors() {
return sensorStorage.allAnalysisErrors;
}

@CheckForNull
public Integer lineHits(String fileKey, CoverageType type, int line) {
@@ -245,6 +252,11 @@ public class SensorContextTester implements SensorContext {
public NewSymbolTable newSymbolTable() {
return new DefaultSymbolTable(sensorStorage);
}
@Override
public NewAnalysisError newAnalysisError() {
return new DefaultAnalysisError(sensorStorage);
}

/**
* Return list of syntax highlighting applied for a given position in a file. The result is a list because in theory you

+ 6
- 1
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java Voir le fichier

@@ -22,6 +22,7 @@ package org.sonar.api.batch.sensor.internal;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
@@ -54,5 +55,9 @@ public interface SensorStorage {
* @since 5.6
*/
void store(DefaultSymbolTable symbolTable);

/**
* @since 6.0
*/
void store(AnalysisError analysisError);
}

+ 78
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java Voir le fichier

@@ -0,0 +1,78 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.batch.sensor.error.internal;

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

import org.junit.Before;
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.TextPointer;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import static org.assertj.core.api.Assertions.assertThat;

public class DefaultAnalysisErrorTest {
private InputFile inputFile;
private SensorStorage storage;
private TextPointer textPointer;

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

@Before
public void setUp() {
inputFile = new DefaultInputFile("module1", "src/File.java");
textPointer = new DefaultTextPointer(5, 2);
storage = mock(SensorStorage.class);
}

@Test
public void test_analysis_error() {
DefaultAnalysisError analysisError = new DefaultAnalysisError(storage);
analysisError.onFile(inputFile)
.at(textPointer)
.message("msg");

assertThat(analysisError.location()).isEqualTo(textPointer);
assertThat(analysisError.message()).isEqualTo("msg");
assertThat(analysisError.inputFile()).isEqualTo(inputFile);
}

@Test
public void test_save() {
DefaultAnalysisError analysisError = new DefaultAnalysisError(storage);
analysisError.onFile(inputFile).save();

verify(storage).store(analysisError);
verifyNoMoreInteractions(storage);
}

@Test
public void test_must_have_file() {
exception.expect(NullPointerException.class);
new DefaultAnalysisError(storage).save();
}
}

+ 24
- 0
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java Voir le fichier

@@ -26,14 +26,18 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.batch.sensor.coverage.CoverageType;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
@@ -100,6 +104,26 @@ public class SensorContextTesterTest {
assertThat(tester.allIssues()).hasSize(2);
}

@Test
public void testAnalysisErrors() {
assertThat(tester.allAnalysisErrors()).isEmpty();
NewAnalysisError newAnalysisError = tester.newAnalysisError();

InputFile file = new DefaultInputFile("foo", "src/Foo.java");
newAnalysisError.onFile(file)
.message("error")
.at(new DefaultTextPointer(5, 2))
.save();

assertThat(tester.allAnalysisErrors()).hasSize(1);
AnalysisError analysisError = tester.allAnalysisErrors().iterator().next();

assertThat(analysisError.inputFile()).isEqualTo(file);
assertThat(analysisError.message()).isEqualTo("error");
assertThat(analysisError.location()).isEqualTo(new DefaultTextPointer(5, 2));

}

@Test
public void testMeasures() {
assertThat(tester.measures("foo:src/Foo.java")).isEmpty();

+ 8
- 0
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorContext.java Voir le fichier

@@ -31,6 +31,7 @@ import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.highlighting.NewHighlighting;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -42,6 +43,7 @@ import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.Version;
import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError;
import org.sonar.scanner.sensor.noop.NoOpNewCpdTokens;
import org.sonar.scanner.sensor.noop.NoOpNewHighlighting;
import org.sonar.scanner.sensor.noop.NoOpNewSymbolTable;
@@ -51,6 +53,7 @@ public class DefaultSensorContext implements SensorContext {
private static final NoOpNewHighlighting NO_OP_NEW_HIGHLIGHTING = new NoOpNewHighlighting();
private static final NoOpNewSymbolTable NO_OP_NEW_SYMBOL_TABLE = new NoOpNewSymbolTable();
private static final NoOpNewCpdTokens NO_OP_NEW_CPD_TOKENS = new NoOpNewCpdTokens();
private static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError();

private final Settings settings;
private final FileSystem fs;
@@ -145,4 +148,9 @@ public class DefaultSensorContext implements SensorContext {
return new DefaultCpdTokens(settings, sensorStorage);
}

@Override
public NewAnalysisError newAnalysisError() {
return NO_OP_NEW_ANALYSIS_ERROR;
}

}

+ 6
- 0
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java Voir le fichier

@@ -37,6 +37,7 @@ import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.batch.sensor.coverage.CoverageType;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.error.AnalysisError;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
import org.sonar.api.batch.sensor.internal.SensorStorage;
@@ -288,4 +289,9 @@ public class DefaultSensorStorage implements SensorStorage {
return blockSize;
}

@Override
public void store(AnalysisError analysisError) {
// no op
}

}

+ 51
- 0
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/noop/NoOpNewAnalysisError.java Voir le fichier

@@ -0,0 +1,51 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.scanner.sensor.noop;

import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.sensor.error.NewAnalysisError;

public class NoOpNewAnalysisError implements NewAnalysisError {

@Override
public NewAnalysisError onFile(InputFile inputFile) {
// no op
return this;
}

@Override
public NewAnalysisError message(String message) {
// no op
return this;
}

@Override
public NewAnalysisError at(TextPointer location) {
// no op
return this;
}

@Override
public void save() {
// no op
}

}

Chargement…
Annuler
Enregistrer