From: Duarte Meneses Date: Tue, 4 Jun 2019 20:43:44 +0000 (-0500) Subject: Extract implementation from plugin API - fix tests X-Git-Tag: 8.0~355 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e020f1425d815ae48e9b5c39bc0eaf92382c3c06;p=sonarqube.git Extract implementation from plugin API - fix tests --- diff --git a/plugins/sonar-xoo-plugin/build.gradle b/plugins/sonar-xoo-plugin/build.gradle index 693f0cb1363..d9236cf050b 100644 --- a/plugins/sonar-xoo-plugin/build.gradle +++ b/plugins/sonar-xoo-plugin/build.gradle @@ -11,6 +11,7 @@ dependencies { runtime project(path: ':sonar-plugin-api', configuration: 'shadow') compileOnly project(path: ':sonar-plugin-api') + testCompile project(path: ':sonar-scanner-engine') testCompile 'junit:junit' testCompile 'org.assertj:assertj-core' testCompile 'org.mockito:mockito-core' diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java index dd4ebcaa1d0..1f5128ddc79 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java @@ -28,9 +28,9 @@ 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.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java index 7d453c9ae40..a6c88780840 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java @@ -28,9 +28,9 @@ 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.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java index cf9023c9cf7..429a64722fd 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java @@ -28,9 +28,9 @@ 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.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java index 7af90432a97..5474f266af6 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java @@ -19,14 +19,12 @@ */ package org.sonar.xoo.extensions; +import java.util.Arrays; import org.junit.Rule; import org.junit.Test; import org.sonar.api.batch.postjob.PostJobContext; -import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; -import org.sonar.api.batch.postjob.issue.PostJobIssue; import org.sonar.api.utils.log.LogTester; - -import java.util.Arrays; +import org.sonar.scanner.postjob.DefaultPostJobDescriptor; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java index 1eb4fd88650..1464eaa8e62 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java @@ -28,9 +28,9 @@ 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.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java index 7ed38d42e0e..5d36dcf4097 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java @@ -29,12 +29,12 @@ 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.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java index 03adee97ed3..5293d3128cf 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java @@ -31,9 +31,9 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.fs.internal.DefaultTextRange; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java index 98d57b104e3..2093e773d49 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java @@ -29,9 +29,9 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.fs.internal.DefaultTextRange; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import org.sonar.xoo.Xoo; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java index a729d4bf9f9..965d4d653e4 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java @@ -27,10 +27,10 @@ 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.TestInputFileBuilder; import org.sonar.api.batch.sensor.highlighting.TypeOfText; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java index 647e411cae5..c5aa5d4534c 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java @@ -25,16 +25,15 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; - 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.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.error.AnalysisError; -import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java index ab8a6ddafea..1d6c610ca49 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java @@ -26,13 +26,13 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.SonarQubeSide; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.Version; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; +import org.sonar.scanner.sensor.SensorContextTester; import org.sonar.xoo.Xoo; import static org.assertj.core.api.Assertions.assertThat; diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java index 9f9a1a22b0e..ef30ede34f0 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java @@ -28,13 +28,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.scm.BlameCommand.BlameInput; import org.sonar.api.batch.scm.BlameCommand.BlameOutput; import org.sonar.api.batch.scm.BlameLine; import org.sonar.api.utils.DateUtils; +import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.xoo.Xoo; import static java.util.Collections.singletonList; diff --git a/sonar-plugin-api/build.gradle b/sonar-plugin-api/build.gradle index 3c2b3d3a0da..1475a50d800 100644 --- a/sonar-plugin-api/build.gradle +++ b/sonar-plugin-api/build.gradle @@ -33,6 +33,7 @@ dependencies { testCompile 'com.tngtech.java:junit-dataprovider' testCompile 'org.assertj:assertj-core' testCompile 'org.mockito:mockito-core' + testCompile project(':sonar-scanner-engine') } sourceSets { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java index ba7cb94cff3..229280fca5b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; +import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @@ -37,6 +38,8 @@ import org.sonar.api.utils.PathUtils; */ @Immutable public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile { + private static AtomicInteger intGenerator = new AtomicInteger(0); + private final String projectRelativePath; private final String moduleRelativePath; private final String projectKey; @@ -45,6 +48,14 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed private final Path absolutePath; private final SensorStrategy sensorStrategy; + /** + * Testing purposes only! + */ + public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) { + this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, intGenerator.getAndIncrement(), + new SensorStrategy()); + } + public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId, SensorStrategy sensorStrategy) { super(batchId); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/package-info.java deleted file mode 100644 index 3280c38fbd9..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.postjob.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java deleted file mode 100644 index 89dea63e1cf..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.highlighting.internal; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.highlighting.NewHighlighting; -import org.sonar.api.batch.sensor.highlighting.TypeOfText; -import org.sonar.api.batch.sensor.internal.DefaultStorable; -import org.sonar.api.batch.sensor.internal.SensorStorage; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkState; - -public class DefaultHighlighting extends DefaultStorable implements NewHighlighting { - - private final List syntaxHighlightingRules; - private DefaultInputFile inputFile; - - public DefaultHighlighting(SensorStorage storage) { - super(storage); - syntaxHighlightingRules = new ArrayList<>(); - } - - public List getSyntaxHighlightingRuleSet() { - return syntaxHighlightingRules; - } - - private void checkOverlappingBoundaries() { - if (syntaxHighlightingRules.size() > 1) { - Iterator it = syntaxHighlightingRules.iterator(); - SyntaxHighlightingRule previous = it.next(); - while (it.hasNext()) { - SyntaxHighlightingRule current = it.next(); - if (previous.range().end().compareTo(current.range().start()) > 0 && (previous.range().end().compareTo(current.range().end()) < 0)) { - String errorMsg = String.format("Cannot register highlighting rule for characters at %s as it " + - "overlaps at least one existing rule", current.range()); - throw new IllegalStateException(errorMsg); - } - previous = current; - } - } - } - - @Override - public DefaultHighlighting onFile(InputFile inputFile) { - requireNonNull(inputFile, "file can't be null"); - this.inputFile = (DefaultInputFile) inputFile; - return this; - } - - public InputFile inputFile() { - return inputFile; - } - - @Override - public DefaultHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText) { - checkInputFileNotNull(); - TextRange newRange; - try { - newRange = inputFile.newRange(startOffset, endOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to highlight file " + inputFile, e); - } - return highlight(newRange, typeOfText); - } - - @Override - public DefaultHighlighting highlight(int startLine, int startLineOffset, int endLine, int endLineOffset, TypeOfText typeOfText) { - checkInputFileNotNull(); - TextRange newRange; - try { - newRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); - } catch (Exception e) { - throw new IllegalArgumentException("Unable to highlight file " + inputFile, e); - } - return highlight(newRange, typeOfText); - } - - @Override - public DefaultHighlighting highlight(TextRange range, TypeOfText typeOfText) { - SyntaxHighlightingRule syntaxHighlightingRule = SyntaxHighlightingRule.create(range, typeOfText); - this.syntaxHighlightingRules.add(syntaxHighlightingRule); - return this; - } - - @Override - protected void doSave() { - checkInputFileNotNull(); - // Sort rules to avoid variation during consecutive runs - Collections.sort(syntaxHighlightingRules, (left, right) -> { - int result = left.range().start().compareTo(right.range().start()); - if (result == 0) { - result = right.range().end().compareTo(left.range().end()); - } - return result; - }); - checkOverlappingBoundaries(); - storage.store(this); - } - - private void checkInputFileNotNull() { - checkState(inputFile != null, "Call onFile() first"); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java deleted file mode 100644 index 22934dc19d2..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.highlighting.internal; - -import org.apache.commons.lang.builder.ReflectionToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.sensor.highlighting.TypeOfText; - -public class SyntaxHighlightingRule { - - private final TextRange range; - private final TypeOfText textType; - - private SyntaxHighlightingRule(TextRange range, TypeOfText textType) { - this.range = range; - this.textType = textType; - } - - public static SyntaxHighlightingRule create(TextRange range, TypeOfText textType) { - return new SyntaxHighlightingRule(range, textType); - } - - public TextRange range() { - return range; - } - - public TypeOfText getTextType() { - return textType; - } - - @Override - public String toString() { - return ReflectionToStringBuilder.toString(this, ToStringStyle.SIMPLE_STYLE); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java deleted file mode 100644 index 7c527665090..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.highlighting.internal; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java index 2bfe79bfba8..fde8e22e5ac 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java @@ -19,20 +19,21 @@ */ package org.sonar.api.batch.sensor.internal; -import org.sonar.api.batch.sensor.issue.ExternalIssue; -import org.sonar.api.batch.sensor.rule.AdHocRule; -import org.sonar.api.scanner.ScannerSide; import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; 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.NewHighlighting; +import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; +import org.sonar.api.batch.sensor.rule.AdHocRule; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; +import org.sonar.api.scanner.ScannerSide; /** * Interface for storing data computed by sensors. + * * @since 5.1 */ @ScannerSide @@ -46,7 +47,7 @@ public interface SensorStorage { void store(AdHocRule adHocRule); - void store(DefaultHighlighting highlighting); + void store(NewHighlighting highlighting); /** * @since 5.2 @@ -54,12 +55,12 @@ public interface SensorStorage { void store(DefaultCoverage defaultCoverage); /** - * @since 5.5 + * @since 5.5 */ void store(DefaultCpdTokens defaultCpdTokens); /** - * @since 5.6 + * @since 5.6 */ void store(DefaultSymbolTable symbolTable); @@ -70,6 +71,7 @@ public interface SensorStorage { /** * Value is overridden if the key was already stored. + * * @throws IllegalArgumentException if key is null * @throws IllegalArgumentException if value is null * @since 6.1 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java index f104d0cef64..bb155753d55 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java @@ -20,11 +20,9 @@ package org.sonar.api.internal; import java.io.IOException; -import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; +import java.util.Scanner; import org.sonar.api.SonarEdition; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; @@ -48,10 +46,11 @@ public class MetadataLoader { public static Version loadVersion(System2 system) { try { URL url = system.getResource(VERSION_FILE_PATH); - String versionInFile = new String(Files.readAllBytes(Paths.get(url.toURI())), StandardCharsets.UTF_8); + Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name()); + String versionInFile = scanner.nextLine(); return Version.parse(versionInFile); - } catch (IOException | URISyntaxException e) { - throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath", e); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath ", e); } } @@ -61,9 +60,10 @@ public class MetadataLoader { if (url == null) { return SonarEdition.COMMUNITY; } - String editionInFile = new String(Files.readAllBytes(Paths.get(url.toURI())), StandardCharsets.UTF_8); + Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name()); + String editionInFile = scanner.nextLine(); return parseEdition(editionInFile); - } catch (IOException | URISyntaxException e) { + } catch (IOException e) { throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/AndPredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/AndPredicateTest.java deleted file mode 100644 index e82241b4413..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/AndPredicateTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import org.junit.Test; -import org.sonar.api.batch.fs.FilePredicate; - -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThat; - -public class AndPredicateTest { - - @Test - public void flattenNestedAnd() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); - FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, - AndPredicate.create(Arrays.asList(pathPatternPredicate2, pathPatternPredicate3)))); - assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); - } - - @Test - public void sortPredicatesByPriority() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - RelativePathPredicate relativePathPredicate = new RelativePathPredicate("foo"); - FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, - relativePathPredicate, pathPatternPredicate2)); - assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(relativePathPredicate, pathPatternPredicate1, pathPatternPredicate2); - } - - @Test - public void simplifyAndExpressionsWhenEmpty() { - FilePredicate andPredicate = AndPredicate.create(Arrays.asList()); - assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); - } - - @Test - public void simplifyAndExpressionsWhenTrue() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, - TruePredicate.TRUE, pathPatternPredicate2)); - assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); - } - - @Test - public void simplifyAndExpressionsWhenFalse() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, - FalsePredicate.FALSE, pathPatternPredicate2)); - assertThat(andPredicate).isEqualTo(FalsePredicate.FALSE); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java deleted file mode 100644 index 6d04f5dab72..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.FilePredicates; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputFile.Status; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultFilePredicatesTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private Path moduleBasePath; - - @Before - public void setUp() throws IOException { - moduleBasePath = temp.newFolder().toPath(); - } - - InputFile javaFile; - FilePredicates predicates; - - @Before - public void before() throws IOException { - predicates = new DefaultFilePredicates(temp.newFolder().toPath()); - javaFile = new TestInputFileBuilder("foo", "src/main/java/struts/Action.java") - .setModuleBaseDir(moduleBasePath) - .setLanguage("java") - .setStatus(Status.SAME) - .build(); - - } - - @Test - public void all() { - assertThat(predicates.all().apply(javaFile)).isTrue(); - } - - @Test - public void none() { - assertThat(predicates.none().apply(javaFile)).isFalse(); - } - - @Test - public void matches_inclusion_pattern() { - assertThat(predicates.matchesPathPattern("src/main/**/Action.java").apply(javaFile)).isTrue(); - assertThat(predicates.matchesPathPattern("Action.java").apply(javaFile)).isFalse(); - assertThat(predicates.matchesPathPattern("src/**/*.php").apply(javaFile)).isFalse(); - } - - @Test - public void matches_inclusion_patterns() { - assertThat(predicates.matchesPathPatterns(new String[] {"src/other/**.java", "src/main/**/Action.java"}).apply(javaFile)).isTrue(); - assertThat(predicates.matchesPathPatterns(new String[] {}).apply(javaFile)).isTrue(); - assertThat(predicates.matchesPathPatterns(new String[] {"src/other/**.java", "src/**/*.php"}).apply(javaFile)).isFalse(); - } - - @Test - public void does_not_match_exclusion_pattern() { - assertThat(predicates.doesNotMatchPathPattern("src/main/**/Action.java").apply(javaFile)).isFalse(); - assertThat(predicates.doesNotMatchPathPattern("Action.java").apply(javaFile)).isTrue(); - assertThat(predicates.doesNotMatchPathPattern("src/**/*.php").apply(javaFile)).isTrue(); - } - - @Test - public void does_not_match_exclusion_patterns() { - assertThat(predicates.doesNotMatchPathPatterns(new String[] {}).apply(javaFile)).isTrue(); - assertThat(predicates.doesNotMatchPathPatterns(new String[] {"src/other/**.java", "src/**/*.php"}).apply(javaFile)).isTrue(); - assertThat(predicates.doesNotMatchPathPatterns(new String[] {"src/other/**.java", "src/main/**/Action.java"}).apply(javaFile)).isFalse(); - } - - @Test - public void has_relative_path() { - assertThat(predicates.hasRelativePath("src/main/java/struts/Action.java").apply(javaFile)).isTrue(); - assertThat(predicates.hasRelativePath("src/main/java/struts/Other.java").apply(javaFile)).isFalse(); - - // path is normalized - assertThat(predicates.hasRelativePath("src/main/java/../java/struts/Action.java").apply(javaFile)).isTrue(); - - assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\Action.java").apply(javaFile)).isTrue(); - assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\Other.java").apply(javaFile)).isFalse(); - assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\..\\struts\\Action.java").apply(javaFile)).isTrue(); - } - - @Test - public void has_absolute_path() throws Exception { - String path = javaFile.file().getAbsolutePath(); - assertThat(predicates.hasAbsolutePath(path).apply(javaFile)).isTrue(); - assertThat(predicates.hasAbsolutePath(path.replaceAll("/", "\\\\")).apply(javaFile)).isTrue(); - - assertThat(predicates.hasAbsolutePath(temp.newFile().getAbsolutePath()).apply(javaFile)).isFalse(); - assertThat(predicates.hasAbsolutePath("src/main/java/struts/Action.java").apply(javaFile)).isFalse(); - } - - @Test - public void has_uri() throws Exception { - URI uri = javaFile.uri(); - assertThat(predicates.hasURI(uri).apply(javaFile)).isTrue(); - - assertThat(predicates.hasURI(temp.newFile().toURI()).apply(javaFile)).isFalse(); - } - - @Test - public void has_path() throws Exception { - // is relative path - assertThat(predicates.hasPath("src/main/java/struts/Action.java").apply(javaFile)).isTrue(); - assertThat(predicates.hasPath("src/main/java/struts/Other.java").apply(javaFile)).isFalse(); - - // is absolute path - String path = javaFile.file().getAbsolutePath(); - assertThat(predicates.hasAbsolutePath(path).apply(javaFile)).isTrue(); - assertThat(predicates.hasPath(temp.newFile().getAbsolutePath()).apply(javaFile)).isFalse(); - } - - @Test - public void is_file() throws Exception { - // relative file - assertThat(predicates.is(new File(javaFile.relativePath())).apply(javaFile)).isTrue(); - - // absolute file - assertThat(predicates.is(javaFile.file()).apply(javaFile)).isTrue(); - assertThat(predicates.is(javaFile.file().getAbsoluteFile()).apply(javaFile)).isTrue(); - assertThat(predicates.is(new File(javaFile.file().toURI())).apply(javaFile)).isTrue(); - assertThat(predicates.is(temp.newFile()).apply(javaFile)).isFalse(); - } - - @Test - public void has_language() { - assertThat(predicates.hasLanguage("java").apply(javaFile)).isTrue(); - assertThat(predicates.hasLanguage("php").apply(javaFile)).isFalse(); - } - - @Test - public void has_languages() { - assertThat(predicates.hasLanguages(Arrays.asList("java", "php")).apply(javaFile)).isTrue(); - assertThat(predicates.hasLanguages(Arrays.asList("cobol", "php")).apply(javaFile)).isFalse(); - assertThat(predicates.hasLanguages(Collections.emptyList()).apply(javaFile)).isTrue(); - } - - @Test - public void has_type() { - assertThat(predicates.hasType(InputFile.Type.MAIN).apply(javaFile)).isTrue(); - assertThat(predicates.hasType(InputFile.Type.TEST).apply(javaFile)).isFalse(); - } - - @Test - public void has_status() { - assertThat(predicates.hasAnyStatus().apply(javaFile)).isTrue(); - assertThat(predicates.hasStatus(InputFile.Status.SAME).apply(javaFile)).isTrue(); - assertThat(predicates.hasStatus(InputFile.Status.ADDED).apply(javaFile)).isFalse(); - } - - @Test - public void not() { - assertThat(predicates.not(predicates.hasType(InputFile.Type.MAIN)).apply(javaFile)).isFalse(); - assertThat(predicates.not(predicates.hasType(InputFile.Type.TEST)).apply(javaFile)).isTrue(); - } - - @Test - public void and() { - // empty - assertThat(predicates.and().apply(javaFile)).isTrue(); - assertThat(predicates.and(new FilePredicate[0]).apply(javaFile)).isTrue(); - assertThat(predicates.and(Collections.emptyList()).apply(javaFile)).isTrue(); - - // two arguments - assertThat(predicates.and(predicates.all(), predicates.all()).apply(javaFile)).isTrue(); - assertThat(predicates.and(predicates.all(), predicates.none()).apply(javaFile)).isFalse(); - assertThat(predicates.and(predicates.none(), predicates.all()).apply(javaFile)).isFalse(); - - // collection - assertThat(predicates.and(Arrays.asList(predicates.all(), predicates.all())).apply(javaFile)).isTrue(); - assertThat(predicates.and(Arrays.asList(predicates.all(), predicates.none())).apply(javaFile)).isFalse(); - - // array - assertThat(predicates.and(new FilePredicate[] {predicates.all(), predicates.all()}).apply(javaFile)).isTrue(); - assertThat(predicates.and(new FilePredicate[] {predicates.all(), predicates.none()}).apply(javaFile)).isFalse(); - } - - @Test - public void or() { - // empty - assertThat(predicates.or().apply(javaFile)).isTrue(); - assertThat(predicates.or(new FilePredicate[0]).apply(javaFile)).isTrue(); - assertThat(predicates.or(Collections.emptyList()).apply(javaFile)).isTrue(); - - // two arguments - assertThat(predicates.or(predicates.all(), predicates.all()).apply(javaFile)).isTrue(); - assertThat(predicates.or(predicates.all(), predicates.none()).apply(javaFile)).isTrue(); - assertThat(predicates.or(predicates.none(), predicates.all()).apply(javaFile)).isTrue(); - assertThat(predicates.or(predicates.none(), predicates.none()).apply(javaFile)).isFalse(); - - // collection - assertThat(predicates.or(Arrays.asList(predicates.all(), predicates.all())).apply(javaFile)).isTrue(); - assertThat(predicates.or(Arrays.asList(predicates.all(), predicates.none())).apply(javaFile)).isTrue(); - assertThat(predicates.or(Arrays.asList(predicates.none(), predicates.none())).apply(javaFile)).isFalse(); - - // array - assertThat(predicates.or(new FilePredicate[] {predicates.all(), predicates.all()}).apply(javaFile)).isTrue(); - assertThat(predicates.or(new FilePredicate[] {predicates.all(), predicates.none()}).apply(javaFile)).isTrue(); - assertThat(predicates.or(new FilePredicate[] {predicates.none(), predicates.none()}).apply(javaFile)).isFalse(); - } - - @Test - public void hasFilename() { - assertThat(predicates.hasFilename("Action.java").apply(javaFile)).isTrue(); - } - - @Test - public void hasExtension() { - assertThat(predicates.hasExtension("java").apply(javaFile)).isTrue(); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java deleted file mode 100644 index f19cb244189..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import java.io.File; -import java.nio.charset.Charset; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultFileSystemTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private DefaultFileSystem fs; - - private File basedir; - - @Before - public void prepare() throws Exception { - basedir = temp.newFolder(); - fs = new DefaultFileSystem(basedir.toPath()); - } - - @Test - public void test_directories() throws Exception { - assertThat(fs.baseDir()).isAbsolute().isDirectory().exists(); - assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); - - File workdir = temp.newFolder(); - fs.setWorkDir(workdir.toPath()); - assertThat(fs.workDir()).isAbsolute().isDirectory().exists(); - assertThat(fs.workDir().getCanonicalPath()).isEqualTo(workdir.getCanonicalPath()); - } - - @Test - public void test_encoding() throws Exception { - fs.setEncoding(Charset.forName("ISO-8859-1")); - assertThat(fs.encoding()).isEqualTo(Charset.forName("ISO-8859-1")); - } - - @Test - public void add_languages() { - assertThat(fs.languages()).isEmpty(); - - fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); - fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); - - assertThat(fs.languages()).containsOnly("java", "php"); - } - - @Test - public void files() { - assertThat(fs.inputFiles(fs.predicates().all())).isEmpty(); - - fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); - fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); - fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); - - // no language - fs.add(new TestInputFileBuilder("foo", "src/readme.txt").build()); - - assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNotNull(); - assertThat(fs.inputFile(fs.predicates().hasRelativePath("does/not/exist"))).isNull(); - - assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "src/Bar.java").getAbsolutePath()))).isNotNull(); - assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "does/not/exist").getAbsolutePath()))).isNull(); - assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "../src/Bar.java").getAbsolutePath()))).isNull(); - - assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "src/Bar.java").toURI()))).isNotNull(); - assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "does/not/exist").toURI()))).isNull(); - assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "../src/Bar.java").toURI()))).isNull(); - - assertThat(fs.files(fs.predicates().all())).hasSize(4); - assertThat(fs.files(fs.predicates().hasLanguage("java"))).hasSize(2); - assertThat(fs.files(fs.predicates().hasLanguage("cobol"))).isEmpty(); - - assertThat(fs.hasFiles(fs.predicates().all())).isTrue(); - assertThat(fs.hasFiles(fs.predicates().hasLanguage("java"))).isTrue(); - assertThat(fs.hasFiles(fs.predicates().hasLanguage("cobol"))).isFalse(); - - assertThat(fs.inputFiles(fs.predicates().all())).hasSize(4); - assertThat(fs.inputFiles(fs.predicates().hasLanguage("php"))).hasSize(1); - assertThat(fs.inputFiles(fs.predicates().hasLanguage("java"))).hasSize(2); - assertThat(fs.inputFiles(fs.predicates().hasLanguage("cobol"))).isEmpty(); - - assertThat(fs.languages()).containsOnly("java", "php"); - } - - @Test - public void input_file_returns_null_if_file_not_found() { - assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNull(); - assertThat(fs.inputFile(fs.predicates().hasLanguage("cobol"))).isNull(); - } - - @Test - public void input_file_fails_if_too_many_results() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("expected one element"); - - fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); - fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); - - fs.inputFile(fs.predicates().all()); - } - - @Test - public void input_file_supports_non_indexed_predicates() { - fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); - - // it would fail if more than one java file - assertThat(fs.inputFile(fs.predicates().hasLanguage("java"))).isNotNull(); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java index 420f433557b..85feccc8581 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java @@ -40,6 +40,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; +import org.sonar.scanner.fs.FileMetadata; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java deleted file mode 100644 index a4b187b0ab2..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import java.io.IOException; -import org.junit.Test; -import org.sonar.api.batch.fs.InputFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.batch.fs.internal.FileExtensionPredicate.getExtension; - -public class FileExtensionPredicateTest { - - @Test - public void should_match_correct_extension() throws IOException { - FileExtensionPredicate predicate = new FileExtensionPredicate("bat"); - assertThat(predicate.apply(mockWithName("prog.bat"))).isTrue(); - assertThat(predicate.apply(mockWithName("prog.bat.bat"))).isTrue(); - } - - @Test - public void should_not_match_incorrect_extension() throws IOException { - FileExtensionPredicate predicate = new FileExtensionPredicate("bat"); - assertThat(predicate.apply(mockWithName("prog.batt"))).isFalse(); - assertThat(predicate.apply(mockWithName("prog.abat"))).isFalse(); - assertThat(predicate.apply(mockWithName("prog."))).isFalse(); - assertThat(predicate.apply(mockWithName("prog.bat."))).isFalse(); - assertThat(predicate.apply(mockWithName("prog.bat.batt"))).isFalse(); - assertThat(predicate.apply(mockWithName("prog"))).isFalse(); - } - - @Test - public void should_match_correct_extension_case_insensitively() throws IOException { - FileExtensionPredicate predicate = new FileExtensionPredicate("jAVa"); - assertThat(predicate.apply(mockWithName("Program.java"))).isTrue(); - assertThat(predicate.apply(mockWithName("Program.JAVA"))).isTrue(); - assertThat(predicate.apply(mockWithName("Program.Java"))).isTrue(); - assertThat(predicate.apply(mockWithName("Program.JaVa"))).isTrue(); - } - - @Test - public void test_empty_extension() { - assertThat(getExtension("prog")).isEmpty(); - assertThat(getExtension("prog.")).isEmpty(); - assertThat(getExtension(".")).isEmpty(); - } - - private InputFile mockWithName(String filename) throws IOException { - InputFile inputFile = mock(InputFile.class); - when(inputFile.filename()).thenReturn(filename); - return inputFile; - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java deleted file mode 100644 index 913166d4c6c..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -import javax.annotation.Nullable; -import org.apache.commons.codec.binary.Hex; -import org.apache.commons.io.FileUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.FileMetadata.LineHashConsumer; -import org.sonar.api.utils.log.LogTester; -import org.sonar.api.utils.log.LoggerLevel; - -import static org.apache.commons.codec.digest.DigestUtils.md5Hex; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -public class FileMetadataTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Rule - public LogTester logTester = new LogTester(); - - @Test - public void empty_file() throws Exception { - File tempFile = temp.newFile(); - FileUtils.touch(tempFile); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(1); - assertThat(metadata.nonBlankLines()).isEqualTo(0); - assertThat(metadata.hash()).isNotEmpty(); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0); - assertThat(metadata.originalLineEndOffsets()).containsOnly(0); - assertThat(metadata.isEmpty()).isTrue(); - } - - @Test - public void windows_without_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(3); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 8, 13); - assertThat(metadata.isEmpty()).isFalse(); - } - - @Test - public void read_with_wrong_encoding() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "marker´s\n", Charset.forName("cp1252")); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(2); - assertThat(metadata.hash()).isEqualTo(md5Hex("marker\ufffds\n")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 9); - } - - @Test - public void non_ascii_utf_8() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10, 18); - } - - @Test - public void non_ascii_utf_16() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_16, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_16, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8))); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10, 18); - } - - @Test - public void unix_without_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\nbar\nbaz", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(3); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11); - assertThat(metadata.isEmpty()).isFalse(); - } - - @Test - public void unix_with_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\nbar\nbaz\n", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8, 12); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11, 12); - } - - @Test - public void mac_without_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\rbar\rbaz", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(3); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11); - } - - @Test - public void mac_with_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\rbar\rbaz\r", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8, 12); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11, 12); - } - - @Test - public void mix_of_newlines_with_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 9, 13); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 12, 13); - } - - @Test - public void several_new_lines() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\n\n\nbar", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(2); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\n\n\nbar")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 5, 6); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 4, 5, 9); - } - - @Test - public void mix_of_newlines_without_latest_eol() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(3); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 9); - assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 12); - } - - @Test - public void start_with_newline() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "\nfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); - assertThat(metadata.lines()).isEqualTo(4); - assertThat(metadata.nonBlankLines()).isEqualTo(3); - assertThat(metadata.hash()).isEqualTo(md5Hex("\nfoo\nbar\nbaz")); - assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 1, 5, 10); - assertThat(metadata.originalLineEndOffsets()).containsOnly(0, 4, 8, 13); - } - - @Test - public void ignore_whitespace_when_computing_line_hashes() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, " foo\nb ar\r\nbaz \t", StandardCharsets.UTF_8, true); - - DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) - .setModuleBaseDir(tempFile.getParentFile().toPath()) - .setCharset(StandardCharsets.UTF_8) - .build(); - FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() { - - @Override - public void consume(int lineIdx, @Nullable byte[] hash) { - switch (lineIdx) { - case 1: - assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("foo")); - break; - case 2: - assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("bar")); - break; - case 3: - assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("baz")); - break; - default: - fail("Invalid line"); - } - } - }); - } - - @Test - public void dont_fail_on_empty_file() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "", StandardCharsets.UTF_8, true); - - DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) - .setModuleBaseDir(tempFile.getParentFile().toPath()) - .setCharset(StandardCharsets.UTF_8) - .build(); - FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() { - - @Override - public void consume(int lineIdx, @Nullable byte[] hash) { - switch (lineIdx) { - case 1: - assertThat(hash).isNull(); - break; - default: - fail("Invalid line"); - } - } - }); - } - - @Test - public void line_feed_is_included_into_hash() throws Exception { - File file1 = temp.newFile(); - FileUtils.write(file1, "foo\nbar\n", StandardCharsets.UTF_8, true); - - // same as file1, except an additional return carriage - File file1a = temp.newFile(); - FileUtils.write(file1a, "foo\r\nbar\n", StandardCharsets.UTF_8, true); - - File file2 = temp.newFile(); - FileUtils.write(file2, "foo\nbar", StandardCharsets.UTF_8, true); - - String hash1 = new FileMetadata().readMetadata(new FileInputStream(file1), StandardCharsets.UTF_8, file1.getName()).hash(); - String hash1a = new FileMetadata().readMetadata(new FileInputStream(file1a), StandardCharsets.UTF_8, file1a.getName()).hash(); - String hash2 = new FileMetadata().readMetadata(new FileInputStream(file2), StandardCharsets.UTF_8, file2.getName()).hash(); - - assertThat(hash1).isEqualTo(hash1a); - assertThat(hash1).isNotEqualTo(hash2); - } - - @Test - public void binary_file_with_unmappable_character() throws Exception { - File woff = new File(this.getClass().getResource("glyphicons-halflings-regular.woff").toURI()); - - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(woff), StandardCharsets.UTF_8, woff.getAbsolutePath()); - - assertThat(metadata.lines()).isEqualTo(135); - assertThat(metadata.nonBlankLines()).isEqualTo(133); - assertThat(metadata.hash()).isNotEmpty(); - - assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains("Invalid character encountered in file"); - assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains( - "glyphicons-halflings-regular.woff at line 1 for encoding UTF-8. Please fix file content or configure the encoding to be used using property 'sonar.sourceEncoding'."); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java deleted file mode 100644 index d0dc4c3ecc4..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import java.io.IOException; -import java.util.Collections; -import org.junit.Test; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class FilenamePredicateTest { - @Test - public void should_match_file_by_filename() throws IOException { - String filename = "some name"; - InputFile inputFile = mock(InputFile.class); - when(inputFile.filename()).thenReturn(filename); - - assertThat(new FilenamePredicate(filename).apply(inputFile)).isTrue(); - } - - @Test - public void should_not_match_file_by_different_filename() throws IOException { - String filename = "some name"; - InputFile inputFile = mock(InputFile.class); - when(inputFile.filename()).thenReturn(filename + "x"); - - assertThat(new FilenamePredicate(filename).apply(inputFile)).isFalse(); - } - - @Test - public void should_find_matching_file_in_index() throws IOException { - String filename = "some name"; - InputFile inputFile = mock(InputFile.class); - when(inputFile.filename()).thenReturn(filename); - - FileSystem.Index index = mock(FileSystem.Index.class); - when(index.getFilesByName(filename)).thenReturn(Collections.singleton(inputFile)); - - assertThat(new FilenamePredicate(filename).get(index)).containsOnly(inputFile); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/OrPredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/OrPredicateTest.java deleted file mode 100644 index 2592bee85ab..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/OrPredicateTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import org.junit.Test; -import org.sonar.api.batch.fs.FilePredicate; - -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThat; - -public class OrPredicateTest { - - @Test - public void flattenNestedOr() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); - FilePredicate orPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, - OrPredicate.create(Arrays.asList(pathPatternPredicate2, pathPatternPredicate3)))); - assertThat(((OrPredicate) orPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); - } - - @Test - public void simplifyOrExpressionsWhenEmpty() { - FilePredicate orPredicate = OrPredicate.create(Arrays.asList()); - assertThat(orPredicate).isEqualTo(TruePredicate.TRUE); - } - - @Test - public void simplifyOrExpressionsWhenFalse() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - FilePredicate andPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, - FalsePredicate.FALSE, pathPatternPredicate2)); - assertThat(((OrPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); - } - - @Test - public void simplifyAndExpressionsWhenTrue() { - PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); - PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); - FilePredicate andPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, - TruePredicate.TRUE, pathPatternPredicate2)); - assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/RelativePathPredicateTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/RelativePathPredicateTest.java deleted file mode 100644 index 50bcba8f2da..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/RelativePathPredicateTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal; - -import org.junit.Test; -import org.sonar.api.batch.fs.InputFile; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class RelativePathPredicateTest { - @Test - public void returns_false_when_path_is_invalid() { - RelativePathPredicate predicate = new RelativePathPredicate(".."); - InputFile inputFile = mock(InputFile.class); - when(inputFile.relativePath()).thenReturn("path"); - assertThat(predicate.apply(inputFile)).isFalse(); - } - - @Test - public void returns_true_if_matches() { - RelativePathPredicate predicate = new RelativePathPredicate("path"); - InputFile inputFile = mock(InputFile.class); - when(inputFile.relativePath()).thenReturn("path"); - assertThat(predicate.apply(inputFile)).isTrue(); - } - - @Test - public void returns_false_if_doesnt_match() { - RelativePathPredicate predicate = new RelativePathPredicate("path1"); - InputFile inputFile = mock(InputFile.class); - when(inputFile.relativePath()).thenReturn("path2"); - assertThat(predicate.apply(inputFile)).isFalse(); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java index 376536e6b7b..3055be6a419 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayListTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayListTest.java deleted file mode 100644 index 91d54fa1475..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayListTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs.internal.charhandler; - -import org.junit.Test; -import org.sonar.api.batch.fs.internal.charhandler.IntArrayList; - -import static org.assertj.core.api.Assertions.assertThat; - -public class IntArrayListTest { - - @Test - public void addElements() { - IntArrayList list = new IntArrayList(); - assertThat(list.trimAndGet()).isEmpty(); - list.add(1); - list.add(2); - assertThat(list.trimAndGet()).containsExactly(1, 2); - } - - @Test - public void trimIfNeeded() { - IntArrayList list = new IntArrayList(); - list.add(1); - list.add(2); - assertThat(list.trimAndGet()).isSameAs(list.trimAndGet()); - } - - @Test - public void grow() { - // Default capacity is 10 - IntArrayList list = new IntArrayList(); - for (int i = 1; i <= 11; i++) { - list.add(i); - } - assertThat(list.trimAndGet()).hasSize(11); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java index 60136eec67a..5a728e95faa 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java @@ -21,10 +21,10 @@ package org.sonar.api.batch.rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; -import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.SonarException; +import org.sonar.scanner.rule.ActiveRulesBuilder; +import org.sonar.scanner.rule.NewActiveRule; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java deleted file mode 100644 index f5abaf1667f..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.rule.ActiveRule; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.Severity; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ActiveRulesBuilderTest { - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void no_rules() { - ActiveRulesBuilder builder = new ActiveRulesBuilder(); - ActiveRules rules = builder.build(); - assertThat(rules.findAll()).isEmpty(); - } - - @Test - public void build_rules() { - NewActiveRule activeRule = new NewActiveRule.Builder() - .setRuleKey(RuleKey.of("squid", "S0001")) - .setName("My Rule") - .setSeverity(Severity.CRITICAL) - .setInternalKey("__S0001__") - .setParam("min", "20") - .build(); - - ActiveRules activeRules = new ActiveRulesBuilder() - .addRule(activeRule) - // most simple rule - .addRule(new NewActiveRule.Builder().setRuleKey(RuleKey.of("squid", "S0002")).build()) - .addRule(new NewActiveRule.Builder() - .setRuleKey(RuleKey.of("findbugs", "NPE")) - .setInternalKey(null) - .setSeverity(null) - .setParam("foo", null) - .build()) - .build(); - - assertThat(activeRules.findAll()).hasSize(3); - assertThat(activeRules.findByRepository("squid")).hasSize(2); - assertThat(activeRules.findByRepository("findbugs")).hasSize(1); - assertThat(activeRules.findByInternalKey("squid", "__S0001__")).isNotNull(); - assertThat(activeRules.findByRepository("unknown")).isEmpty(); - - ActiveRule squid1 = activeRules.find(RuleKey.of("squid", "S0001")); - assertThat(squid1.ruleKey().repository()).isEqualTo("squid"); - assertThat(squid1.ruleKey().rule()).isEqualTo("S0001"); - assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL); - assertThat(squid1.internalKey()).isEqualTo("__S0001__"); - assertThat(squid1.params()).hasSize(1); - assertThat(squid1.param("min")).isEqualTo("20"); - - ActiveRule squid2 = activeRules.find(RuleKey.of("squid", "S0002")); - assertThat(squid2.ruleKey().repository()).isEqualTo("squid"); - assertThat(squid2.ruleKey().rule()).isEqualTo("S0002"); - assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity()); - assertThat(squid2.params()).isEmpty(); - - ActiveRule findbugsRule = activeRules.find(RuleKey.of("findbugs", "NPE")); - assertThat(findbugsRule.severity()).isEqualTo(Severity.defaultSeverity()); - assertThat(findbugsRule.internalKey()).isNull(); - assertThat(findbugsRule.params()).isEmpty(); - } - - @Test - public void fail_to_add_twice_the_same_rule() { - ActiveRulesBuilder builder = new ActiveRulesBuilder(); - NewActiveRule rule = new NewActiveRule.Builder() - .setRuleKey(RuleKey.of("squid", "S0001")) - .build(); - builder.addRule(rule); - - thrown.expect(IllegalStateException.class); - thrown.expectMessage("Rule 'squid:S0001' is already activated"); - - builder.addRule(rule); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/DefaultRulesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/DefaultRulesTest.java deleted file mode 100644 index 8ca9b7d2f80..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/DefaultRulesTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import org.sonar.api.rule.RuleKey; -import org.junit.Test; - -import java.util.LinkedList; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultRulesTest { - @Test - public void testRepeatedInternalKey() { - List newRules = new LinkedList<>(); - newRules.add(createRule("key1", "repo", "internal")); - newRules.add(createRule("key2", "repo", "internal")); - - DefaultRules rules = new DefaultRules(newRules); - assertThat(rules.findByInternalKey("repo", "internal")).hasSize(2); - assertThat(rules.find(RuleKey.of("repo", "key1"))).isNotNull(); - assertThat(rules.find(RuleKey.of("repo", "key2"))).isNotNull(); - assertThat(rules.findByRepository("repo")).hasSize(2); - } - - @Test - public void testNonExistingKey() { - List newRules = new LinkedList<>(); - newRules.add(createRule("key1", "repo", "internal")); - newRules.add(createRule("key2", "repo", "internal")); - - DefaultRules rules = new DefaultRules(newRules); - assertThat(rules.findByInternalKey("xx", "xx")).hasSize(0); - assertThat(rules.find(RuleKey.of("xxx", "xx"))).isNull(); - assertThat(rules.findByRepository("xxxx")).hasSize(0); - } - - @Test - public void testRepeatedRule() { - List newRules = new LinkedList<>(); - newRules.add(createRule("key", "repo", "internal")); - newRules.add(createRule("key", "repo", "internal")); - - DefaultRules rules = new DefaultRules(newRules); - assertThat(rules.find(RuleKey.of("repo", "key"))).isNotNull(); - } - - private NewRule createRule(String key, String repo, String internalKey) { - RuleKey ruleKey = RuleKey.of(repo, key); - NewRule newRule = new NewRule(ruleKey); - newRule.setInternalKey(internalKey); - - return newRule; - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java deleted file mode 100644 index 324b191df0a..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import com.google.common.collect.ImmutableMap; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.Severity; - -import static org.assertj.core.api.Assertions.assertThat; - -public class NewActiveRuleTest { - - private NewActiveRule.Builder builder; - - @Before - public void setBuilder() { - builder = new NewActiveRule.Builder(); - } - - @Test - public void builder_should_set_every_param() { - NewActiveRule rule = builder - .setRuleKey(RuleKey.of("foo", "bar")) - .setName("name") - .setSeverity(Severity.CRITICAL) - .setParam("key", "value") - .setCreatedAt(1_000L) - .setUpdatedAt(1_000L) - .setInternalKey("internal_key") - .setLanguage("language") - .setTemplateRuleKey("templateRuleKey") - .setQProfileKey("qProfileKey") - .build(); - - assertThat(rule.ruleKey).isEqualTo(RuleKey.of("foo", "bar")); - assertThat(rule.name).isEqualTo("name"); - assertThat(rule.severity).isEqualTo(Severity.CRITICAL); - assertThat(rule.params).isEqualTo(ImmutableMap.of("key", "value")); - assertThat(rule.createdAt).isEqualTo(1_000L); - assertThat(rule.updatedAt).isEqualTo(1_000L); - assertThat(rule.internalKey).isEqualTo("internal_key"); - assertThat(rule.language).isEqualTo("language"); - assertThat(rule.templateRuleKey).isEqualTo("templateRuleKey"); - assertThat(rule.qProfileKey).isEqualTo("qProfileKey"); - } - - @Test - public void severity_should_have_default_value() { - NewActiveRule rule = builder.build(); - assertThat(rule.severity).isEqualTo(Severity.defaultSeverity()); - } - - @Test - public void params_should_be_empty_map_if_no_params() { - NewActiveRule rule = builder.build(); - assertThat(rule.params).isEqualTo(ImmutableMap.of()); - } - - @Test - public void set_param_remove_param_if_value_is_null() { - NewActiveRule rule = builder - .setParam("foo", "bar") - .setParam("removed", "value") - .setParam("removed", null) - .build(); - assertThat(rule.params).isEqualTo(ImmutableMap.of("foo", "bar")); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java deleted file mode 100644 index 9473b04eb27..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.rule.Rule; -import org.sonar.api.batch.rule.Rules; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rule.Severity; - -import static org.assertj.core.api.Assertions.assertThat; - -public class RulesBuilderTest { - @org.junit.Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void no_rules() { - RulesBuilder builder = new RulesBuilder(); - Rules rules = builder.build(); - assertThat(rules.findAll()).isEmpty(); - } - - @Test - public void build_rules() { - RulesBuilder builder = new RulesBuilder(); - NewRule newSquid1 = builder.add(RuleKey.of("squid", "S0001")); - newSquid1.setName("Detect bug"); - newSquid1.setDescription("Detect potential bug"); - newSquid1.setInternalKey("foo=bar"); - newSquid1.setSeverity(Severity.CRITICAL); - newSquid1.setStatus(RuleStatus.BETA); - newSquid1.addParam("min"); - newSquid1.addParam("max").setDescription("Maximum"); - // most simple rule - builder.add(RuleKey.of("squid", "S0002")); - builder.add(RuleKey.of("findbugs", "NPE")); - - Rules rules = builder.build(); - - assertThat(rules.findAll()).hasSize(3); - assertThat(rules.findByRepository("squid")).hasSize(2); - assertThat(rules.findByRepository("findbugs")).hasSize(1); - assertThat(rules.findByRepository("unknown")).isEmpty(); - - Rule squid1 = rules.find(RuleKey.of("squid", "S0001")); - assertThat(squid1.key().repository()).isEqualTo("squid"); - assertThat(squid1.key().rule()).isEqualTo("S0001"); - assertThat(squid1.name()).isEqualTo("Detect bug"); - assertThat(squid1.description()).isEqualTo("Detect potential bug"); - assertThat(squid1.internalKey()).isEqualTo("foo=bar"); - assertThat(squid1.status()).isEqualTo(RuleStatus.BETA); - assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL); - assertThat(squid1.params()).hasSize(2); - assertThat(squid1.param("min").key()).isEqualTo("min"); - assertThat(squid1.param("min").description()).isNull(); - assertThat(squid1.param("max").key()).isEqualTo("max"); - assertThat(squid1.param("max").description()).isEqualTo("Maximum"); - - Rule squid2 = rules.find(RuleKey.of("squid", "S0002")); - assertThat(squid2.key().repository()).isEqualTo("squid"); - assertThat(squid2.key().rule()).isEqualTo("S0002"); - assertThat(squid2.description()).isNull(); - assertThat(squid2.internalKey()).isNull(); - assertThat(squid2.status()).isEqualTo(RuleStatus.defaultStatus()); - assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity()); - assertThat(squid2.params()).isEmpty(); - } - - @Test - public void fail_to_add_twice_the_same_rule() { - RulesBuilder builder = new RulesBuilder(); - builder.add(RuleKey.of("squid", "S0001")); - - thrown.expect(IllegalStateException.class); - thrown.expectMessage("Rule 'squid:S0001' already exists"); - - builder.add(RuleKey.of("squid", "S0001")); - } - - @Test - public void fail_to_add_twice_the_same_param() { - RulesBuilder builder = new RulesBuilder(); - NewRule newRule = builder.add(RuleKey.of("squid", "S0001")); - newRule.addParam("min"); - newRule.addParam("max"); - - thrown.expect(IllegalStateException.class); - thrown.expectMessage("Parameter 'min' already exists on rule 'squid:S0001'"); - - newRule.addParam("min"); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java index e23ccc355ff..5d853e456ea 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java @@ -23,8 +23,9 @@ 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.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java index 8320cea7544..1adb0c71e54 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java @@ -22,8 +22,8 @@ package org.sonar.api.batch.sensor.cpd.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.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java index 2e5e5104489..ae920c967fe 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java @@ -30,9 +30,10 @@ 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.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; + import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java deleted file mode 100644 index 42cc0e4eb07..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.highlighting.internal; - -import java.util.Collection; -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.TextRange; -import org.sonar.api.batch.fs.internal.DefaultTextPointer; -import org.sonar.api.batch.fs.internal.DefaultTextRange; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorStorage; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.sonar.api.batch.sensor.highlighting.TypeOfText.COMMENT; -import static org.sonar.api.batch.sensor.highlighting.TypeOfText.CPP_DOC; -import static org.sonar.api.batch.sensor.highlighting.TypeOfText.KEYWORD; - -public class DefaultHighlightingTest { - - private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") - .setLines(2) - .setOriginalLineStartOffsets(new int[] {0, 50}) - .setOriginalLineEndOffsets(new int[] {49, 100}) - .setLastValidOffset(101) - .build(); - - private Collection highlightingRules; - - @Rule - public ExpectedException throwable = ExpectedException.none(); - - @Before - public void setUpSampleRules() { - - DefaultHighlighting highlightingDataBuilder = new DefaultHighlighting(mock(SensorStorage.class)) - .onFile(INPUT_FILE) - .highlight(0, 10, COMMENT) - .highlight(1, 10, 1, 12, KEYWORD) - .highlight(24, 38, KEYWORD) - .highlight(42, 50, KEYWORD) - .highlight(24, 65, CPP_DOC) - .highlight(12, 20, COMMENT); - - highlightingDataBuilder.save(); - - highlightingRules = highlightingDataBuilder.getSyntaxHighlightingRuleSet(); - } - - @Test - public void should_register_highlighting_rule() { - assertThat(highlightingRules).hasSize(6); - } - - private static TextRange rangeOf(int startLine, int startOffset, int endLine, int endOffset) { - return new DefaultTextRange(new DefaultTextPointer(startLine, startOffset), new DefaultTextPointer(endLine, endOffset)); - } - - @Test - public void should_order_by_start_then_end_offset() { - assertThat(highlightingRules).extracting("range", TextRange.class).containsExactly( - rangeOf(1, 0, 1, 10), - rangeOf(1, 10, 1, 12), - rangeOf(1, 12, 1, 20), - rangeOf(1, 24, 2, 15), - rangeOf(1, 24, 1, 38), - rangeOf(1, 42, 2, 0)); - assertThat(highlightingRules).extracting("textType").containsExactly(COMMENT, KEYWORD, COMMENT, CPP_DOC, KEYWORD, KEYWORD); - } - - @Test - public void should_support_overlapping() { - new DefaultHighlighting(mock(SensorStorage.class)) - .onFile(INPUT_FILE) - .highlight(0, 15, KEYWORD) - .highlight(8, 12, CPP_DOC) - .save(); - } - - @Test - public void should_prevent_start_equal_end() { - throwable.expect(IllegalArgumentException.class); - throwable - .expectMessage("Unable to highlight file"); - - new DefaultHighlighting(mock(SensorStorage.class)) - .onFile(INPUT_FILE) - .highlight(10, 10, KEYWORD) - .save(); - } - - @Test - public void should_prevent_boudaries_overlapping() { - throwable.expect(IllegalStateException.class); - throwable - .expectMessage("Cannot register highlighting rule for characters at Range[from [line=1, lineOffset=8] to [line=1, lineOffset=15]] as it overlaps at least one existing rule"); - - new DefaultHighlighting(mock(SensorStorage.class)) - .onFile(INPUT_FILE) - .highlight(0, 10, KEYWORD) - .highlight(8, 15, KEYWORD) - .save(); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java deleted file mode 100644 index 25a1088e049..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.internal; - -import org.junit.Test; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.config.internal.MapSettings; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DefaultSensorDescriptorTest { - - @Test - public void describe() { - DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor(); - descriptor - .name("Foo") - .onlyOnLanguage("java") - .onlyOnFileType(InputFile.Type.MAIN) - .requireProperty("sonar.foo.reportPath", "sonar.foo.reportPath2") - .createIssuesForRuleRepository("squid-java"); - - assertThat(descriptor.name()).isEqualTo("Foo"); - assertThat(descriptor.languages()).containsOnly("java"); - assertThat(descriptor.type()).isEqualTo(InputFile.Type.MAIN); - MapSettings settings = new MapSettings(); - settings.setProperty("sonar.foo.reportPath", "foo"); - assertThat(descriptor.configurationPredicate().test(settings.asConfig())).isFalse(); - settings.setProperty("sonar.foo.reportPath2", "foo"); - assertThat(descriptor.configurationPredicate().test(settings.asConfig())).isTrue(); - assertThat(descriptor.ruleRepositories()).containsOnly("squid-java"); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java deleted file mode 100644 index fe3ce4153cd..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.internal; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.data.MapEntry.entry; - -public class InMemorySensorStorageTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - InMemorySensorStorage underTest = new InMemorySensorStorage(); - - @Test - public void test_storeProperty() { - assertThat(underTest.contextProperties).isEmpty(); - - underTest.storeProperty("foo", "bar"); - assertThat(underTest.contextProperties).containsOnly(entry("foo", "bar")); - } - - @Test - public void storeProperty_throws_IAE_if_key_is_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Key of context property must not be null"); - - underTest.storeProperty(null, "bar"); - } - - @Test - public void storeProperty_throws_IAE_if_value_is_null() { - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Value of context property must not be null"); - - underTest.storeProperty("foo", null); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java deleted file mode 100644 index 493d7133cfd..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java +++ /dev/null @@ -1,375 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.internal; - -import java.io.File; -import java.io.IOException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -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.TestInputFileBuilder; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; -import org.sonar.api.batch.rule.internal.NewActiveRule; -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.NewExternalIssue; -import org.sonar.api.batch.sensor.issue.NewIssue; -import org.sonar.api.batch.sensor.symbol.NewSymbolTable; -import org.sonar.api.config.Settings; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; -import static org.assertj.core.data.MapEntry.entry; - -public class SensorContextTesterTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Rule - public ExpectedException exception = ExpectedException.none(); - - private SensorContextTester tester; - private File baseDir; - - @Before - public void prepare() throws Exception { - baseDir = temp.newFolder(); - tester = SensorContextTester.create(baseDir); - } - - @Test - public void testSettings() { - Settings settings = new MapSettings(); - settings.setProperty("foo", "bar"); - tester.setSettings(settings); - assertThat(tester.settings().getString("foo")).isEqualTo("bar"); - } - - @Test - public void testActiveRules() { - NewActiveRule activeRule = new NewActiveRule.Builder() - .setRuleKey(RuleKey.of("foo", "bar")) - .build(); - ActiveRules activeRules = new ActiveRulesBuilder().addRule(activeRule).build(); - tester.setActiveRules(activeRules); - assertThat(tester.activeRules().findAll()).hasSize(1); - } - - @Test - public void testFs() throws Exception { - DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); - tester.setFileSystem(fs); - assertThat(tester.fileSystem().baseDir()).isNotEqualTo(baseDir); - } - - @Test - public void testIssues() { - assertThat(tester.allIssues()).isEmpty(); - NewIssue newIssue = tester.newIssue(); - newIssue - .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) - .forRule(RuleKey.of("repo", "rule")) - .save(); - newIssue = tester.newIssue(); - newIssue - .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) - .forRule(RuleKey.of("repo", "rule")) - .save(); - assertThat(tester.allIssues()).hasSize(2); - } - - @Test - public void testExternalIssues() { - assertThat(tester.allExternalIssues()).isEmpty(); - NewExternalIssue newExternalIssue = tester.newExternalIssue(); - newExternalIssue - .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build())) - .forRule(RuleKey.of("repo", "rule")) - .type(RuleType.BUG) - .severity(Severity.BLOCKER) - .save(); - newExternalIssue = tester.newExternalIssue(); - newExternalIssue - .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build())) - .type(RuleType.BUG) - .severity(Severity.BLOCKER) - .forRule(RuleKey.of("repo", "rule")) - .save(); - assertThat(tester.allExternalIssues()).hasSize(2); - } - - @Test - public void testAnalysisErrors() { - assertThat(tester.allAnalysisErrors()).isEmpty(); - NewAnalysisError newAnalysisError = tester.newAnalysisError(); - - InputFile file = new TestInputFileBuilder("foo", "src/Foo.java").build(); - 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() throws IOException { - assertThat(tester.measures("foo:src/Foo.java")).isEmpty(); - assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull(); - tester.newMeasure() - .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) - .forMetric(CoreMetrics.NCLOC) - .withValue(2) - .save(); - assertThat(tester.measures("foo:src/Foo.java")).hasSize(1); - assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); - tester.newMeasure() - .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) - .forMetric(CoreMetrics.LINES) - .withValue(4) - .save(); - assertThat(tester.measures("foo:src/Foo.java")).hasSize(2); - assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); - assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull(); - tester.newMeasure() - .on(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))) - .forMetric(CoreMetrics.DIRECTORIES) - .withValue(4) - .save(); - assertThat(tester.measures("foo")).hasSize(1); - assertThat(tester.measure("foo", "directories")).isNotNull(); - } - - @Test(expected = IllegalStateException.class) - public void duplicateMeasures() { - tester.newMeasure() - .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) - .forMetric(CoreMetrics.NCLOC) - .withValue(2) - .save(); - tester.newMeasure() - .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) - .forMetric(CoreMetrics.NCLOC) - .withValue(2) - .save(); - } - - @Test - public void testHighlighting() { - assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).isEmpty(); - tester.newHighlighting() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) - .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) - .highlight(8, 10, TypeOfText.CONSTANT) - .highlight(9, 10, TypeOfText.COMMENT) - .save(); - assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).containsExactly(TypeOfText.ANNOTATION); - assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT); - } - - @Test(expected = UnsupportedOperationException.class) - public void duplicateHighlighting() { - tester.newHighlighting() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) - .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) - .save(); - tester.newHighlighting() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) - .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) - .save(); - } - - @Test - public void testSymbolReferences() { - assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull(); - - NewSymbolTable symbolTable = tester.newSymbolTable() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); - symbolTable - .newSymbol(1, 8, 1, 10); - - symbolTable - .newSymbol(1, 1, 1, 5) - .newReference(6, 9) - .newReference(1, 10, 1, 13); - - symbolTable.save(); - - assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull(); - assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 8)).isEmpty(); - assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 3)).extracting("start.line", "start.lineOffset", "end.line", "end.lineOffset").containsExactly(tuple(1, 6, 1, 9), - tuple(1, 10, 1, 13)); - } - - @Test(expected = UnsupportedOperationException.class) - public void duplicateSymbolReferences() { - NewSymbolTable symbolTable = tester.newSymbolTable() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); - symbolTable - .newSymbol(1, 8, 1, 10); - - symbolTable.save(); - - symbolTable = tester.newSymbolTable() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); - symbolTable - .newSymbol(1, 8, 1, 10); - - symbolTable.save(); - } - - @Test - public void testCoverageAtLineZero() { - assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); - - exception.expect(IllegalStateException.class); - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) - .lineHits(0, 3); - } - - @Test - public void testCoverageAtLineOutOfRange() { - assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); - exception.expect(IllegalStateException.class); - - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) - .lineHits(4, 3); - } - - @Test - public void testLineHits() { - assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); - assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) - .lineHits(1, 2) - .lineHits(2, 3) - .save(); - assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(2); - assertThat(tester.lineHits("foo:src/Foo.java", 2)).isEqualTo(3); - } - - public void multipleCoverage() { - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) - .lineHits(1, 2) - .conditions(3, 4, 2) - .save(); - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) - .lineHits(1, 2) - .conditions(3, 4, 3) - .save(); - assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(4); - assertThat(tester.conditions("foo:src/Foo.java", 3)).isEqualTo(4); - assertThat(tester.coveredConditions("foo:src/Foo.java", 3)).isEqualTo(3); - } - - @Test - public void testConditions() { - assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull(); - assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull(); - tester.newCoverage() - .onFile(new TestInputFileBuilder("foo", "src/Foo.java") - .initMetadata("annot dsf fds foo bar\nasd\nasdas\nasdfas") - .build()) - .conditions(1, 4, 2) - .save(); - assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4); - assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isEqualTo(2); - } - - @Test - public void testCpdTokens() { - assertThat(tester.cpdTokens("foo:src/Foo.java")).isNull(); - DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") - .initMetadata("public class Foo {\n\n}") - .build(); - tester.newCpdTokens() - .onFile(inputFile) - .addToken(inputFile.newRange(0, 6), "public") - .addToken(inputFile.newRange(7, 12), "class") - .addToken(inputFile.newRange(13, 16), "$IDENTIFIER") - .addToken(inputFile.newRange(17, 18), "{") - .addToken(inputFile.newRange(3, 0, 3, 1), "}") - .save(); - assertThat(tester.cpdTokens("foo:src/Foo.java")).extracting("value", "startLine", "startUnit", "endUnit") - .containsExactly( - tuple("publicclass$IDENTIFIER{", 1, 1, 4), - tuple("}", 3, 5, 5)); - } - - @Test(expected = UnsupportedOperationException.class) - public void duplicateCpdTokens() { - DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") - .initMetadata("public class Foo {\n\n}") - .build(); - tester.newCpdTokens() - .onFile(inputFile) - .addToken(inputFile.newRange(0, 6), "public") - .save(); - - tester.newCpdTokens() - .onFile(inputFile) - .addToken(inputFile.newRange(0, 6), "public") - .save(); - } - - @Test - public void testCancellation() { - assertThat(tester.isCancelled()).isFalse(); - tester.setCancelled(true); - assertThat(tester.isCancelled()).isTrue(); - } - - @Test - public void testContextProperties() { - assertThat(tester.getContextProperties()).isEmpty(); - - tester.addContextProperty("foo", "bar"); - assertThat(tester.getContextProperties()).containsOnly(entry("foo", "bar")); - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java deleted file mode 100644 index a2d07c75b20..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.issue.internal; - -import java.io.IOException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.RuleType; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class DefaultExternalIssueTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private DefaultInputProject project; - - @Before - public void setup() throws IOException { - project = new DefaultInputProject(ProjectDefinition.create() - .setKey("foo") - .setBaseDir(temp.newFolder()) - .setWorkDir(temp.newFolder())); - } - - @Rule - public ExpectedException exception = ExpectedException.none(); - - private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") - .initMetadata("Foo\nBar\n") - .build(); - - @Test - public void build_file_issue() { - SensorStorage storage = mock(SensorStorage.class); - DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputFile) - .at(inputFile.selectLine(1)) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .remediationEffortMinutes(10l) - .type(RuleType.BUG) - .severity(Severity.BLOCKER); - - assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_repo", "rule")); - assertThat(issue.engineId()).isEqualTo("repo"); - assertThat(issue.ruleId()).isEqualTo("rule"); - assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); - assertThat(issue.remediationEffort()).isEqualTo(10l); - assertThat(issue.type()).isEqualTo(RuleType.BUG); - assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); - assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); - - issue.save(); - - verify(storage).store(issue); - } - - @Test - public void fail_to_store_if_no_type() { - SensorStorage storage = mock(SensorStorage.class); - DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputFile) - .at(inputFile.selectLine(1)) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .remediationEffortMinutes(10l) - .severity(Severity.BLOCKER); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Type is mandatory"); - issue.save(); - } - - @Test - public void fail_to_store_if_primary_location_is_not_a_file() { - SensorStorage storage = mock(SensorStorage.class); - DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) - .at(new DefaultIssueLocation() - .on(mock(InputComponent.class)) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .remediationEffortMinutes(10l) - .severity(Severity.BLOCKER); - - exception.expect(IllegalStateException.class); - exception.expectMessage("External issues must be located in files"); - issue.save(); - } - - @Test - public void fail_to_store_if_primary_location_has_no_message() { - SensorStorage storage = mock(SensorStorage.class); - DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputFile) - .at(inputFile.selectLine(1))) - .forRule(RuleKey.of("repo", "rule")) - .remediationEffortMinutes(10l) - .type(RuleType.BUG) - .severity(Severity.BLOCKER); - - exception.expect(IllegalStateException.class); - exception.expectMessage("External issues must have a message"); - issue.save(); - } - - @Test - public void fail_to_store_if_no_severity() { - SensorStorage storage = mock(SensorStorage.class); - DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputFile) - .at(inputFile.selectLine(1)) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .remediationEffortMinutes(10l) - .type(RuleType.BUG); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Severity is mandatory"); - issue.save(); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java deleted file mode 100644 index 66b5369391a..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.issue.internal; - -import org.apache.commons.lang.StringUtils; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeMatcher; -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.TestInputFileBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.rules.ExpectedException.none; - -public class DefaultIssueLocationTest { - - @Rule - public ExpectedException thrown = none(); - - private InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") - .initMetadata("Foo\nBar\n") - .build(); - - @Test - public void should_build() { - assertThat(new DefaultIssueLocation() - .on(inputFile) - .message("pipo bimbo") - .message() - ).isEqualTo("pipo bimbo"); - } - - @Test - public void not_allowed_to_call_on_twice() { - thrown.expect(IllegalStateException.class); - thrown.expectMessage("on() already called"); - new DefaultIssueLocation() - .on(inputFile) - .on(inputFile) - .message("Wrong way!"); - } - - @Test - public void prevent_too_long_messages() { - assertThat(new DefaultIssueLocation() - .on(inputFile) - .message(StringUtils.repeat("a", 4000)).message()).hasSize(4000); - - assertThat(new DefaultIssueLocation() - .on(inputFile) - .message(StringUtils.repeat("a", 4001)).message()).hasSize(4000); - } - - @Test - public void prevent_null_character_in_message_text() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Character \\u0000 is not supported in issue message"); - - new DefaultIssueLocation() - .message("pipo " + '\u0000' + " bimbo"); - } - - @Test - public void prevent_null_character_in_message_text_when_builder_has_been_initialized() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage(customMatcher("Character \\u0000 is not supported in issue message", ", on component: src/Foo.php")); - - new DefaultIssueLocation() - .on(inputFile) - .message("pipo " + '\u0000' + " bimbo"); - } - - private Matcher customMatcher(String startWith, String endWith) { - return new TypeSafeMatcher() { - @Override - public void describeTo(Description description) { - description.appendText("Invalid message"); - } - - @Override - protected boolean matchesSafely(final String item) { - return item.startsWith(startWith) && item.endsWith(endWith); - } - }; - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java deleted file mode 100644 index 9fc65984432..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.issue.internal; - -import java.io.File; -import java.io.IOException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.rule.RuleKey; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class DefaultIssueTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private DefaultInputProject project; - - private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") - .initMetadata("Foo\nBar\n") - .build(); - - @Before - public void prepare() throws IOException { - project = new DefaultInputProject(ProjectDefinition.create() - .setKey("foo") - .setBaseDir(temp.newFolder()) - .setWorkDir(temp.newFolder())); - } - - @Test - public void build_file_issue() { - SensorStorage storage = mock(SensorStorage.class); - DefaultIssue issue = new DefaultIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputFile) - .at(inputFile.selectLine(1)) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .gap(10.0); - - assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); - assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); - assertThat(issue.gap()).isEqualTo(10.0); - assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); - - issue.save(); - - verify(storage).store(issue); - } - - @Test - public void move_directory_issue_to_project_root() { - SensorStorage storage = mock(SensorStorage.class); - DefaultIssue issue = new DefaultIssue(project, storage) - .at(new DefaultIssueLocation() - .on(new DefaultInputDir("foo", "src/main").setModuleBaseDir(project.getBaseDir())) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .overrideSeverity(Severity.BLOCKER); - - assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); - assertThat(issue.primaryLocation().textRange()).isNull(); - assertThat(issue.primaryLocation().message()).isEqualTo("[src/main] Wrong way!"); - assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); - - issue.save(); - - verify(storage).store(issue); - } - - @Test - public void move_submodule_issue_to_project_root() { - File subModuleDirectory = new File(project.getBaseDir().toString(), "bar"); - subModuleDirectory.mkdir(); - - ProjectDefinition subModuleDefinition = ProjectDefinition.create() - .setKey("foo/bar") - .setBaseDir(subModuleDirectory) - .setWorkDir(subModuleDirectory); - project.definition().addSubProject(subModuleDefinition); - DefaultInputModule subModule = new DefaultInputModule(subModuleDefinition); - - SensorStorage storage = mock(SensorStorage.class); - DefaultIssue issue = new DefaultIssue(project, storage) - .at(new DefaultIssueLocation() - .on(subModule) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .overrideSeverity(Severity.BLOCKER); - - assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); - assertThat(issue.primaryLocation().textRange()).isNull(); - assertThat(issue.primaryLocation().message()).isEqualTo("[bar] Wrong way!"); - assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); - - issue.save(); - - verify(storage).store(issue); - } - - @Test - public void build_project_issue() throws IOException { - SensorStorage storage = mock(SensorStorage.class); - DefaultInputModule inputModule = new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); - DefaultIssue issue = new DefaultIssue(project, storage) - .at(new DefaultIssueLocation() - .on(inputModule) - .message("Wrong way!")) - .forRule(RuleKey.of("repo", "rule")) - .gap(10.0); - - assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputModule); - assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); - assertThat(issue.primaryLocation().textRange()).isNull(); - assertThat(issue.gap()).isEqualTo(10.0); - assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); - - issue.save(); - - verify(storage).store(issue); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java deleted file mode 100644 index f6133e9fd6d..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.measure.internal; - -import java.io.IOException; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.measures.CoreMetrics; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class DefaultMeasureTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void build_file_measure() { - SensorStorage storage = mock(SensorStorage.class); - DefaultMeasure newMeasure = new DefaultMeasure(storage) - .forMetric(CoreMetrics.LINES) - .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) - .withValue(3); - - assertThat(newMeasure.inputComponent()).isEqualTo(new TestInputFileBuilder("foo", "src/Foo.php").build()); - assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES); - assertThat(newMeasure.value()).isEqualTo(3); - - newMeasure.save(); - - verify(storage).store(newMeasure); - } - - @Test - public void build_project_measure() throws IOException { - SensorStorage storage = mock(SensorStorage.class); - AbstractProjectOrModule module = new DefaultInputProject(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); - DefaultMeasure newMeasure = new DefaultMeasure(storage) - .forMetric(CoreMetrics.LINES) - .on(module) - .withValue(3); - - assertThat(newMeasure.inputComponent()).isEqualTo(module); - assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES); - assertThat(newMeasure.value()).isEqualTo(3); - - newMeasure.save(); - - verify(storage).store(newMeasure); - } - - @Test - public void not_allowed_to_call_on_twice() throws IOException { - thrown.expect(IllegalStateException.class); - thrown.expectMessage("on() already called"); - new DefaultMeasure() - .on(new DefaultInputProject(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))) - .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) - .withValue(3) - .save(); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRuleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRuleTest.java deleted file mode 100644 index 332542f3fb4..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRuleTest.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.rule.internal; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.SensorStorage; -import org.sonar.api.batch.sensor.rule.NewAdHocRule; -import org.sonar.api.rules.RuleType; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class DefaultAdHocRuleTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void store() { - SensorStorage storage = mock(SensorStorage.class); - DefaultAdHocRule rule = new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId("ruleId") - .name("name") - .description("desc") - .severity(Severity.BLOCKER) - .type(RuleType.CODE_SMELL); - rule.save(); - - assertThat(rule.engineId()).isEqualTo("engine"); - assertThat(rule.ruleId()).isEqualTo("ruleId"); - assertThat(rule.name()).isEqualTo("name"); - assertThat(rule.description()).isEqualTo("desc"); - assertThat(rule.severity()).isEqualTo(Severity.BLOCKER); - assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL); - - verify(storage).store(any(DefaultAdHocRule.class)); - } - - - @Test - public void description_is_optional() { - SensorStorage storage = mock(SensorStorage.class); - new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId("ruleId") - .name("name") - .severity(Severity.BLOCKER) - .type(RuleType.CODE_SMELL) - .save(); - - verify(storage).store(any(DefaultAdHocRule.class)); - } - - @Test - public void fail_to_store_if_no_engine_id() { - SensorStorage storage = mock(SensorStorage.class); - NewAdHocRule rule = new DefaultAdHocRule(storage) - .engineId(" ") - .ruleId("ruleId") - .name("name") - .description("desc") - .severity(Severity.BLOCKER) - .type(RuleType.CODE_SMELL); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Engine id is mandatory"); - rule.save(); - } - - @Test - public void fail_to_store_if_no_rule_id() { - SensorStorage storage = mock(SensorStorage.class); - NewAdHocRule rule = new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId(" ") - .name("name") - .description("desc") - .severity(Severity.BLOCKER) - .type(RuleType.CODE_SMELL); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Rule id is mandatory"); - rule.save(); - } - - @Test - public void fail_to_store_if_no_name() { - SensorStorage storage = mock(SensorStorage.class); - NewAdHocRule rule = new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId("ruleId") - .name(" ") - .description("desc") - .severity(Severity.BLOCKER) - .type(RuleType.CODE_SMELL); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Name is mandatory"); - rule.save(); - } - - - @Test - public void fail_to_store_if_no_severity() { - SensorStorage storage = mock(SensorStorage.class); - NewAdHocRule rule = new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId("ruleId") - .name("name") - .description("desc") - .type(RuleType.CODE_SMELL); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Severity is mandatory"); - rule.save(); - } - - @Test - public void fail_to_store_if_no_type() { - SensorStorage storage = mock(SensorStorage.class); - NewAdHocRule rule = new DefaultAdHocRule(storage) - .engineId("engine") - .ruleId("ruleId") - .name("name") - .description("desc") - .severity(Severity.BLOCKER); - - exception.expect(IllegalStateException.class); - exception.expectMessage("Type is mandatory"); - rule.save(); - } - -} \ No newline at end of file diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java index 8f98a84ecfe..c880f7f0bd9 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java @@ -27,8 +27,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java index b28f70876fd..76ac2f6758a 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java @@ -23,7 +23,7 @@ import java.util.Arrays; import java.util.HashSet; import org.junit.Test; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -32,10 +32,10 @@ public class NoSonarFilterTest { @Test public void should_store_nosonar_lines_on_inputfile() { DefaultInputFile f = TestInputFileBuilder.create("module1", "myfile.java").setLines(8).build(); - new NoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1,4))); + new NoSonarFilter().noSonarInFile(f, new HashSet<>(Arrays.asList(1, 4))); - assertThat(f.hasNoSonarAt(1)).isTrue(); - assertThat(f.hasNoSonarAt(2)).isFalse(); - assertThat(f.hasNoSonarAt(4)).isTrue(); + assertThat(f.hasNoSonarAt(1)).isTrue(); + assertThat(f.hasNoSonarAt(2)).isFalse(); + assertThat(f.hasNoSonarAt(4)).isTrue(); } } diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/batch/fs/internal/glyphicons-halflings-regular.woff b/sonar-plugin-api/src/test/resources/org/sonar/api/batch/fs/internal/glyphicons-halflings-regular.woff deleted file mode 100644 index 2cc3e4852a5..00000000000 Binary files a/sonar-plugin-api/src/test/resources/org/sonar/api/batch/fs/internal/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java index 9fc2d130f4a..d458edd0ca9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java @@ -34,6 +34,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.internal.DefaultInputComponent; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java index 1c1729634e1..de882ad0c54 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java @@ -37,6 +37,7 @@ import org.sonar.api.batch.fs.FilePredicates; 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.internal.DefaultInputDir; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.PathUtils; import org.sonar.scanner.fs.predicates.DefaultFilePredicates; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java deleted file mode 100644 index a3d060217e0..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.batch.fs.IndexedFile; -import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.utils.PathUtils; - -/** - * @since 6.3 - */ -@Immutable -public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile { - private final String projectRelativePath; - private final String moduleRelativePath; - private final String projectKey; - private final String language; - private final Type type; - private final Path absolutePath; - private final SensorStrategy sensorStrategy; - - /** - * Testing purposes only! - */ - public DefaultIndexedFile(String projectKey, Path baseDir, String relativePath, @Nullable String language) { - this(baseDir.resolve(relativePath), projectKey, relativePath, relativePath, Type.MAIN, language, TestInputFileBuilder.nextBatchId(), - new SensorStrategy()); - } - - public DefaultIndexedFile(Path absolutePath, String projectKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId, - SensorStrategy sensorStrategy) { - super(batchId); - this.projectKey = projectKey; - this.projectRelativePath = PathUtils.sanitize(projectRelativePath); - this.moduleRelativePath = PathUtils.sanitize(moduleRelativePath); - this.type = type; - this.language = language; - this.sensorStrategy = sensorStrategy; - this.absolutePath = absolutePath; - } - - @Override - public String relativePath() { - return sensorStrategy.isGlobal() ? projectRelativePath : moduleRelativePath; - } - - public String getModuleRelativePath() { - return moduleRelativePath; - } - - public String getProjectRelativePath() { - return projectRelativePath; - } - - @Override - public String absolutePath() { - return PathUtils.sanitize(path().toString()); - } - - @Override - public File file() { - return path().toFile(); - } - - @Override - public Path path() { - return absolutePath; - } - - @Override - public InputStream inputStream() throws IOException { - return Files.newInputStream(path()); - } - - @CheckForNull - @Override - public String language() { - return language; - } - - @Override - public Type type() { - return type; - } - - /** - * Component key (without branch). - */ - @Override - public String key() { - return new StringBuilder().append(projectKey).append(":").append(projectRelativePath).toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof DefaultIndexedFile)) { - return false; - } - - DefaultIndexedFile that = (DefaultIndexedFile) o; - return projectRelativePath.equals(that.projectRelativePath); - } - - @Override - public int hashCode() { - return projectRelativePath.hashCode(); - } - - @Override - public String toString() { - return projectRelativePath; - } - - @Override - public boolean isFile() { - return true; - } - - @Override - public String filename() { - return path().getFileName().toString(); - } - - @Override - public URI uri() { - return path().toUri(); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java deleted file mode 100644 index 11601e0265f..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs; - -import java.util.HashSet; -import java.util.Set; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.measure.Metric; - -/** - * @since 5.2 - */ -public abstract class DefaultInputComponent implements InputComponent { - private int id; - private Set storedMetricKeys = new HashSet<>(); - - public DefaultInputComponent(int scannerId) { - this.id = scannerId; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - DefaultInputComponent that = (DefaultInputComponent) o; - return key().equals(that.key()); - } - - public int scannerId() { - return id; - } - - @Override - public int hashCode() { - return key().hashCode(); - } - - @Override - public String toString() { - return "[key=" + key() + "]"; - } - - public void setHasMeasureFor(Metric metric) { - storedMetricKeys.add(metric.key()); - } - - public boolean hasMeasureFor(Metric metric) { - return storedMetricKeys.contains(metric.key()); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java deleted file mode 100644 index 13eb77be1c4..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs; - -import java.io.File; -import java.net.URI; -import java.nio.file.Path; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.fs.InputDir; -import org.sonar.api.utils.PathUtils; - -/** - * @since 4.5 - */ -public class DefaultInputDir extends DefaultInputComponent implements InputDir { - - private final String relativePath; - private final String moduleKey; - private Path moduleBaseDir; - - public DefaultInputDir(String moduleKey, String relativePath) { - super(-1); - this.moduleKey = moduleKey; - this.relativePath = PathUtils.sanitize(relativePath); - } - - @Override - public String relativePath() { - return relativePath; - } - - @Override - public String absolutePath() { - return PathUtils.sanitize(path().toString()); - } - - @Override - public File file() { - return path().toFile(); - } - - @Override - public Path path() { - if (moduleBaseDir == null) { - throw new IllegalStateException("Can not return the java.nio.file.Path because module baseDir is not set (see method setModuleBaseDir(java.io.File))"); - } - return moduleBaseDir.resolve(relativePath); - } - - public String moduleKey() { - return moduleKey; - } - - @Override - public String key() { - StringBuilder sb = new StringBuilder().append(moduleKey).append(":"); - if (StringUtils.isEmpty(relativePath)) { - sb.append("/"); - } else { - sb.append(relativePath); - } - return sb.toString(); - } - - /** - * For testing purpose. Will be automatically set when dir is added to {@link DefaultFileSystem} - */ - public DefaultInputDir setModuleBaseDir(Path moduleBaseDir) { - this.moduleBaseDir = moduleBaseDir.normalize(); - return this; - } - - @Override - public boolean isFile() { - return false; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - - DefaultInputDir that = (DefaultInputDir) o; - return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath); - } - - @Override - public int hashCode() { - return moduleKey.hashCode() + relativePath.hashCode() * 13; - } - - @Override - public String toString() { - return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]"; - } - - @Override - public URI uri() { - return path().toUri(); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java deleted file mode 100644 index f29f11db64a..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.apache.commons.io.ByteOrderMark; -import org.apache.commons.io.input.BOMInputStream; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.TextPointer; -import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.Metadata; - -import static org.sonar.api.utils.Preconditions.checkArgument; -import static org.sonar.api.utils.Preconditions.checkState; - -/** - * @since 4.2 - * To create {@link InputFile} in tests, use {@link TestInputFileBuilder}. - */ -public class DefaultInputFile extends DefaultInputComponent implements InputFile { - - private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; - - private final DefaultIndexedFile indexedFile; - private final String contents; - private final Consumer metadataGenerator; - - private boolean published; - private boolean excludedForCoverage; - private boolean excludedForDuplication; - private boolean ignoreAllIssues; - // Lazy init to save memory - private BitSet noSonarLines; - private Status status; - private Charset charset; - private Metadata metadata; - private Collection ignoreIssuesOnlineRanges; - private BitSet executableLines; - - public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator) { - this(indexedFile, metadataGenerator, null); - } - - // For testing - public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer metadataGenerator, @Nullable String contents) { - super(indexedFile.scannerId()); - this.indexedFile = indexedFile; - this.metadataGenerator = metadataGenerator; - this.metadata = null; - this.published = false; - this.excludedForCoverage = false; - this.contents = contents; - } - - public void checkMetadata() { - if (metadata == null) { - metadataGenerator.accept(this); - } - } - - @Override - public InputStream inputStream() throws IOException { - return contents != null ? new ByteArrayInputStream(contents.getBytes(charset())) - : new BOMInputStream(Files.newInputStream(path()), - ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE); - } - - @Override - public String contents() throws IOException { - if (contents != null) { - return contents; - } else { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - try (InputStream inputStream = inputStream()) { - byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - result.write(buffer, 0, length); - } - } - return result.toString(charset().name()); - } - } - - public DefaultInputFile setPublished(boolean published) { - this.published = published; - return this; - } - - public boolean isPublished() { - return published; - } - - public DefaultInputFile setExcludedForCoverage(boolean excludedForCoverage) { - this.excludedForCoverage = excludedForCoverage; - return this; - } - - public boolean isExcludedForCoverage() { - return excludedForCoverage; - } - - public DefaultInputFile setExcludedForDuplication(boolean excludedForDuplication) { - this.excludedForDuplication = excludedForDuplication; - return this; - } - - public boolean isExcludedForDuplication() { - return excludedForDuplication; - } - - /** - * @deprecated since 6.6 - */ - @Deprecated - @Override - public String relativePath() { - return indexedFile.relativePath(); - } - - public String getModuleRelativePath() { - return indexedFile.getModuleRelativePath(); - } - - public String getProjectRelativePath() { - return indexedFile.getProjectRelativePath(); - } - - @Override - public String absolutePath() { - return indexedFile.absolutePath(); - } - - @Override - public File file() { - return indexedFile.file(); - } - - @Override - public Path path() { - return indexedFile.path(); - } - - @CheckForNull - @Override - public String language() { - return indexedFile.language(); - } - - @Override - public Type type() { - return indexedFile.type(); - } - - /** - * Component key (without branch). - */ - @Override - public String key() { - return indexedFile.key(); - } - - @Override - public int hashCode() { - return indexedFile.hashCode(); - } - - @Override - public String toString() { - return indexedFile.toString(); - } - - /** - * {@link #setStatus(Status)} - */ - @Override - public Status status() { - checkMetadata(); - return status; - } - - @Override - public int lines() { - checkMetadata(); - return metadata.lines(); - } - - @Override - public boolean isEmpty() { - checkMetadata(); - return metadata.isEmpty(); - } - - @Override - public Charset charset() { - checkMetadata(); - return charset; - } - - public int lastValidOffset() { - checkMetadata(); - return metadata.lastValidOffset(); - } - - /** - * Digest hash of the file. - */ - public String hash() { - checkMetadata(); - return metadata.hash(); - } - - public int nonBlankLines() { - checkMetadata(); - return metadata.nonBlankLines(); - } - - public int[] originalLineStartOffsets() { - checkMetadata(); - checkState(metadata.originalLineStartOffsets() != null, "InputFile is not properly initialized."); - checkState(metadata.originalLineStartOffsets().length == metadata.lines(), - "InputFile is not properly initialized. 'originalLineStartOffsets' property length should be equal to 'lines'"); - return metadata.originalLineStartOffsets(); - } - - public int[] originalLineEndOffsets() { - checkMetadata(); - checkState(metadata.originalLineEndOffsets() != null, "InputFile is not properly initialized."); - checkState(metadata.originalLineEndOffsets().length == metadata.lines(), - "InputFile is not properly initialized. 'originalLineEndOffsets' property length should be equal to 'lines'"); - return metadata.originalLineEndOffsets(); - } - - @Override - public TextPointer newPointer(int line, int lineOffset) { - checkMetadata(); - DefaultTextPointer textPointer = new DefaultTextPointer(line, lineOffset); - checkValid(textPointer, "pointer"); - return textPointer; - } - - @Override - public TextRange newRange(TextPointer start, TextPointer end) { - checkMetadata(); - checkValid(start, "start pointer"); - checkValid(end, "end pointer"); - return newRangeValidPointers(start, end, false); - } - - @Override - public TextRange newRange(int startLine, int startLineOffset, int endLine, int endLineOffset) { - checkMetadata(); - TextPointer start = newPointer(startLine, startLineOffset); - TextPointer end = newPointer(endLine, endLineOffset); - return newRangeValidPointers(start, end, false); - } - - @Override - public TextRange selectLine(int line) { - checkMetadata(); - TextPointer startPointer = newPointer(line, 0); - TextPointer endPointer = newPointer(line, lineLength(line)); - return newRangeValidPointers(startPointer, endPointer, true); - } - - public void validate(TextRange range) { - checkMetadata(); - checkValid(range.start(), "start pointer"); - checkValid(range.end(), "end pointer"); - } - - /** - * Create Range from global offsets. Used for backward compatibility with older API. - */ - public TextRange newRange(int startOffset, int endOffset) { - checkMetadata(); - return newRangeValidPointers(newPointer(startOffset), newPointer(endOffset), false); - } - - public TextPointer newPointer(int globalOffset) { - checkMetadata(); - checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset); - checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset()); - int line = findLine(globalOffset); - int startLineOffset = originalLineStartOffsets()[line - 1]; - // In case the global offset is between \r and \n, move the pointer to a valid location - return new DefaultTextPointer(line, Math.min(globalOffset, originalLineEndOffsets()[line - 1]) - startLineOffset); - } - - public DefaultInputFile setStatus(Status status) { - this.status = status; - return this; - } - - public DefaultInputFile setCharset(Charset charset) { - this.charset = charset; - return this; - } - - private void checkValid(TextPointer pointer, String owner) { - checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line()); - checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines()); - checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset()); - int lineLength = lineLength(pointer.line()); - checkArgument(pointer.lineOffset() <= lineLength, - "%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line()); - } - - private int lineLength(int line) { - return originalLineEndOffsets()[line - 1] - originalLineStartOffsets()[line - 1]; - } - - private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) { - checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0), - "Start pointer %s should be before end pointer %s", start, end); - return new DefaultTextRange(start, end); - } - - private int findLine(int globalOffset) { - return Math.abs(Arrays.binarySearch(originalLineStartOffsets(), globalOffset) + 1); - } - - public DefaultInputFile setMetadata(Metadata metadata) { - this.metadata = metadata; - return this; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - - if (this.getClass() != obj.getClass()) { - return false; - } - - DefaultInputFile that = (DefaultInputFile) obj; - return this.getProjectRelativePath().equals(that.getProjectRelativePath()); - } - - @Override - public boolean isFile() { - return true; - } - - @Override - public String filename() { - return indexedFile.filename(); - } - - @Override - public URI uri() { - return indexedFile.uri(); - } - - public void noSonarAt(Set noSonarLines) { - if (this.noSonarLines == null) { - this.noSonarLines = new BitSet(lines()); - } - noSonarLines.forEach(l -> this.noSonarLines.set(l - 1)); - } - - public boolean hasNoSonarAt(int line) { - if (this.noSonarLines == null) { - return false; - } - return this.noSonarLines.get(line - 1); - } - - public boolean isIgnoreAllIssues() { - return ignoreAllIssues; - } - - public void setIgnoreAllIssues(boolean ignoreAllIssues) { - this.ignoreAllIssues = ignoreAllIssues; - } - - public void addIgnoreIssuesOnLineRanges(Collection lineRanges) { - if (this.ignoreIssuesOnlineRanges == null) { - this.ignoreIssuesOnlineRanges = new ArrayList<>(); - } - this.ignoreIssuesOnlineRanges.addAll(lineRanges); - } - - public boolean isIgnoreAllIssuesOnLine(@Nullable Integer line) { - if (line == null || ignoreIssuesOnlineRanges == null) { - return false; - } - return ignoreIssuesOnlineRanges.stream().anyMatch(r -> r[0] <= line && line <= r[1]); - } - - public void setExecutableLines(Set executableLines) { - checkState(this.executableLines == null, "Executable lines have already been saved for file: {}", this.toString()); - this.executableLines = new BitSet(lines()); - executableLines.forEach(l -> this.executableLines.set(l - 1)); - } - - public Optional> getExecutableLines() { - if (this.executableLines == null) { - return Optional.empty(); - } - return Optional.of(this.executableLines.stream().map(i -> i + 1).boxed().collect(Collectors.toSet())); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/PathPattern.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/PathPattern.java deleted file mode 100644 index 5d5947d9927..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/PathPattern.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info 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.fs; - -import java.nio.file.Path; -import javax.annotation.concurrent.ThreadSafe; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.utils.PathUtils; -import org.sonar.api.utils.WildcardPattern; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -@ThreadSafe -public abstract class PathPattern { - - private static final Logger LOG = Loggers.get(PathPattern.class); - - /** - * @deprecated since 6.6 - */ - @Deprecated - private static final String ABSOLUTE_PATH_PATTERN_PREFIX = "file:"; - final WildcardPattern pattern; - - PathPattern(String pattern) { - this.pattern = WildcardPattern.create(pattern); - } - - public abstract boolean match(Path absolutePath, Path relativePath); - - public abstract boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension); - - public static PathPattern create(String s) { - String trimmed = StringUtils.trim(s); - if (StringUtils.startsWithIgnoreCase(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX)) { - LOG.warn("Using absolute path pattern is deprecated. Please use relative path instead of '" + trimmed + "'"); - return new AbsolutePathPattern(StringUtils.substring(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX.length())); - } - return new RelativePathPattern(trimmed); - } - - public static PathPattern[] create(String[] s) { - PathPattern[] result = new PathPattern[s.length]; - for (int i = 0; i < s.length; i++) { - result[i] = create(s[i]); - } - return result; - } - - /** - * @deprecated since 6.6 - */ - @Deprecated - private static class AbsolutePathPattern extends PathPattern { - private AbsolutePathPattern(String pattern) { - super(pattern); - } - - @Override - public boolean match(Path absolutePath, Path relativePath) { - return match(absolutePath, relativePath, true); - } - - @Override - public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { - String path = PathUtils.sanitize(absolutePath.toString()); - if (!caseSensitiveFileExtension) { - String extension = sanitizeExtension(FilenameUtils.getExtension(path)); - if (StringUtils.isNotBlank(extension)) { - path = StringUtils.removeEndIgnoreCase(path, extension); - path = path + extension; - } - } - return pattern.match(path); - } - - @Override - public String toString() { - return ABSOLUTE_PATH_PATTERN_PREFIX + pattern.toString(); - } - } - - /** - * Path relative to module basedir - */ - private static class RelativePathPattern extends PathPattern { - private RelativePathPattern(String pattern) { - super(pattern); - } - - @Override - public boolean match(Path absolutePath, Path relativePath) { - return match(absolutePath, relativePath, true); - } - - @Override - public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { - String path = PathUtils.sanitize(relativePath.toString()); - if (!caseSensitiveFileExtension) { - String extension = sanitizeExtension(FilenameUtils.getExtension(path)); - if (StringUtils.isNotBlank(extension)) { - path = StringUtils.removeEndIgnoreCase(path, extension); - path = path + extension; - } - } - return path != null && pattern.match(path); - } - - @Override - public String toString() { - return pattern.toString(); - } - } - - static String sanitizeExtension(String suffix) { - return StringUtils.lowerCase(StringUtils.removeStart(suffix, ".")); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java index 5d6e8b9bc9c..eee66064b29 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java @@ -31,7 +31,14 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; +import org.sonar.api.batch.fs.internal.DefaultInputDir; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.Metadata; +import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.api.utils.PathUtils; /** @@ -211,14 +218,14 @@ public class TestInputFileBuilder { return setMetadata(new FileMetadata().readMetadata(new StringReader(content))); } - public DefaultInputFile build() { + public org.sonar.api.batch.fs.internal.DefaultInputFile build() { Path absolutePath = moduleBaseDir.resolve(relativePath); if (projectBaseDir == null) { projectBaseDir = moduleBaseDir; } String projectRelativePath = projectBaseDir.relativize(absolutePath).toString(); - DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy()); - DefaultInputFile inputFile = new DefaultInputFile(indexedFile, + org.sonar.api.batch.fs.internal.DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy()); + org.sonar.api.batch.fs.internal.DefaultInputFile inputFile = new org.sonar.api.batch.fs.internal.DefaultInputFile(indexedFile, f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineStartOffsets, originalLineEndOffsets, lastValidOffset)), contents); inputFile.setStatus(status); @@ -227,7 +234,7 @@ public class TestInputFileBuilder { return inputFile; } - public static DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { + public static org.sonar.api.batch.fs.internal.DefaultInputModule newDefaultInputModule(String moduleKey, File baseDir) { ProjectDefinition definition = ProjectDefinition.create() .setKey(moduleKey) .setBaseDir(baseDir) @@ -235,17 +242,17 @@ public class TestInputFileBuilder { return newDefaultInputModule(definition); } - public static DefaultInputModule newDefaultInputModule(ProjectDefinition projectDefinition) { - return new DefaultInputModule(projectDefinition, TestInputFileBuilder.nextBatchId()); + public static org.sonar.api.batch.fs.internal.DefaultInputModule newDefaultInputModule(ProjectDefinition projectDefinition) { + return new org.sonar.api.batch.fs.internal.DefaultInputModule(projectDefinition, TestInputFileBuilder.nextBatchId()); } - public static DefaultInputModule newDefaultInputModule(AbstractProjectOrModule parent, String key) throws IOException { + public static DefaultInputModule newDefaultInputModule(org.sonar.api.batch.fs.internal.AbstractProjectOrModule parent, String key) throws IOException { Path basedir = parent.getBaseDir().resolve(key); Files.createDirectory(basedir); return newDefaultInputModule(key, basedir.toFile()); } - public static DefaultInputProject newDefaultInputProject(String projectKey, File baseDir) { + public static org.sonar.api.batch.fs.internal.DefaultInputProject newDefaultInputProject(String projectKey, File baseDir) { ProjectDefinition definition = ProjectDefinition.create() .setKey(projectKey) .setBaseDir(baseDir) @@ -253,8 +260,8 @@ public class TestInputFileBuilder { return newDefaultInputProject(definition); } - public static DefaultInputProject newDefaultInputProject(ProjectDefinition projectDefinition) { - return new DefaultInputProject(projectDefinition, TestInputFileBuilder.nextBatchId()); + public static org.sonar.api.batch.fs.internal.DefaultInputProject newDefaultInputProject(ProjectDefinition projectDefinition) { + return new org.sonar.api.batch.fs.internal.DefaultInputProject(projectDefinition, TestInputFileBuilder.nextBatchId()); } public static DefaultInputProject newDefaultInputProject(String key, Path baseDir) throws IOException { @@ -262,7 +269,7 @@ public class TestInputFileBuilder { return newDefaultInputProject(key, baseDir.toFile()); } - public static DefaultInputDir newDefaultInputDir(AbstractProjectOrModule module, String relativePath) throws IOException { + public static org.sonar.api.batch.fs.internal.DefaultInputDir newDefaultInputDir(org.sonar.api.batch.fs.internal.AbstractProjectOrModule module, String relativePath) throws IOException { Path basedir = module.getBaseDir().resolve(relativePath); Files.createDirectory(basedir); return new DefaultInputDir(module.key(), relativePath) diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/DefaultFilePredicates.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/DefaultFilePredicates.java index 60bb37e9896..bcda1ac7351 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/DefaultFilePredicates.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/DefaultFilePredicates.java @@ -30,7 +30,7 @@ import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; -import org.sonar.scanner.fs.PathPattern; +import org.sonar.api.batch.fs.internal.PathPattern; /** * Factory of {@link FilePredicate} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/PathPatternPredicate.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/PathPatternPredicate.java index 0fdabcbcd31..032d820919b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/PathPatternPredicate.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/PathPatternPredicate.java @@ -21,7 +21,7 @@ package org.sonar.scanner.fs.predicates; import java.nio.file.Paths; import org.sonar.api.batch.fs.InputFile; -import org.sonar.scanner.fs.PathPattern; +import org.sonar.api.batch.fs.internal.PathPattern; /** * @since 4.2 diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java index c3c23969ac6..1292e10612f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java @@ -17,7 +17,7 @@ * 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.postjob.internal; +package org.sonar.scanner.postjob; import java.util.Arrays; import java.util.Collection; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobOptimizer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobOptimizer.java index dda587711a3..cd68e1694fe 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobOptimizer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobOptimizer.java @@ -21,7 +21,6 @@ package org.sonar.scanner.postjob; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; import org.sonar.api.config.Configuration; public class PostJobOptimizer { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobWrapper.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobWrapper.java index 408ad6385c0..60ea2882163 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobWrapper.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobWrapper.java @@ -21,7 +21,6 @@ package org.sonar.scanner.postjob; import org.sonar.api.batch.postjob.PostJob; import org.sonar.api.batch.postjob.PostJobContext; -import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; public class PostJobWrapper { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java new file mode 100644 index 00000000000..42129a26177 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java @@ -0,0 +1,127 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.highlighting.NewHighlighting; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.api.batch.sensor.internal.DefaultStorable; +import org.sonar.api.batch.sensor.internal.SensorStorage; + +import static java.util.Objects.requireNonNull; +import static org.sonar.api.utils.Preconditions.checkState; + +public class DefaultHighlighting extends DefaultStorable implements NewHighlighting { + + private final List syntaxHighlightingRules; + private DefaultInputFile inputFile; + + public DefaultHighlighting(SensorStorage storage) { + super(storage); + syntaxHighlightingRules = new ArrayList<>(); + } + + public List getSyntaxHighlightingRuleSet() { + return syntaxHighlightingRules; + } + + private void checkOverlappingBoundaries() { + if (syntaxHighlightingRules.size() > 1) { + Iterator it = syntaxHighlightingRules.iterator(); + SyntaxHighlightingRule previous = it.next(); + while (it.hasNext()) { + SyntaxHighlightingRule current = it.next(); + if (previous.range().end().compareTo(current.range().start()) > 0 && (previous.range().end().compareTo(current.range().end()) < 0)) { + String errorMsg = String.format("Cannot register highlighting rule for characters at %s as it " + + "overlaps at least one existing rule", current.range()); + throw new IllegalStateException(errorMsg); + } + previous = current; + } + } + } + + @Override + public DefaultHighlighting onFile(InputFile inputFile) { + requireNonNull(inputFile, "file can't be null"); + this.inputFile = (DefaultInputFile) inputFile; + return this; + } + + public InputFile inputFile() { + return inputFile; + } + + @Override + public DefaultHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText) { + checkInputFileNotNull(); + TextRange newRange; + try { + newRange = inputFile.newRange(startOffset, endOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to highlight file " + inputFile, e); + } + return highlight(newRange, typeOfText); + } + + @Override + public DefaultHighlighting highlight(int startLine, int startLineOffset, int endLine, int endLineOffset, TypeOfText typeOfText) { + checkInputFileNotNull(); + TextRange newRange; + try { + newRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to highlight file " + inputFile, e); + } + return highlight(newRange, typeOfText); + } + + @Override + public DefaultHighlighting highlight(TextRange range, TypeOfText typeOfText) { + SyntaxHighlightingRule syntaxHighlightingRule = SyntaxHighlightingRule.create(range, typeOfText); + this.syntaxHighlightingRules.add(syntaxHighlightingRule); + return this; + } + + @Override + protected void doSave() { + checkInputFileNotNull(); + // Sort rules to avoid variation during consecutive runs + Collections.sort(syntaxHighlightingRules, (left, right) -> { + int result = left.range().start().compareTo(right.range().start()); + if (result == 0) { + result = right.range().end().compareTo(left.range().end()); + } + return result; + }); + checkOverlappingBoundaries(); + storage.store(this); + } + + private void checkInputFileNotNull() { + checkState(inputFile != null, "Call onFile() first"); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java index 415a884380b..b9ca180c598 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java @@ -41,7 +41,7 @@ import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; 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.NewHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; @@ -255,7 +255,8 @@ public class DefaultSensorStorage implements SensorStorage { } @Override - public void store(DefaultHighlighting highlighting) { + public void store(NewHighlighting newHighlighting) { + DefaultHighlighting highlighting = (DefaultHighlighting) newHighlighting; ScannerReportWriter writer = reportPublisher.getWriter(); DefaultInputFile inputFile = (DefaultInputFile) highlighting.inputFile(); if (shouldSkipStorage(inputFile)) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java index 887f1d02c66..45933fe1730 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java @@ -29,7 +29,7 @@ import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; 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.NewHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; @@ -48,7 +48,7 @@ class InMemorySensorStorage implements SensorStorage { Collection allAdHocRules = new ArrayList<>(); Collection allAnalysisErrors = new ArrayList<>(); - Map highlightingByComponent = new HashMap<>(); + Map highlightingByComponent = new HashMap<>(); Map cpdTokensByComponent = new HashMap<>(); Map> coverageByComponent = new HashMap<>(); Map symbolsPerComponent = new HashMap<>(); @@ -77,7 +77,8 @@ class InMemorySensorStorage implements SensorStorage { } @Override - public void store(DefaultHighlighting highlighting) { + public void store(NewHighlighting newHighlighting) { + DefaultHighlighting highlighting = (DefaultHighlighting) newHighlighting; String fileKey = highlighting.inputFile().key(); // Emulate duplicate storage check if (highlightingByComponent.containsKey(fileKey)) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java index 21e6d2b8f70..42e8559e83b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java @@ -37,7 +37,6 @@ 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; import org.sonar.api.batch.sensor.issue.NewExternalIssue; import org.sonar.api.batch.sensor.issue.NewIssue; @@ -65,7 +64,7 @@ public class ProjectSensorContext implements SensorContext { private final Configuration config; public ProjectSensorContext(DefaultInputProject project, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, - SensorStorage sensorStorage, SonarRuntime sonarRuntime) { + SensorStorage sensorStorage, SonarRuntime sonarRuntime) { this.project = project; this.config = config; this.mutableSettings = mutableSettings; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java index 26777fc0a99..785920220ff 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java @@ -44,7 +44,6 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.scanner.rule.ActiveRulesBuilder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.code.NewSignificantCode; @@ -59,8 +58,6 @@ 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; -import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.NewExternalIssue; @@ -82,6 +79,7 @@ import org.sonar.api.scanner.fs.InputProject; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.rule.ActiveRulesBuilder; import static java.util.Collections.unmodifiableMap; @@ -342,7 +340,7 @@ public class SensorContextTester implements SensorContext { * @return List of styles applied to this position or empty list if there is no highlighting at this position. */ public List highlightingTypeAt(String componentKey, int line, int lineOffset) { - DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey); + DefaultHighlighting syntaxHighlightingData = (DefaultHighlighting) sensorStorage.highlightingByComponent.get(componentKey); if (syntaxHighlightingData == null) { return Collections.emptyList(); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SyntaxHighlightingRule.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SyntaxHighlightingRule.java new file mode 100644 index 00000000000..cded69e4bf5 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SyntaxHighlightingRule.java @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import org.apache.commons.lang.builder.ReflectionToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.sensor.highlighting.TypeOfText; + +public class SyntaxHighlightingRule { + + private final TextRange range; + private final TypeOfText textType; + + private SyntaxHighlightingRule(TextRange range, TypeOfText textType) { + this.range = range; + this.textType = textType; + } + + public static SyntaxHighlightingRule create(TextRange range, TypeOfText textType) { + return new SyntaxHighlightingRule(range, textType); + } + + public TextRange range() { + return range; + } + + public TypeOfText getTextType() { + return textType; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.SIMPLE_STYLE); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java index 19ce32d686c..d60f344a516 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.scanner.sensor.DefaultMeasure; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionnaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionnaryTest.java index 4d63704cae0..2c4ed265b27 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionnaryTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionnaryTest.java @@ -33,8 +33,8 @@ import org.sonar.api.batch.ScannerSide; 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.internal.DefaultSensorDescriptor; import org.sonar.core.platform.ComponentContainer; +import org.sonar.scanner.sensor.DefaultSensorDescriptor; import org.sonar.scanner.sensor.ModuleSensorContext; import org.sonar.scanner.sensor.ModuleSensorExtensionDictionnary; import org.sonar.scanner.sensor.ModuleSensorOptimizer; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionnaryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionnaryTest.java index 15cf84a2a18..ed35ee1943d 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionnaryTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionnaryTest.java @@ -25,7 +25,7 @@ import org.sonar.api.batch.Phase; import org.sonar.api.batch.postjob.PostJob; import org.sonar.api.batch.postjob.PostJobContext; import org.sonar.api.batch.postjob.PostJobDescriptor; -import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.scanner.postjob.DefaultPostJobDescriptor; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java index 3e10ad5dad3..ecc155cd5e5 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java @@ -38,7 +38,7 @@ import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentMatchers; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.util.CloseableIterator; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java index 7a0a2f21695..3d7c7486034 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java @@ -33,10 +33,10 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.duplications.block.Block; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.eq; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java index 155e08b98c4..596a25f9275 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java @@ -28,12 +28,12 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.rule.Severity; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.scanner.sensor.SensorContextTester; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.commons.lang.ObjectUtils.defaultIfNull; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultFileSystemTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultFileSystemTest.java new file mode 100644 index 00000000000..74a43db65f1 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultFileSystemTest.java @@ -0,0 +1,139 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs; + +import java.io.File; +import java.nio.charset.Charset; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultFileSystemTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private DefaultFileSystem fs; + + private File basedir; + + @Before + public void prepare() throws Exception { + basedir = temp.newFolder(); + fs = new DefaultFileSystem(basedir.toPath()); + } + + @Test + public void test_directories() throws Exception { + assertThat(fs.baseDir()).isAbsolute().isDirectory().exists(); + assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); + + File workdir = temp.newFolder(); + fs.setWorkDir(workdir.toPath()); + assertThat(fs.workDir()).isAbsolute().isDirectory().exists(); + assertThat(fs.workDir().getCanonicalPath()).isEqualTo(workdir.getCanonicalPath()); + } + + @Test + public void test_encoding() throws Exception { + fs.setEncoding(Charset.forName("ISO-8859-1")); + assertThat(fs.encoding()).isEqualTo(Charset.forName("ISO-8859-1")); + } + + @Test + public void add_languages() { + assertThat(fs.languages()).isEmpty(); + + fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + + assertThat(fs.languages()).containsOnly("java", "php"); + } + + @Test + public void files() { + assertThat(fs.inputFiles(fs.predicates().all())).isEmpty(); + + fs.add(new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build()); + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); + + // no language + fs.add(new TestInputFileBuilder("foo", "src/readme.txt").build()); + + assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNotNull(); + assertThat(fs.inputFile(fs.predicates().hasRelativePath("does/not/exist"))).isNull(); + + assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "src/Bar.java").getAbsolutePath()))).isNotNull(); + assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "does/not/exist").getAbsolutePath()))).isNull(); + assertThat(fs.inputFile(fs.predicates().hasAbsolutePath(new File(basedir, "../src/Bar.java").getAbsolutePath()))).isNull(); + + assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "src/Bar.java").toURI()))).isNotNull(); + assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "does/not/exist").toURI()))).isNull(); + assertThat(fs.inputFile(fs.predicates().hasURI(new File(basedir, "../src/Bar.java").toURI()))).isNull(); + + assertThat(fs.files(fs.predicates().all())).hasSize(4); + assertThat(fs.files(fs.predicates().hasLanguage("java"))).hasSize(2); + assertThat(fs.files(fs.predicates().hasLanguage("cobol"))).isEmpty(); + + assertThat(fs.hasFiles(fs.predicates().all())).isTrue(); + assertThat(fs.hasFiles(fs.predicates().hasLanguage("java"))).isTrue(); + assertThat(fs.hasFiles(fs.predicates().hasLanguage("cobol"))).isFalse(); + + assertThat(fs.inputFiles(fs.predicates().all())).hasSize(4); + assertThat(fs.inputFiles(fs.predicates().hasLanguage("php"))).hasSize(1); + assertThat(fs.inputFiles(fs.predicates().hasLanguage("java"))).hasSize(2); + assertThat(fs.inputFiles(fs.predicates().hasLanguage("cobol"))).isEmpty(); + + assertThat(fs.languages()).containsOnly("java", "php"); + } + + @Test + public void input_file_returns_null_if_file_not_found() { + assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNull(); + assertThat(fs.inputFile(fs.predicates().hasLanguage("cobol"))).isNull(); + } + + @Test + public void input_file_fails_if_too_many_results() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("expected one element"); + + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); + + fs.inputFile(fs.predicates().all()); + } + + @Test + public void input_file_supports_non_indexed_predicates() { + fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); + + // it would fail if more than one java file + assertThat(fs.inputFile(fs.predicates().hasLanguage("java"))).isNotNull(); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java new file mode 100644 index 00000000000..826edf9d086 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java @@ -0,0 +1,310 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +import javax.annotation.Nullable; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.Metadata; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; + +import static org.apache.commons.codec.digest.DigestUtils.md5Hex; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +public class FileMetadataTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public LogTester logTester = new LogTester(); + + @Test + public void empty_file() throws Exception { + File tempFile = temp.newFile(); + FileUtils.touch(tempFile); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(1); + assertThat(metadata.nonBlankLines()).isEqualTo(0); + assertThat(metadata.hash()).isNotEmpty(); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0); + assertThat(metadata.originalLineEndOffsets()).containsOnly(0); + assertThat(metadata.isEmpty()).isTrue(); + } + + @Test + public void windows_without_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 8, 13); + assertThat(metadata.isEmpty()).isFalse(); + } + + @Test + public void read_with_wrong_encoding() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "marker´s\n", Charset.forName("cp1252")); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(2); + assertThat(metadata.hash()).isEqualTo(md5Hex("marker\ufffds\n")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 9); + } + + @Test + public void non_ascii_utf_8() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10, 18); + } + + @Test + public void non_ascii_utf_16() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_16, true); + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_16, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8))); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 5, 10, 18); + } + + @Test + public void unix_without_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\nbar\nbaz", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11); + assertThat(metadata.isEmpty()).isFalse(); + } + + @Test + public void unix_with_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\nbar\nbaz\n", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8, 12); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11, 12); + } + + @Test + public void mac_without_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\rbar\rbaz", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11); + } + + @Test + public void mac_with_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\rbar\rbaz\r", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 8, 12); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 11, 12); + } + + @Test + public void mix_of_newlines_with_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 9, 13); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 12, 13); + } + + @Test + public void several_new_lines() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\n\n\nbar", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(2); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\n\n\nbar")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 5, 6); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 4, 5, 9); + } + + @Test + public void mix_of_newlines_without_latest_eol() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "foo\nbar\r\nbaz", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(3); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 4, 9); + assertThat(metadata.originalLineEndOffsets()).containsOnly(3, 7, 12); + } + + @Test + public void start_with_newline() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "\nfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + assertThat(metadata.lines()).isEqualTo(4); + assertThat(metadata.nonBlankLines()).isEqualTo(3); + assertThat(metadata.hash()).isEqualTo(md5Hex("\nfoo\nbar\nbaz")); + assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 1, 5, 10); + assertThat(metadata.originalLineEndOffsets()).containsOnly(0, 4, 8, 13); + } + + @Test + public void ignore_whitespace_when_computing_line_hashes() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, " foo\nb ar\r\nbaz \t", StandardCharsets.UTF_8, true); + + org.sonar.api.batch.fs.internal.DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) + .setModuleBaseDir(tempFile.getParentFile().toPath()) + .setCharset(StandardCharsets.UTF_8) + .build(); + FileMetadata.computeLineHashesForIssueTracking(f, new FileMetadata.LineHashConsumer() { + + @Override + public void consume(int lineIdx, @Nullable byte[] hash) { + switch (lineIdx) { + case 1: + assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("foo")); + break; + case 2: + assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("bar")); + break; + case 3: + assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("baz")); + break; + default: + fail("Invalid line"); + } + } + }); + } + + @Test + public void dont_fail_on_empty_file() throws Exception { + File tempFile = temp.newFile(); + FileUtils.write(tempFile, "", StandardCharsets.UTF_8, true); + + DefaultInputFile f = new TestInputFileBuilder("foo", tempFile.getName()) + .setModuleBaseDir(tempFile.getParentFile().toPath()) + .setCharset(StandardCharsets.UTF_8) + .build(); + FileMetadata.computeLineHashesForIssueTracking(f, new FileMetadata.LineHashConsumer() { + + @Override + public void consume(int lineIdx, @Nullable byte[] hash) { + switch (lineIdx) { + case 1: + assertThat(hash).isNull(); + break; + default: + fail("Invalid line"); + } + } + }); + } + + @Test + public void line_feed_is_included_into_hash() throws Exception { + File file1 = temp.newFile(); + FileUtils.write(file1, "foo\nbar\n", StandardCharsets.UTF_8, true); + + // same as file1, except an additional return carriage + File file1a = temp.newFile(); + FileUtils.write(file1a, "foo\r\nbar\n", StandardCharsets.UTF_8, true); + + File file2 = temp.newFile(); + FileUtils.write(file2, "foo\nbar", StandardCharsets.UTF_8, true); + + String hash1 = new FileMetadata().readMetadata(new FileInputStream(file1), StandardCharsets.UTF_8, file1.getName()).hash(); + String hash1a = new FileMetadata().readMetadata(new FileInputStream(file1a), StandardCharsets.UTF_8, file1a.getName()).hash(); + String hash2 = new FileMetadata().readMetadata(new FileInputStream(file2), StandardCharsets.UTF_8, file2.getName()).hash(); + + assertThat(hash1).isEqualTo(hash1a); + assertThat(hash1).isNotEqualTo(hash2); + } + + @Test + public void binary_file_with_unmappable_character() throws Exception { + File woff = new File(this.getClass().getResource("glyphicons-halflings-regular.woff").toURI()); + + Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(woff), StandardCharsets.UTF_8, woff.getAbsolutePath()); + + assertThat(metadata.lines()).isEqualTo(135); + assertThat(metadata.nonBlankLines()).isEqualTo(133); + assertThat(metadata.hash()).isNotEmpty(); + + assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains("Invalid character encountered in file"); + assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains( + "glyphicons-halflings-regular.woff at line 1 for encoding UTF-8. Please fix file content or configure the encoding to be used using property 'sonar.sourceEncoding'."); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/charhandler/IntArrayListTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/charhandler/IntArrayListTest.java new file mode 100644 index 00000000000..048a0309e5f --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/charhandler/IntArrayListTest.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.charhandler; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class IntArrayListTest { + + @Test + public void addElements() { + IntArrayList list = new IntArrayList(); + assertThat(list.trimAndGet()).isEmpty(); + list.add(1); + list.add(2); + assertThat(list.trimAndGet()).containsExactly(1, 2); + } + + @Test + public void trimIfNeeded() { + IntArrayList list = new IntArrayList(); + list.add(1); + list.add(2); + assertThat(list.trimAndGet()).isSameAs(list.trimAndGet()); + } + + @Test + public void grow() { + // Default capacity is 10 + IntArrayList list = new IntArrayList(); + for (int i = 1; i <= 11; i++) { + list.add(i); + } + assertThat(list.trimAndGet()).hasSize(11); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/AndPredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/AndPredicateTest.java new file mode 100644 index 00000000000..d3ec2aa7b81 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/AndPredicateTest.java @@ -0,0 +1,76 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import org.junit.Test; +import org.sonar.api.batch.fs.FilePredicate; + +import java.util.Arrays; +import org.sonar.api.batch.fs.internal.PathPattern; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AndPredicateTest { + + @Test + public void flattenNestedAnd() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); + FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, + AndPredicate.create(Arrays.asList(pathPatternPredicate2, pathPatternPredicate3)))); + assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); + } + + @Test + public void sortPredicatesByPriority() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + RelativePathPredicate relativePathPredicate = new RelativePathPredicate("foo"); + FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, + relativePathPredicate, pathPatternPredicate2)); + assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(relativePathPredicate, pathPatternPredicate1, pathPatternPredicate2); + } + + @Test + public void simplifyAndExpressionsWhenEmpty() { + FilePredicate andPredicate = AndPredicate.create(Arrays.asList()); + assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); + } + + @Test + public void simplifyAndExpressionsWhenTrue() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, + TruePredicate.TRUE, pathPatternPredicate2)); + assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); + } + + @Test + public void simplifyAndExpressionsWhenFalse() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + FilePredicate andPredicate = AndPredicate.create(Arrays.asList(pathPatternPredicate1, + FalsePredicate.FALSE, pathPatternPredicate2)); + assertThat(andPredicate).isEqualTo(FalsePredicate.FALSE); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/DefaultFilePredicatesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/DefaultFilePredicatesTest.java new file mode 100644 index 00000000000..d0869f0d9a2 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/DefaultFilePredicatesTest.java @@ -0,0 +1,245 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Status; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultFilePredicatesTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private Path moduleBasePath; + + @Before + public void setUp() throws IOException { + moduleBasePath = temp.newFolder().toPath(); + } + + InputFile javaFile; + FilePredicates predicates; + + @Before + public void before() throws IOException { + predicates = new DefaultFilePredicates(temp.newFolder().toPath()); + javaFile = new TestInputFileBuilder("foo", "src/main/java/struts/Action.java") + .setModuleBaseDir(moduleBasePath) + .setLanguage("java") + .setStatus(Status.SAME) + .build(); + + } + + @Test + public void all() { + assertThat(predicates.all().apply(javaFile)).isTrue(); + } + + @Test + public void none() { + assertThat(predicates.none().apply(javaFile)).isFalse(); + } + + @Test + public void matches_inclusion_pattern() { + assertThat(predicates.matchesPathPattern("src/main/**/Action.java").apply(javaFile)).isTrue(); + assertThat(predicates.matchesPathPattern("Action.java").apply(javaFile)).isFalse(); + assertThat(predicates.matchesPathPattern("src/**/*.php").apply(javaFile)).isFalse(); + } + + @Test + public void matches_inclusion_patterns() { + assertThat(predicates.matchesPathPatterns(new String[] {"src/other/**.java", "src/main/**/Action.java"}).apply(javaFile)).isTrue(); + assertThat(predicates.matchesPathPatterns(new String[] {}).apply(javaFile)).isTrue(); + assertThat(predicates.matchesPathPatterns(new String[] {"src/other/**.java", "src/**/*.php"}).apply(javaFile)).isFalse(); + } + + @Test + public void does_not_match_exclusion_pattern() { + assertThat(predicates.doesNotMatchPathPattern("src/main/**/Action.java").apply(javaFile)).isFalse(); + assertThat(predicates.doesNotMatchPathPattern("Action.java").apply(javaFile)).isTrue(); + assertThat(predicates.doesNotMatchPathPattern("src/**/*.php").apply(javaFile)).isTrue(); + } + + @Test + public void does_not_match_exclusion_patterns() { + assertThat(predicates.doesNotMatchPathPatterns(new String[] {}).apply(javaFile)).isTrue(); + assertThat(predicates.doesNotMatchPathPatterns(new String[] {"src/other/**.java", "src/**/*.php"}).apply(javaFile)).isTrue(); + assertThat(predicates.doesNotMatchPathPatterns(new String[] {"src/other/**.java", "src/main/**/Action.java"}).apply(javaFile)).isFalse(); + } + + @Test + public void has_relative_path() { + assertThat(predicates.hasRelativePath("src/main/java/struts/Action.java").apply(javaFile)).isTrue(); + assertThat(predicates.hasRelativePath("src/main/java/struts/Other.java").apply(javaFile)).isFalse(); + + // path is normalized + assertThat(predicates.hasRelativePath("src/main/java/../java/struts/Action.java").apply(javaFile)).isTrue(); + + assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\Action.java").apply(javaFile)).isTrue(); + assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\Other.java").apply(javaFile)).isFalse(); + assertThat(predicates.hasRelativePath("src\\main\\java\\struts\\..\\struts\\Action.java").apply(javaFile)).isTrue(); + } + + @Test + public void has_absolute_path() throws Exception { + String path = javaFile.file().getAbsolutePath(); + assertThat(predicates.hasAbsolutePath(path).apply(javaFile)).isTrue(); + assertThat(predicates.hasAbsolutePath(path.replaceAll("/", "\\\\")).apply(javaFile)).isTrue(); + + assertThat(predicates.hasAbsolutePath(temp.newFile().getAbsolutePath()).apply(javaFile)).isFalse(); + assertThat(predicates.hasAbsolutePath("src/main/java/struts/Action.java").apply(javaFile)).isFalse(); + } + + @Test + public void has_uri() throws Exception { + URI uri = javaFile.uri(); + assertThat(predicates.hasURI(uri).apply(javaFile)).isTrue(); + + assertThat(predicates.hasURI(temp.newFile().toURI()).apply(javaFile)).isFalse(); + } + + @Test + public void has_path() throws Exception { + // is relative path + assertThat(predicates.hasPath("src/main/java/struts/Action.java").apply(javaFile)).isTrue(); + assertThat(predicates.hasPath("src/main/java/struts/Other.java").apply(javaFile)).isFalse(); + + // is absolute path + String path = javaFile.file().getAbsolutePath(); + assertThat(predicates.hasAbsolutePath(path).apply(javaFile)).isTrue(); + assertThat(predicates.hasPath(temp.newFile().getAbsolutePath()).apply(javaFile)).isFalse(); + } + + @Test + public void is_file() throws Exception { + // relative file + assertThat(predicates.is(new File(javaFile.relativePath())).apply(javaFile)).isTrue(); + + // absolute file + assertThat(predicates.is(javaFile.file()).apply(javaFile)).isTrue(); + assertThat(predicates.is(javaFile.file().getAbsoluteFile()).apply(javaFile)).isTrue(); + assertThat(predicates.is(new File(javaFile.file().toURI())).apply(javaFile)).isTrue(); + assertThat(predicates.is(temp.newFile()).apply(javaFile)).isFalse(); + } + + @Test + public void has_language() { + assertThat(predicates.hasLanguage("java").apply(javaFile)).isTrue(); + assertThat(predicates.hasLanguage("php").apply(javaFile)).isFalse(); + } + + @Test + public void has_languages() { + assertThat(predicates.hasLanguages(Arrays.asList("java", "php")).apply(javaFile)).isTrue(); + assertThat(predicates.hasLanguages(Arrays.asList("cobol", "php")).apply(javaFile)).isFalse(); + assertThat(predicates.hasLanguages(Collections.emptyList()).apply(javaFile)).isTrue(); + } + + @Test + public void has_type() { + assertThat(predicates.hasType(InputFile.Type.MAIN).apply(javaFile)).isTrue(); + assertThat(predicates.hasType(InputFile.Type.TEST).apply(javaFile)).isFalse(); + } + + @Test + public void has_status() { + assertThat(predicates.hasAnyStatus().apply(javaFile)).isTrue(); + assertThat(predicates.hasStatus(InputFile.Status.SAME).apply(javaFile)).isTrue(); + assertThat(predicates.hasStatus(InputFile.Status.ADDED).apply(javaFile)).isFalse(); + } + + @Test + public void not() { + assertThat(predicates.not(predicates.hasType(InputFile.Type.MAIN)).apply(javaFile)).isFalse(); + assertThat(predicates.not(predicates.hasType(InputFile.Type.TEST)).apply(javaFile)).isTrue(); + } + + @Test + public void and() { + // empty + assertThat(predicates.and().apply(javaFile)).isTrue(); + assertThat(predicates.and(new FilePredicate[0]).apply(javaFile)).isTrue(); + assertThat(predicates.and(Collections.emptyList()).apply(javaFile)).isTrue(); + + // two arguments + assertThat(predicates.and(predicates.all(), predicates.all()).apply(javaFile)).isTrue(); + assertThat(predicates.and(predicates.all(), predicates.none()).apply(javaFile)).isFalse(); + assertThat(predicates.and(predicates.none(), predicates.all()).apply(javaFile)).isFalse(); + + // collection + assertThat(predicates.and(Arrays.asList(predicates.all(), predicates.all())).apply(javaFile)).isTrue(); + assertThat(predicates.and(Arrays.asList(predicates.all(), predicates.none())).apply(javaFile)).isFalse(); + + // array + assertThat(predicates.and(new FilePredicate[] {predicates.all(), predicates.all()}).apply(javaFile)).isTrue(); + assertThat(predicates.and(new FilePredicate[] {predicates.all(), predicates.none()}).apply(javaFile)).isFalse(); + } + + @Test + public void or() { + // empty + assertThat(predicates.or().apply(javaFile)).isTrue(); + assertThat(predicates.or(new FilePredicate[0]).apply(javaFile)).isTrue(); + assertThat(predicates.or(Collections.emptyList()).apply(javaFile)).isTrue(); + + // two arguments + assertThat(predicates.or(predicates.all(), predicates.all()).apply(javaFile)).isTrue(); + assertThat(predicates.or(predicates.all(), predicates.none()).apply(javaFile)).isTrue(); + assertThat(predicates.or(predicates.none(), predicates.all()).apply(javaFile)).isTrue(); + assertThat(predicates.or(predicates.none(), predicates.none()).apply(javaFile)).isFalse(); + + // collection + assertThat(predicates.or(Arrays.asList(predicates.all(), predicates.all())).apply(javaFile)).isTrue(); + assertThat(predicates.or(Arrays.asList(predicates.all(), predicates.none())).apply(javaFile)).isTrue(); + assertThat(predicates.or(Arrays.asList(predicates.none(), predicates.none())).apply(javaFile)).isFalse(); + + // array + assertThat(predicates.or(new FilePredicate[] {predicates.all(), predicates.all()}).apply(javaFile)).isTrue(); + assertThat(predicates.or(new FilePredicate[] {predicates.all(), predicates.none()}).apply(javaFile)).isTrue(); + assertThat(predicates.or(new FilePredicate[] {predicates.none(), predicates.none()}).apply(javaFile)).isFalse(); + } + + @Test + public void hasFilename() { + assertThat(predicates.hasFilename("Action.java").apply(javaFile)).isTrue(); + } + + @Test + public void hasExtension() { + assertThat(predicates.hasExtension("java").apply(javaFile)).isTrue(); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FileExtensionPredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FileExtensionPredicateTest.java new file mode 100644 index 00000000000..8cae2f45ff0 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FileExtensionPredicateTest.java @@ -0,0 +1,72 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import java.io.IOException; +import org.junit.Test; +import org.sonar.api.batch.fs.InputFile; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.scanner.fs.predicates.FileExtensionPredicate.getExtension; + +public class FileExtensionPredicateTest { + + @Test + public void should_match_correct_extension() throws IOException { + FileExtensionPredicate predicate = new FileExtensionPredicate("bat"); + assertThat(predicate.apply(mockWithName("prog.bat"))).isTrue(); + assertThat(predicate.apply(mockWithName("prog.bat.bat"))).isTrue(); + } + + @Test + public void should_not_match_incorrect_extension() throws IOException { + FileExtensionPredicate predicate = new FileExtensionPredicate("bat"); + assertThat(predicate.apply(mockWithName("prog.batt"))).isFalse(); + assertThat(predicate.apply(mockWithName("prog.abat"))).isFalse(); + assertThat(predicate.apply(mockWithName("prog."))).isFalse(); + assertThat(predicate.apply(mockWithName("prog.bat."))).isFalse(); + assertThat(predicate.apply(mockWithName("prog.bat.batt"))).isFalse(); + assertThat(predicate.apply(mockWithName("prog"))).isFalse(); + } + + @Test + public void should_match_correct_extension_case_insensitively() throws IOException { + FileExtensionPredicate predicate = new FileExtensionPredicate("jAVa"); + assertThat(predicate.apply(mockWithName("Program.java"))).isTrue(); + assertThat(predicate.apply(mockWithName("Program.JAVA"))).isTrue(); + assertThat(predicate.apply(mockWithName("Program.Java"))).isTrue(); + assertThat(predicate.apply(mockWithName("Program.JaVa"))).isTrue(); + } + + @Test + public void test_empty_extension() { + assertThat(getExtension("prog")).isEmpty(); + assertThat(getExtension("prog.")).isEmpty(); + assertThat(getExtension(".")).isEmpty(); + } + + private InputFile mockWithName(String filename) throws IOException { + InputFile inputFile = mock(InputFile.class); + when(inputFile.filename()).thenReturn(filename); + return inputFile; + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FilenamePredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FilenamePredicateTest.java new file mode 100644 index 00000000000..71c7d1f47de --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FilenamePredicateTest.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import java.io.IOException; +import java.util.Collections; +import org.junit.Test; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class FilenamePredicateTest { + @Test + public void should_match_file_by_filename() throws IOException { + String filename = "some name"; + InputFile inputFile = mock(InputFile.class); + when(inputFile.filename()).thenReturn(filename); + + assertThat(new FilenamePredicate(filename).apply(inputFile)).isTrue(); + } + + @Test + public void should_not_match_file_by_different_filename() throws IOException { + String filename = "some name"; + InputFile inputFile = mock(InputFile.class); + when(inputFile.filename()).thenReturn(filename + "x"); + + assertThat(new FilenamePredicate(filename).apply(inputFile)).isFalse(); + } + + @Test + public void should_find_matching_file_in_index() throws IOException { + String filename = "some name"; + InputFile inputFile = mock(InputFile.class); + when(inputFile.filename()).thenReturn(filename); + + FileSystem.Index index = mock(FileSystem.Index.class); + when(index.getFilesByName(filename)).thenReturn(Collections.singleton(inputFile)); + + assertThat(new FilenamePredicate(filename).get(index)).containsOnly(inputFile); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/OrPredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/OrPredicateTest.java new file mode 100644 index 00000000000..0804d1f3f7e --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/OrPredicateTest.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import org.junit.Test; +import org.sonar.api.batch.fs.FilePredicate; + +import java.util.Arrays; +import org.sonar.api.batch.fs.internal.PathPattern; + +import static org.assertj.core.api.Assertions.assertThat; + +public class OrPredicateTest { + + @Test + public void flattenNestedOr() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + PathPatternPredicate pathPatternPredicate3 = new PathPatternPredicate(PathPattern.create("foo3/**")); + FilePredicate orPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, + OrPredicate.create(Arrays.asList(pathPatternPredicate2, pathPatternPredicate3)))); + assertThat(((OrPredicate) orPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2, pathPatternPredicate3); + } + + @Test + public void simplifyOrExpressionsWhenEmpty() { + FilePredicate orPredicate = OrPredicate.create(Arrays.asList()); + assertThat(orPredicate).isEqualTo(TruePredicate.TRUE); + } + + @Test + public void simplifyOrExpressionsWhenFalse() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + FilePredicate andPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, + FalsePredicate.FALSE, pathPatternPredicate2)); + assertThat(((OrPredicate) andPredicate).predicates()).containsExactly(pathPatternPredicate1, pathPatternPredicate2); + } + + @Test + public void simplifyAndExpressionsWhenTrue() { + PathPatternPredicate pathPatternPredicate1 = new PathPatternPredicate(PathPattern.create("foo1/**")); + PathPatternPredicate pathPatternPredicate2 = new PathPatternPredicate(PathPattern.create("foo2/**")); + FilePredicate andPredicate = OrPredicate.create(Arrays.asList(pathPatternPredicate1, + TruePredicate.TRUE, pathPatternPredicate2)); + assertThat(andPredicate).isEqualTo(TruePredicate.TRUE); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/RelativePathPredicateTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/RelativePathPredicateTest.java new file mode 100644 index 00000000000..b3c9c2dc9ff --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/RelativePathPredicateTest.java @@ -0,0 +1,53 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.fs.predicates; + +import org.junit.Test; +import org.sonar.api.batch.fs.InputFile; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RelativePathPredicateTest { + @Test + public void returns_false_when_path_is_invalid() { + RelativePathPredicate predicate = new RelativePathPredicate(".."); + InputFile inputFile = mock(InputFile.class); + when(inputFile.relativePath()).thenReturn("path"); + assertThat(predicate.apply(inputFile)).isFalse(); + } + + @Test + public void returns_true_if_matches() { + RelativePathPredicate predicate = new RelativePathPredicate("path"); + InputFile inputFile = mock(InputFile.class); + when(inputFile.relativePath()).thenReturn("path"); + assertThat(predicate.apply(inputFile)).isTrue(); + } + + @Test + public void returns_false_if_doesnt_match() { + RelativePathPredicate predicate = new RelativePathPredicate("path1"); + InputFile inputFile = mock(InputFile.class); + when(inputFile.relativePath()).thenReturn("path2"); + assertThat(predicate.apply(inputFile)).isFalse(); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java index af226b302ee..b90e6a19dd4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java @@ -28,9 +28,9 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java index 817d7b4aae9..c9f44cd5b8f 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java @@ -28,12 +28,12 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.test.MutableTestCase; import org.sonar.api.test.MutableTestPlan; import org.sonar.api.utils.MessageException; import org.sonar.scanner.deprecated.test.TestPlanBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java index eb479cc0bce..980ee96bbe8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java @@ -28,7 +28,6 @@ import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.config.Encryption; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.utils.log.LogTester; @@ -36,6 +35,7 @@ import org.sonar.api.utils.log.LoggerLevel; import org.sonar.scanner.config.DefaultConfiguration; import org.sonar.scanner.deprecated.test.TestPlanBuilder; import org.sonar.scanner.scan.ProjectConfiguration; +import org.sonar.scanner.sensor.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java index 50ea80aceb7..50c247f5b51 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java @@ -34,7 +34,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.rule.ActiveRulesBuilder; import org.sonar.scanner.rule.NewActiveRule; import org.sonar.scanner.rule.RulesBuilder; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java index 80ce4f25eb2..a656a767f71 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java @@ -26,7 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.rule.RuleKey; import org.sonar.api.scan.issue.filter.IssueFilterChain; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java index b52ad14b4af..6a597ef85b3 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java @@ -28,7 +28,7 @@ import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java index ab54b184c7d..07c39d82113 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java @@ -35,8 +35,8 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.FileMetadata; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader.DoubleRegexpMatcher; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java index f376d56999e..16154f5ff0c 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java @@ -31,7 +31,7 @@ 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.FileMetadata; +import org.sonar.scanner.fs.FileMetadata; import org.sonar.scanner.mediumtest.AnalysisResult; import org.sonar.scanner.mediumtest.ScannerMediumTester; import org.sonar.scanner.protocol.output.ScannerReport; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java index 63239c0924a..fe18fdb725f 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.ModuleConfiguration; import org.sonar.scanner.scan.filesystem.ModuleCoverageAndDuplicationExclusions; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java index c715462d0ca..bce232d44f0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java @@ -29,7 +29,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.batch.fs.internal.SensorStrategy; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.scanner.sensor.ModuleSensorExtensionDictionnary; import org.sonar.scanner.bootstrap.ScannerPluginRepository; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java index ea27f1cd1f8..b041c6badc8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.ProjectConfiguration; import org.sonar.scanner.scan.filesystem.ProjectCoverageAndDuplicationExclusions; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java index 45c25ef9568..1b604e11b6e 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java @@ -23,8 +23,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; -import org.sonar.api.config.Settings; import org.sonar.api.config.internal.MapSettings; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java index 2d155cea756..4d4a3476553 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java @@ -33,7 +33,7 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java index 41a5c2eeb78..36134513be9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java @@ -33,7 +33,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.utils.DateUtils; import org.sonar.scanner.ProjectInfo; import org.sonar.scanner.protocol.output.FileStructure; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java index 3c1d845f785..7a66973ec20 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java @@ -41,7 +41,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.scanner.ProjectInfo; import org.sonar.scanner.bootstrap.ScannerPlugin; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java index 4028bdae0af..5f6054f81c9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java @@ -29,7 +29,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.protocol.output.ScannerReportWriter; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java new file mode 100644 index 00000000000..e892510d046 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java @@ -0,0 +1,104 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.rule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.rule.ActiveRule; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.Severity; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ActiveRulesBuilderTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void no_rules() { + ActiveRulesBuilder builder = new ActiveRulesBuilder(); + ActiveRules rules = builder.build(); + assertThat(rules.findAll()).isEmpty(); + } + + @Test + public void build_rules() { + NewActiveRule activeRule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("squid", "S0001")) + .setName("My Rule") + .setSeverity(Severity.CRITICAL) + .setInternalKey("__S0001__") + .setParam("min", "20") + .build(); + + ActiveRules activeRules = new ActiveRulesBuilder() + .addRule(activeRule) + // most simple rule + .addRule(new NewActiveRule.Builder().setRuleKey(RuleKey.of("squid", "S0002")).build()) + .addRule(new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("findbugs", "NPE")) + .setInternalKey(null) + .setSeverity(null) + .setParam("foo", null) + .build()) + .build(); + + assertThat(activeRules.findAll()).hasSize(3); + assertThat(activeRules.findByRepository("squid")).hasSize(2); + assertThat(activeRules.findByRepository("findbugs")).hasSize(1); + assertThat(activeRules.findByInternalKey("squid", "__S0001__")).isNotNull(); + assertThat(activeRules.findByRepository("unknown")).isEmpty(); + + ActiveRule squid1 = activeRules.find(RuleKey.of("squid", "S0001")); + assertThat(squid1.ruleKey().repository()).isEqualTo("squid"); + assertThat(squid1.ruleKey().rule()).isEqualTo("S0001"); + assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL); + assertThat(squid1.internalKey()).isEqualTo("__S0001__"); + assertThat(squid1.params()).hasSize(1); + assertThat(squid1.param("min")).isEqualTo("20"); + + ActiveRule squid2 = activeRules.find(RuleKey.of("squid", "S0002")); + assertThat(squid2.ruleKey().repository()).isEqualTo("squid"); + assertThat(squid2.ruleKey().rule()).isEqualTo("S0002"); + assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity()); + assertThat(squid2.params()).isEmpty(); + + ActiveRule findbugsRule = activeRules.find(RuleKey.of("findbugs", "NPE")); + assertThat(findbugsRule.severity()).isEqualTo(Severity.defaultSeverity()); + assertThat(findbugsRule.internalKey()).isNull(); + assertThat(findbugsRule.params()).isEmpty(); + } + + @Test + public void fail_to_add_twice_the_same_rule() { + ActiveRulesBuilder builder = new ActiveRulesBuilder(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("squid", "S0001")) + .build(); + builder.addRule(rule); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Rule 'squid:S0001' is already activated"); + + builder.addRule(rule); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultRulesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultRulesTest.java new file mode 100644 index 00000000000..3beb53fcc04 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultRulesTest.java @@ -0,0 +1,73 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.rule; + +import org.sonar.api.rule.RuleKey; +import org.junit.Test; + +import java.util.LinkedList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultRulesTest { + @Test + public void testRepeatedInternalKey() { + List newRules = new LinkedList<>(); + newRules.add(createRule("key1", "repo", "internal")); + newRules.add(createRule("key2", "repo", "internal")); + + DefaultRules rules = new DefaultRules(newRules); + assertThat(rules.findByInternalKey("repo", "internal")).hasSize(2); + assertThat(rules.find(RuleKey.of("repo", "key1"))).isNotNull(); + assertThat(rules.find(RuleKey.of("repo", "key2"))).isNotNull(); + assertThat(rules.findByRepository("repo")).hasSize(2); + } + + @Test + public void testNonExistingKey() { + List newRules = new LinkedList<>(); + newRules.add(createRule("key1", "repo", "internal")); + newRules.add(createRule("key2", "repo", "internal")); + + DefaultRules rules = new DefaultRules(newRules); + assertThat(rules.findByInternalKey("xx", "xx")).hasSize(0); + assertThat(rules.find(RuleKey.of("xxx", "xx"))).isNull(); + assertThat(rules.findByRepository("xxxx")).hasSize(0); + } + + @Test + public void testRepeatedRule() { + List newRules = new LinkedList<>(); + newRules.add(createRule("key", "repo", "internal")); + newRules.add(createRule("key", "repo", "internal")); + + DefaultRules rules = new DefaultRules(newRules); + assertThat(rules.find(RuleKey.of("repo", "key"))).isNotNull(); + } + + private NewRule createRule(String key, String repo, String internalKey) { + RuleKey ruleKey = RuleKey.of(repo, key); + NewRule newRule = new NewRule(ruleKey); + newRule.setInternalKey(internalKey); + + return newRule; + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/NewActiveRuleTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/NewActiveRuleTest.java new file mode 100644 index 00000000000..a3a4e40393d --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/NewActiveRuleTest.java @@ -0,0 +1,87 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.rule; + +import com.google.common.collect.ImmutableMap; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.Severity; + +import static org.assertj.core.api.Assertions.assertThat; + +public class NewActiveRuleTest { + + private NewActiveRule.Builder builder; + + @Before + public void setBuilder() { + builder = new NewActiveRule.Builder(); + } + + @Test + public void builder_should_set_every_param() { + NewActiveRule rule = builder + .setRuleKey(RuleKey.of("foo", "bar")) + .setName("name") + .setSeverity(Severity.CRITICAL) + .setParam("key", "value") + .setCreatedAt(1_000L) + .setUpdatedAt(1_000L) + .setInternalKey("internal_key") + .setLanguage("language") + .setTemplateRuleKey("templateRuleKey") + .setQProfileKey("qProfileKey") + .build(); + + assertThat(rule.ruleKey).isEqualTo(RuleKey.of("foo", "bar")); + assertThat(rule.name).isEqualTo("name"); + assertThat(rule.severity).isEqualTo(Severity.CRITICAL); + assertThat(rule.params).isEqualTo(ImmutableMap.of("key", "value")); + assertThat(rule.createdAt).isEqualTo(1_000L); + assertThat(rule.updatedAt).isEqualTo(1_000L); + assertThat(rule.internalKey).isEqualTo("internal_key"); + assertThat(rule.language).isEqualTo("language"); + assertThat(rule.templateRuleKey).isEqualTo("templateRuleKey"); + assertThat(rule.qProfileKey).isEqualTo("qProfileKey"); + } + + @Test + public void severity_should_have_default_value() { + NewActiveRule rule = builder.build(); + assertThat(rule.severity).isEqualTo(Severity.defaultSeverity()); + } + + @Test + public void params_should_be_empty_map_if_no_params() { + NewActiveRule rule = builder.build(); + assertThat(rule.params).isEqualTo(ImmutableMap.of()); + } + + @Test + public void set_param_remove_param_if_value_is_null() { + NewActiveRule rule = builder + .setParam("foo", "bar") + .setParam("removed", "value") + .setParam("removed", null) + .build(); + assertThat(rule.params).isEqualTo(ImmutableMap.of("foo", "bar")); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java index faad5baa933..f7a64f06b63 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java @@ -24,9 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.slf4j.Logger; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.utils.MessageException; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.branch.BranchConfiguration; import org.sonar.scanner.scan.filesystem.InputComponentStore; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/RulesBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/RulesBuilderTest.java new file mode 100644 index 00000000000..1bb2375bc21 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/RulesBuilderTest.java @@ -0,0 +1,112 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.rule; + +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.rule.Rule; +import org.sonar.api.batch.rule.Rules; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RulesBuilderTest { + @org.junit.Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void no_rules() { + RulesBuilder builder = new RulesBuilder(); + Rules rules = builder.build(); + assertThat(rules.findAll()).isEmpty(); + } + + @Test + public void build_rules() { + RulesBuilder builder = new RulesBuilder(); + NewRule newSquid1 = builder.add(RuleKey.of("squid", "S0001")); + newSquid1.setName("Detect bug"); + newSquid1.setDescription("Detect potential bug"); + newSquid1.setInternalKey("foo=bar"); + newSquid1.setSeverity(Severity.CRITICAL); + newSquid1.setStatus(RuleStatus.BETA); + newSquid1.addParam("min"); + newSquid1.addParam("max").setDescription("Maximum"); + // most simple rule + builder.add(RuleKey.of("squid", "S0002")); + builder.add(RuleKey.of("findbugs", "NPE")); + + Rules rules = builder.build(); + + assertThat(rules.findAll()).hasSize(3); + assertThat(rules.findByRepository("squid")).hasSize(2); + assertThat(rules.findByRepository("findbugs")).hasSize(1); + assertThat(rules.findByRepository("unknown")).isEmpty(); + + Rule squid1 = rules.find(RuleKey.of("squid", "S0001")); + assertThat(squid1.key().repository()).isEqualTo("squid"); + assertThat(squid1.key().rule()).isEqualTo("S0001"); + assertThat(squid1.name()).isEqualTo("Detect bug"); + assertThat(squid1.description()).isEqualTo("Detect potential bug"); + assertThat(squid1.internalKey()).isEqualTo("foo=bar"); + assertThat(squid1.status()).isEqualTo(RuleStatus.BETA); + assertThat(squid1.severity()).isEqualTo(Severity.CRITICAL); + assertThat(squid1.params()).hasSize(2); + assertThat(squid1.param("min").key()).isEqualTo("min"); + assertThat(squid1.param("min").description()).isNull(); + assertThat(squid1.param("max").key()).isEqualTo("max"); + assertThat(squid1.param("max").description()).isEqualTo("Maximum"); + + Rule squid2 = rules.find(RuleKey.of("squid", "S0002")); + assertThat(squid2.key().repository()).isEqualTo("squid"); + assertThat(squid2.key().rule()).isEqualTo("S0002"); + assertThat(squid2.description()).isNull(); + assertThat(squid2.internalKey()).isNull(); + assertThat(squid2.status()).isEqualTo(RuleStatus.defaultStatus()); + assertThat(squid2.severity()).isEqualTo(Severity.defaultSeverity()); + assertThat(squid2.params()).isEmpty(); + } + + @Test + public void fail_to_add_twice_the_same_rule() { + RulesBuilder builder = new RulesBuilder(); + builder.add(RuleKey.of("squid", "S0001")); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Rule 'squid:S0001' already exists"); + + builder.add(RuleKey.of("squid", "S0001")); + } + + @Test + public void fail_to_add_twice_the_same_param() { + RulesBuilder builder = new RulesBuilder(); + NewRule newRule = builder.add(RuleKey.of("squid", "S0001")); + newRule.addParam("min"); + newRule.addParam("max"); + + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Parameter 'min' already exists on rule 'squid:S0001'"); + + newRule.addParam("min"); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java index be8da961f40..37775d19ae5 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java @@ -22,7 +22,7 @@ package org.sonar.scanner.scan.filesystem; import org.junit.Test; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java index 98785e06e62..04490bd02e4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java @@ -35,7 +35,7 @@ import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.branch.BranchConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java index cc4b6bf2485..9bd732b9287 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java @@ -33,10 +33,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.PathUtils; +import org.sonar.scanner.fs.FileMetadata; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.IgnoreIssuesFilter; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.scanner.issue.ignore.scanner.IssueExclusionsLoader; @@ -59,7 +59,7 @@ public class MetadataGeneratorTest { private MetadataGenerator generator; @Before - public void setUp() throws IOException { + public void setUp() { MockitoAnnotations.initMocks(this); metadata = new FileMetadata(); IssueExclusionsLoader issueExclusionsLoader = new IssueExclusionsLoader(mock(IssueExclusionPatternInitializer.class), mock(IgnoreIssuesFilter.class), diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java index 29064edd51b..2ead8234b68 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java @@ -28,7 +28,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.fs.internal.SensorStrategy; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.scan.branch.BranchConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java index 857f12e9f69..ccd56feef74 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java @@ -27,7 +27,7 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.repository.FileData; import org.sonar.scanner.repository.ProjectRepositoriesSupplier; import org.sonar.scanner.repository.SingleProjectRepository; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java index 78a9c53a4f3..a408dde4a41 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java @@ -25,7 +25,7 @@ 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.TestInputFileBuilder; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.api.batch.scm.BlameLine; public class DefaultBlameOutputTest { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAdHocRuleTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAdHocRuleTest.java new file mode 100644 index 00000000000..44a53e7dbf9 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAdHocRuleTest.java @@ -0,0 +1,156 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.batch.sensor.rule.NewAdHocRule; +import org.sonar.api.rules.RuleType; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultAdHocRuleTest { + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void store() { + SensorStorage storage = mock(SensorStorage.class); + DefaultAdHocRule rule = new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId("ruleId") + .name("name") + .description("desc") + .severity(Severity.BLOCKER) + .type(RuleType.CODE_SMELL); + rule.save(); + + assertThat(rule.engineId()).isEqualTo("engine"); + assertThat(rule.ruleId()).isEqualTo("ruleId"); + assertThat(rule.name()).isEqualTo("name"); + assertThat(rule.description()).isEqualTo("desc"); + assertThat(rule.severity()).isEqualTo(Severity.BLOCKER); + assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL); + + verify(storage).store(any(DefaultAdHocRule.class)); + } + + + @Test + public void description_is_optional() { + SensorStorage storage = mock(SensorStorage.class); + new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId("ruleId") + .name("name") + .severity(Severity.BLOCKER) + .type(RuleType.CODE_SMELL) + .save(); + + verify(storage).store(any(DefaultAdHocRule.class)); + } + + @Test + public void fail_to_store_if_no_engine_id() { + SensorStorage storage = mock(SensorStorage.class); + NewAdHocRule rule = new DefaultAdHocRule(storage) + .engineId(" ") + .ruleId("ruleId") + .name("name") + .description("desc") + .severity(Severity.BLOCKER) + .type(RuleType.CODE_SMELL); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Engine id is mandatory"); + rule.save(); + } + + @Test + public void fail_to_store_if_no_rule_id() { + SensorStorage storage = mock(SensorStorage.class); + NewAdHocRule rule = new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId(" ") + .name("name") + .description("desc") + .severity(Severity.BLOCKER) + .type(RuleType.CODE_SMELL); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Rule id is mandatory"); + rule.save(); + } + + @Test + public void fail_to_store_if_no_name() { + SensorStorage storage = mock(SensorStorage.class); + NewAdHocRule rule = new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId("ruleId") + .name(" ") + .description("desc") + .severity(Severity.BLOCKER) + .type(RuleType.CODE_SMELL); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Name is mandatory"); + rule.save(); + } + + + @Test + public void fail_to_store_if_no_severity() { + SensorStorage storage = mock(SensorStorage.class); + NewAdHocRule rule = new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId("ruleId") + .name("name") + .description("desc") + .type(RuleType.CODE_SMELL); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Severity is mandatory"); + rule.save(); + } + + @Test + public void fail_to_store_if_no_type() { + SensorStorage storage = mock(SensorStorage.class); + NewAdHocRule rule = new DefaultAdHocRule(storage) + .engineId("engine") + .ruleId("ruleId") + .name("name") + .description("desc") + .severity(Severity.BLOCKER); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Type is mandatory"); + rule.save(); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java new file mode 100644 index 00000000000..ca91e301cc8 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java @@ -0,0 +1,159 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.io.IOException; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.InputComponent; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rules.RuleType; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultExternalIssueTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private DefaultInputProject project; + + @Before + public void setup() throws IOException { + project = new DefaultInputProject(ProjectDefinition.create() + .setKey("foo") + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder())); + } + + @Rule + public ExpectedException exception = ExpectedException.none(); + + private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("Foo\nBar\n") + .build(); + + @Test + public void build_file_issue() { + SensorStorage storage = mock(SensorStorage.class); + DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputFile) + .at(inputFile.selectLine(1)) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .remediationEffortMinutes(10l) + .type(RuleType.BUG) + .severity(Severity.BLOCKER); + + assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); + assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_repo", "rule")); + assertThat(issue.engineId()).isEqualTo("repo"); + assertThat(issue.ruleId()).isEqualTo("rule"); + assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); + assertThat(issue.remediationEffort()).isEqualTo(10l); + assertThat(issue.type()).isEqualTo(RuleType.BUG); + assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); + assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); + + issue.save(); + + verify(storage).store(issue); + } + + @Test + public void fail_to_store_if_no_type() { + SensorStorage storage = mock(SensorStorage.class); + DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputFile) + .at(inputFile.selectLine(1)) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .remediationEffortMinutes(10l) + .severity(Severity.BLOCKER); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Type is mandatory"); + issue.save(); + } + + @Test + public void fail_to_store_if_primary_location_is_not_a_file() { + SensorStorage storage = mock(SensorStorage.class); + DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) + .at(new DefaultIssueLocation() + .on(mock(InputComponent.class)) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .remediationEffortMinutes(10l) + .severity(Severity.BLOCKER); + + exception.expect(IllegalStateException.class); + exception.expectMessage("External issues must be located in files"); + issue.save(); + } + + @Test + public void fail_to_store_if_primary_location_has_no_message() { + SensorStorage storage = mock(SensorStorage.class); + DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputFile) + .at(inputFile.selectLine(1))) + .forRule(RuleKey.of("repo", "rule")) + .remediationEffortMinutes(10l) + .type(RuleType.BUG) + .severity(Severity.BLOCKER); + + exception.expect(IllegalStateException.class); + exception.expectMessage("External issues must have a message"); + issue.save(); + } + + @Test + public void fail_to_store_if_no_severity() { + SensorStorage storage = mock(SensorStorage.class); + DefaultExternalIssue issue = new DefaultExternalIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputFile) + .at(inputFile.selectLine(1)) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .remediationEffortMinutes(10l) + .type(RuleType.BUG); + + exception.expect(IllegalStateException.class); + exception.expectMessage("Severity is mandatory"); + issue.save(); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java new file mode 100644 index 00000000000..712703976c2 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java @@ -0,0 +1,126 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.util.Collection; +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.TextRange; +import org.sonar.api.batch.fs.internal.DefaultTextPointer; +import org.sonar.api.batch.fs.internal.DefaultTextRange; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.sonar.api.batch.sensor.highlighting.TypeOfText.COMMENT; +import static org.sonar.api.batch.sensor.highlighting.TypeOfText.CPP_DOC; +import static org.sonar.api.batch.sensor.highlighting.TypeOfText.KEYWORD; + +public class DefaultHighlightingTest { + + private static final InputFile INPUT_FILE = new TestInputFileBuilder("foo", "src/Foo.java") + .setLines(2) + .setOriginalLineStartOffsets(new int[] {0, 50}) + .setOriginalLineEndOffsets(new int[] {49, 100}) + .setLastValidOffset(101) + .build(); + + private Collection highlightingRules; + + @Rule + public ExpectedException throwable = ExpectedException.none(); + + @Before + public void setUpSampleRules() { + + DefaultHighlighting highlightingDataBuilder = new DefaultHighlighting(mock(SensorStorage.class)) + .onFile(INPUT_FILE) + .highlight(0, 10, COMMENT) + .highlight(1, 10, 1, 12, KEYWORD) + .highlight(24, 38, KEYWORD) + .highlight(42, 50, KEYWORD) + .highlight(24, 65, CPP_DOC) + .highlight(12, 20, COMMENT); + + highlightingDataBuilder.save(); + + highlightingRules = highlightingDataBuilder.getSyntaxHighlightingRuleSet(); + } + + @Test + public void should_register_highlighting_rule() { + assertThat(highlightingRules).hasSize(6); + } + + private static TextRange rangeOf(int startLine, int startOffset, int endLine, int endOffset) { + return new DefaultTextRange(new DefaultTextPointer(startLine, startOffset), new DefaultTextPointer(endLine, endOffset)); + } + + @Test + public void should_order_by_start_then_end_offset() { + assertThat(highlightingRules).extracting("range", TextRange.class).containsExactly( + rangeOf(1, 0, 1, 10), + rangeOf(1, 10, 1, 12), + rangeOf(1, 12, 1, 20), + rangeOf(1, 24, 2, 15), + rangeOf(1, 24, 1, 38), + rangeOf(1, 42, 2, 0)); + assertThat(highlightingRules).extracting("textType").containsExactly(COMMENT, KEYWORD, COMMENT, CPP_DOC, KEYWORD, KEYWORD); + } + + @Test + public void should_support_overlapping() { + new DefaultHighlighting(mock(SensorStorage.class)) + .onFile(INPUT_FILE) + .highlight(0, 15, KEYWORD) + .highlight(8, 12, CPP_DOC) + .save(); + } + + @Test + public void should_prevent_start_equal_end() { + throwable.expect(IllegalArgumentException.class); + throwable + .expectMessage("Unable to highlight file"); + + new DefaultHighlighting(mock(SensorStorage.class)) + .onFile(INPUT_FILE) + .highlight(10, 10, KEYWORD) + .save(); + } + + @Test + public void should_prevent_boudaries_overlapping() { + throwable.expect(IllegalStateException.class); + throwable + .expectMessage("Cannot register highlighting rule for characters at Range[from [line=1, lineOffset=8] to [line=1, lineOffset=15]] as it overlaps at least one existing rule"); + + new DefaultHighlighting(mock(SensorStorage.class)) + .onFile(INPUT_FILE) + .highlight(0, 10, KEYWORD) + .highlight(8, 15, KEYWORD) + .save(); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java new file mode 100644 index 00000000000..96bd5936b6b --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java @@ -0,0 +1,107 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import org.apache.commons.lang.StringUtils; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.rules.ExpectedException.none; + +public class DefaultIssueLocationTest { + + @Rule + public ExpectedException thrown = none(); + + private InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("Foo\nBar\n") + .build(); + + @Test + public void should_build() { + assertThat(new DefaultIssueLocation() + .on(inputFile) + .message("pipo bimbo") + .message() + ).isEqualTo("pipo bimbo"); + } + + @Test + public void not_allowed_to_call_on_twice() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("on() already called"); + new DefaultIssueLocation() + .on(inputFile) + .on(inputFile) + .message("Wrong way!"); + } + + @Test + public void prevent_too_long_messages() { + assertThat(new DefaultIssueLocation() + .on(inputFile) + .message(StringUtils.repeat("a", 4000)).message()).hasSize(4000); + + assertThat(new DefaultIssueLocation() + .on(inputFile) + .message(StringUtils.repeat("a", 4001)).message()).hasSize(4000); + } + + @Test + public void prevent_null_character_in_message_text() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Character \\u0000 is not supported in issue message"); + + new DefaultIssueLocation() + .message("pipo " + '\u0000' + " bimbo"); + } + + @Test + public void prevent_null_character_in_message_text_when_builder_has_been_initialized() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(customMatcher("Character \\u0000 is not supported in issue message", ", on component: src/Foo.php")); + + new DefaultIssueLocation() + .on(inputFile) + .message("pipo " + '\u0000' + " bimbo"); + } + + private Matcher customMatcher(String startWith, String endWith) { + return new TypeSafeMatcher() { + @Override + public void describeTo(Description description) { + description.appendText("Invalid message"); + } + + @Override + protected boolean matchesSafely(final String item) { + return item.startsWith(startWith) && item.endsWith(endWith); + } + }; + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java new file mode 100644 index 00000000000..0ab0b99655b --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java @@ -0,0 +1,157 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.io.File; +import java.io.IOException; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.internal.DefaultInputDir; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.rule.RuleKey; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultIssueTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private DefaultInputProject project; + + private DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("Foo\nBar\n") + .build(); + + @Before + public void prepare() throws IOException { + project = new DefaultInputProject(ProjectDefinition.create() + .setKey("foo") + .setBaseDir(temp.newFolder()) + .setWorkDir(temp.newFolder())); + } + + @Test + public void build_file_issue() { + SensorStorage storage = mock(SensorStorage.class); + DefaultIssue issue = new DefaultIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputFile) + .at(inputFile.selectLine(1)) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .gap(10.0); + + assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputFile); + assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); + assertThat(issue.primaryLocation().textRange().start().line()).isEqualTo(1); + assertThat(issue.gap()).isEqualTo(10.0); + assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); + + issue.save(); + + verify(storage).store(issue); + } + + @Test + public void move_directory_issue_to_project_root() { + SensorStorage storage = mock(SensorStorage.class); + DefaultIssue issue = new DefaultIssue(project, storage) + .at(new DefaultIssueLocation() + .on(new DefaultInputDir("foo", "src/main").setModuleBaseDir(project.getBaseDir())) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .overrideSeverity(Severity.BLOCKER); + + assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); + assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); + assertThat(issue.primaryLocation().textRange()).isNull(); + assertThat(issue.primaryLocation().message()).isEqualTo("[src/main] Wrong way!"); + assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); + + issue.save(); + + verify(storage).store(issue); + } + + @Test + public void move_submodule_issue_to_project_root() { + File subModuleDirectory = new File(project.getBaseDir().toString(), "bar"); + subModuleDirectory.mkdir(); + + ProjectDefinition subModuleDefinition = ProjectDefinition.create() + .setKey("foo/bar") + .setBaseDir(subModuleDirectory) + .setWorkDir(subModuleDirectory); + project.definition().addSubProject(subModuleDefinition); + DefaultInputModule subModule = new DefaultInputModule(subModuleDefinition); + + SensorStorage storage = mock(SensorStorage.class); + DefaultIssue issue = new DefaultIssue(project, storage) + .at(new DefaultIssueLocation() + .on(subModule) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .overrideSeverity(Severity.BLOCKER); + + assertThat(issue.primaryLocation().inputComponent()).isEqualTo(project); + assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); + assertThat(issue.primaryLocation().textRange()).isNull(); + assertThat(issue.primaryLocation().message()).isEqualTo("[bar] Wrong way!"); + assertThat(issue.overriddenSeverity()).isEqualTo(Severity.BLOCKER); + + issue.save(); + + verify(storage).store(issue); + } + + @Test + public void build_project_issue() throws IOException { + SensorStorage storage = mock(SensorStorage.class); + DefaultInputModule inputModule = new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); + DefaultIssue issue = new DefaultIssue(project, storage) + .at(new DefaultIssueLocation() + .on(inputModule) + .message("Wrong way!")) + .forRule(RuleKey.of("repo", "rule")) + .gap(10.0); + + assertThat(issue.primaryLocation().inputComponent()).isEqualTo(inputModule); + assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule")); + assertThat(issue.primaryLocation().textRange()).isNull(); + assertThat(issue.gap()).isEqualTo(10.0); + assertThat(issue.primaryLocation().message()).isEqualTo("Wrong way!"); + + issue.save(); + + verify(storage).store(issue); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java new file mode 100644 index 00000000000..43844837e1e --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java @@ -0,0 +1,92 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.io.IOException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; +import org.sonar.api.batch.fs.internal.DefaultInputProject; +import org.sonar.api.batch.sensor.internal.SensorStorage; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.scanner.fs.TestInputFileBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class DefaultMeasureTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void build_file_measure() { + SensorStorage storage = mock(SensorStorage.class); + DefaultMeasure newMeasure = new DefaultMeasure(storage) + .forMetric(CoreMetrics.LINES) + .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) + .withValue(3); + + assertThat(newMeasure.inputComponent()).isEqualTo(new TestInputFileBuilder("foo", "src/Foo.php").build()); + assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES); + assertThat(newMeasure.value()).isEqualTo(3); + + newMeasure.save(); + + verify(storage).store(newMeasure); + } + + @Test + public void build_project_measure() throws IOException { + SensorStorage storage = mock(SensorStorage.class); + AbstractProjectOrModule module = new DefaultInputProject(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder())); + DefaultMeasure newMeasure = new DefaultMeasure(storage) + .forMetric(CoreMetrics.LINES) + .on(module) + .withValue(3); + + assertThat(newMeasure.inputComponent()).isEqualTo(module); + assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES); + assertThat(newMeasure.value()).isEqualTo(3); + + newMeasure.save(); + + verify(storage).store(newMeasure); + } + + @Test + public void not_allowed_to_call_on_twice() throws IOException { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("on() already called"); + new DefaultMeasure() + .on(new DefaultInputProject(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))) + .on(new TestInputFileBuilder("foo", "src/Foo.php").build()) + .withValue(3) + .save(); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorDescriptorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorDescriptorTest.java new file mode 100644 index 00000000000..a43272ba20d --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorDescriptorTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import org.junit.Test; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.config.internal.MapSettings; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultSensorDescriptorTest { + + @Test + public void describe() { + DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor(); + descriptor + .name("Foo") + .onlyOnLanguage("java") + .onlyOnFileType(InputFile.Type.MAIN) + .requireProperty("sonar.foo.reportPath", "sonar.foo.reportPath2") + .createIssuesForRuleRepository("squid-java"); + + assertThat(descriptor.name()).isEqualTo("Foo"); + assertThat(descriptor.languages()).containsOnly("java"); + assertThat(descriptor.type()).isEqualTo(InputFile.Type.MAIN); + MapSettings settings = new MapSettings(); + settings.setProperty("sonar.foo.reportPath", "foo"); + assertThat(descriptor.configurationPredicate().test(settings.asConfig())).isFalse(); + settings.setProperty("sonar.foo.reportPath2", "foo"); + assertThat(descriptor.configurationPredicate().test(settings.asConfig())).isTrue(); + assertThat(descriptor.ruleRepositories()).containsOnly("squid-java"); + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java index bdefb6f3436..d0aca624090 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java @@ -33,11 +33,9 @@ import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode; import org.sonar.api.batch.sensor.highlighting.TypeOfText; -import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.issue.ExternalIssue; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; @@ -45,6 +43,7 @@ import org.sonar.api.config.internal.MapSettings; import org.sonar.api.measures.CoreMetrics; import org.sonar.core.metric.ScannerMetrics; import org.sonar.scanner.cpd.index.SonarCpdBlockIndex; +import org.sonar.scanner.fs.TestInputFileBuilder; import org.sonar.scanner.issue.IssuePublisher; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReport; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/InMemorySensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/InMemorySensorStorageTest.java new file mode 100644 index 00000000000..76e4874a41a --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/InMemorySensorStorageTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.MapEntry.entry; + +public class InMemorySensorStorageTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + InMemorySensorStorage underTest = new InMemorySensorStorage(); + + @Test + public void test_storeProperty() { + assertThat(underTest.contextProperties).isEmpty(); + + underTest.storeProperty("foo", "bar"); + assertThat(underTest.contextProperties).containsOnly(entry("foo", "bar")); + } + + @Test + public void storeProperty_throws_IAE_if_key_is_null() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Key of context property must not be null"); + + underTest.storeProperty(null, "bar"); + } + + @Test + public void storeProperty_throws_IAE_if_value_is_null() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Value of context property must not be null"); + + underTest.storeProperty("foo", null); + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java index f64ba90b3f1..01d3b6046e8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java @@ -19,25 +19,25 @@ */ package org.sonar.scanner.sensor; -import org.sonar.api.SonarEdition; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.scanner.rule.ActiveRulesBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.Version; +import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.rule.ActiveRulesBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java index 2a31dae65cc..0a78c6b2984 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java @@ -25,14 +25,13 @@ 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.TestInputFileBuilder; import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.scanner.rule.ActiveRulesBuilder; -import org.sonar.scanner.rule.NewActiveRule; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.rule.RuleKey; +import org.sonar.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.scanner.rule.ActiveRulesBuilder; +import org.sonar.scanner.rule.NewActiveRule; import static org.assertj.core.api.Assertions.assertThat; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java new file mode 100644 index 00000000000..cf1d452f76a --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java @@ -0,0 +1,375 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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; + +import java.io.File; +import java.io.IOException; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.InputFile; +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.scanner.fs.DefaultFileSystem; +import org.sonar.scanner.fs.TestInputFileBuilder; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.Severity; +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.NewExternalIssue; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.batch.sensor.symbol.NewSymbolTable; +import org.sonar.api.config.Settings; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rules.RuleType; +import org.sonar.scanner.rule.ActiveRulesBuilder; +import org.sonar.scanner.rule.NewActiveRule; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.assertj.core.data.MapEntry.entry; + +public class SensorContextTesterTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException exception = ExpectedException.none(); + + private SensorContextTester tester; + private File baseDir; + + @Before + public void prepare() throws Exception { + baseDir = temp.newFolder(); + tester = SensorContextTester.create(baseDir); + } + + @Test + public void testSettings() { + Settings settings = new MapSettings(); + settings.setProperty("foo", "bar"); + tester.setSettings(settings); + assertThat(tester.settings().getString("foo")).isEqualTo("bar"); + } + + @Test + public void testActiveRules() { + NewActiveRule activeRule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("foo", "bar")) + .build(); + ActiveRules activeRules = new ActiveRulesBuilder().addRule(activeRule).build(); + tester.setActiveRules(activeRules); + assertThat(tester.activeRules().findAll()).hasSize(1); + } + + @Test + public void testFs() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder()); + tester.setFileSystem(fs); + assertThat(tester.fileSystem().baseDir()).isNotEqualTo(baseDir); + } + + @Test + public void testIssues() { + assertThat(tester.allIssues()).isEmpty(); + NewIssue newIssue = tester.newIssue(); + newIssue + .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) + .forRule(RuleKey.of("repo", "rule")) + .save(); + newIssue = tester.newIssue(); + newIssue + .at(newIssue.newLocation().on(new TestInputFileBuilder("foo", "src/Foo.java").build())) + .forRule(RuleKey.of("repo", "rule")) + .save(); + assertThat(tester.allIssues()).hasSize(2); + } + + @Test + public void testExternalIssues() { + assertThat(tester.allExternalIssues()).isEmpty(); + NewExternalIssue newExternalIssue = tester.newExternalIssue(); + newExternalIssue + .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build())) + .forRule(RuleKey.of("repo", "rule")) + .type(RuleType.BUG) + .severity(Severity.BLOCKER) + .save(); + newExternalIssue = tester.newExternalIssue(); + newExternalIssue + .at(newExternalIssue.newLocation().message("message").on(new TestInputFileBuilder("foo", "src/Foo.java").build())) + .type(RuleType.BUG) + .severity(Severity.BLOCKER) + .forRule(RuleKey.of("repo", "rule")) + .save(); + assertThat(tester.allExternalIssues()).hasSize(2); + } + + @Test + public void testAnalysisErrors() { + assertThat(tester.allAnalysisErrors()).isEmpty(); + NewAnalysisError newAnalysisError = tester.newAnalysisError(); + + InputFile file = new TestInputFileBuilder("foo", "src/Foo.java").build(); + 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() throws IOException { + assertThat(tester.measures("foo:src/Foo.java")).isEmpty(); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull(); + tester.newMeasure() + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) + .forMetric(CoreMetrics.NCLOC) + .withValue(2) + .save(); + assertThat(tester.measures("foo:src/Foo.java")).hasSize(1); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); + tester.newMeasure() + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) + .forMetric(CoreMetrics.LINES) + .withValue(4) + .save(); + assertThat(tester.measures("foo:src/Foo.java")).hasSize(2); + assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull(); + assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull(); + tester.newMeasure() + .on(new DefaultInputModule(ProjectDefinition.create().setKey("foo").setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder()))) + .forMetric(CoreMetrics.DIRECTORIES) + .withValue(4) + .save(); + assertThat(tester.measures("foo")).hasSize(1); + assertThat(tester.measure("foo", "directories")).isNotNull(); + } + + @Test(expected = IllegalStateException.class) + public void duplicateMeasures() { + tester.newMeasure() + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) + .forMetric(CoreMetrics.NCLOC) + .withValue(2) + .save(); + tester.newMeasure() + .on(new TestInputFileBuilder("foo", "src/Foo.java").build()) + .forMetric(CoreMetrics.NCLOC) + .withValue(2) + .save(); + } + + @Test + public void testHighlighting() { + assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).isEmpty(); + tester.newHighlighting() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) + .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) + .highlight(8, 10, TypeOfText.CONSTANT) + .highlight(9, 10, TypeOfText.COMMENT) + .save(); + assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 3)).containsExactly(TypeOfText.ANNOTATION); + assertThat(tester.highlightingTypeAt("foo:src/Foo.java", 1, 9)).containsExactly(TypeOfText.CONSTANT, TypeOfText.COMMENT); + } + + @Test(expected = UnsupportedOperationException.class) + public void duplicateHighlighting() { + tester.newHighlighting() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) + .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) + .save(); + tester.newHighlighting() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) + .highlight(1, 0, 1, 5, TypeOfText.ANNOTATION) + .save(); + } + + @Test + public void testSymbolReferences() { + assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull(); + + NewSymbolTable symbolTable = tester.newSymbolTable() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); + symbolTable + .newSymbol(1, 8, 1, 10); + + symbolTable + .newSymbol(1, 1, 1, 5) + .newReference(6, 9) + .newReference(1, 10, 1, 13); + + symbolTable.save(); + + assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 0)).isNull(); + assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 8)).isEmpty(); + assertThat(tester.referencesForSymbolAt("foo:src/Foo.java", 1, 3)).extracting("start.line", "start.lineOffset", "end.line", "end.lineOffset").containsExactly(tuple(1, 6, 1, 9), + tuple(1, 10, 1, 13)); + } + + @Test(expected = UnsupportedOperationException.class) + public void duplicateSymbolReferences() { + NewSymbolTable symbolTable = tester.newSymbolTable() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); + symbolTable + .newSymbol(1, 8, 1, 10); + + symbolTable.save(); + + symbolTable = tester.newSymbolTable() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()); + symbolTable + .newSymbol(1, 8, 1, 10); + + symbolTable.save(); + } + + @Test + public void testCoverageAtLineZero() { + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); + + exception.expect(IllegalStateException.class); + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) + .lineHits(0, 3); + } + + @Test + public void testCoverageAtLineOutOfRange() { + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); + exception.expect(IllegalStateException.class); + + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar").build()) + .lineHits(4, 3); + } + + @Test + public void testLineHits() { + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.lineHits("foo:src/Foo.java", 4)).isNull(); + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) + .lineHits(1, 2) + .lineHits(2, 3) + .save(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(2); + assertThat(tester.lineHits("foo:src/Foo.java", 2)).isEqualTo(3); + } + + public void multipleCoverage() { + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) + .lineHits(1, 2) + .conditions(3, 4, 2) + .save(); + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java").initMetadata("annot dsf fds foo bar\nasdas").build()) + .lineHits(1, 2) + .conditions(3, 4, 3) + .save(); + assertThat(tester.lineHits("foo:src/Foo.java", 1)).isEqualTo(4); + assertThat(tester.conditions("foo:src/Foo.java", 3)).isEqualTo(4); + assertThat(tester.coveredConditions("foo:src/Foo.java", 3)).isEqualTo(3); + } + + @Test + public void testConditions() { + assertThat(tester.conditions("foo:src/Foo.java", 1)).isNull(); + assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isNull(); + tester.newCoverage() + .onFile(new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("annot dsf fds foo bar\nasd\nasdas\nasdfas") + .build()) + .conditions(1, 4, 2) + .save(); + assertThat(tester.conditions("foo:src/Foo.java", 1)).isEqualTo(4); + assertThat(tester.coveredConditions("foo:src/Foo.java", 1)).isEqualTo(2); + } + + @Test + public void testCpdTokens() { + assertThat(tester.cpdTokens("foo:src/Foo.java")).isNull(); + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("public class Foo {\n\n}") + .build(); + tester.newCpdTokens() + .onFile(inputFile) + .addToken(inputFile.newRange(0, 6), "public") + .addToken(inputFile.newRange(7, 12), "class") + .addToken(inputFile.newRange(13, 16), "$IDENTIFIER") + .addToken(inputFile.newRange(17, 18), "{") + .addToken(inputFile.newRange(3, 0, 3, 1), "}") + .save(); + assertThat(tester.cpdTokens("foo:src/Foo.java")).extracting("value", "startLine", "startUnit", "endUnit") + .containsExactly( + tuple("publicclass$IDENTIFIER{", 1, 1, 4), + tuple("}", 3, 5, 5)); + } + + @Test(expected = UnsupportedOperationException.class) + public void duplicateCpdTokens() { + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .initMetadata("public class Foo {\n\n}") + .build(); + tester.newCpdTokens() + .onFile(inputFile) + .addToken(inputFile.newRange(0, 6), "public") + .save(); + + tester.newCpdTokens() + .onFile(inputFile) + .addToken(inputFile.newRange(0, 6), "public") + .save(); + } + + @Test + public void testCancellation() { + assertThat(tester.isCancelled()).isFalse(); + tester.setCancelled(true); + assertThat(tester.isCancelled()).isTrue(); + } + + @Test + public void testContextProperties() { + assertThat(tester.getContextProperties()).isEmpty(); + + tester.addContextProperty("foo", "bar"); + assertThat(tester.getContextProperties()).containsOnly(entry("foo", "bar")); + } +} diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scanner/fs/glyphicons-halflings-regular.woff b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/fs/glyphicons-halflings-regular.woff new file mode 100644 index 00000000000..2cc3e4852a5 Binary files /dev/null and b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/fs/glyphicons-halflings-regular.woff differ