]> source.dussan.org Git - sonarqube.git/commitdiff
Extract implementation from plugin API - fix tests
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 4 Jun 2019 20:43:44 +0000 (15:43 -0500)
committerSonarTech <sonartech@sonarsource.com>
Fri, 12 Jul 2019 18:21:13 +0000 (20:21 +0200)
126 files changed:
plugins/sonar-xoo-plugin/build.gradle
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/ItCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/OverallCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/coverage/UtCoverageSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/extensions/XooPostJobTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/CpdTokenizerSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SignificantCodeSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SymbolReferencesSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/SyntaxHighlightingSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java
sonar-plugin-api/build.gradle
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/SyntaxHighlightingRule.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/AndPredicateTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFilePredicatesTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileExtensionPredicateTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FilenamePredicateTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/OrPredicateTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/RelativePathPredicateTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/TestInputFileBuilderTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/charhandler/IntArrayListTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/DefaultRulesTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/RulesBuilderTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCodeTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisErrorTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlightingTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptorTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorageTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssueTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocationTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRuleTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTableTest.java
sonar-plugin-api/src/test/java/org/sonar/api/issue/NoSonarFilterTest.java
sonar-plugin-api/src/test/resources/org/sonar/api/batch/fs/internal/glyphicons-halflings-regular.woff [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/AbstractProjectOrModule.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultFileSystem.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultIndexedFile.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputComponent.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputDir.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/DefaultInputFile.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/PathPattern.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/TestInputFileBuilder.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/DefaultFilePredicates.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/fs/predicates/PathPatternPredicate.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobOptimizer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobWrapper.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultHighlighting.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SyntaxHighlightingRule.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ModuleSensorExtensionDictionnaryTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/PostJobExtensionDictionnaryTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/JavaCpdBlockIndexerSensorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/ExternalIssueImporterTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/DefaultFileSystemTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/FileMetadataTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/charhandler/IntArrayListTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/AndPredicateTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/DefaultFilePredicatesTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FileExtensionPredicateTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/FilenamePredicateTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/OrPredicateTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/fs/predicates/RelativePathPredicateTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/EnforceIssuesFilterTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleCoverageAndDuplicationExclusionsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ModuleSensorsExecutorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/ProjectCoverageExclusionsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ChangedLinesPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/ActiveRulesBuilderTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/DefaultRulesTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/NewActiveRuleTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/RulesBuilderTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputComponentStoreTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultAdHocRuleTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultExternalIssueTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultHighlightingTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueLocationTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultIssueTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultMeasureTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorDescriptorTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/InMemorySensorStorageTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorOptimizerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorContextTesterTest.java [new file with mode: 0644]
sonar-scanner-engine/src/test/resources/org/sonar/scanner/fs/glyphicons-halflings-regular.woff [new file with mode: 0644]

index 693f0cb1363c571e185d46070f805bc12972a304..d9236cf050b399e2c08776776a765cf50e8b5d0e 100644 (file)
@@ -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'
index dd4ebcaa1d092cad3605389146d93a126571c80e..1f5128ddc7985dacc576c1faaa4b845207202d47 100644 (file)
@@ -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;
 
index 7d453c9ae4018e47a5550ffce89c581023babecd..a6c8878084001700aba7064564860b7b0f4b82ff 100644 (file)
@@ -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;
 
index cf9023c9cf743c13f569287ed0d782b985686cc8..429a64722fdfa4db24bb9a669129d82d1ecf5e0b 100644 (file)
@@ -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;
 
index 7af90432a97510d4458cf4dc1c434786852ffd2b..5474f266af63059ffe46c1ff832dd8b0ba84fc59 100644 (file)
  */
 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;
index 1eb4fd88650898236f1ba1a7d418e8ea6006c834..1464eaa8e626553dbd3c744f1a36afe98aa7d223 100644 (file)
@@ -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;
index 7ed38d42e0ec80005726c7e24c7ed98cdb3110f9..5d36dcf4097ad862a5dff59a4bdb260fd553213e 100644 (file)
@@ -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;
index 03adee97ed379980e0c99503dac9bcdadc6361cd..5293d3128cfd83ddf2a0beac2b4c95e234859dc6 100644 (file)
@@ -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;
 
index 98d57b104e3eecaf96b0cf03227bee5d7665d357..2093e773d49c7075e0357a02e26056ab9687cf19 100644 (file)
@@ -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;
index a729d4bf9f97f667bfbb676bd7e7a512ce500947..965d4d653e415c40fbbd6f6ed495c794d78c3473 100644 (file)
@@ -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;
 
index 647e411cae50bdf484d70f32b932ea60106f1964..c5aa5d4534c8bb06216c74515714bf1a5ad6da3c 100644 (file)
@@ -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;
 
index ab8a6ddafea18280cdb97726467331741f45cd61..1d6c610ca49df7ef0af80b76572ebb0b0be1652c 100644 (file)
@@ -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;
index 9f9a1a22b0e778a7d0b317fbeb4d6b1654788216..ef30ede34f02a2e04ad3a90061b15f9b739430f5 100644 (file)
@@ -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;
index 3c2b3d3a0da992858051b3a4a4457698cf45cef2..1475a50d80081200fc292d59fca158033251f744 100644 (file)
@@ -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 {
index ba7cb94cff3cb071a17d6d3627a1a2d7a34f3c8e..229280fca5b2518df0907c19f8925abc0f579c90 100644 (file)
@@ -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 (file)
index 3280c38..0000000
+++ /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 (file)
index 89dea63..0000000
+++ /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<SyntaxHighlightingRule> syntaxHighlightingRules;
-  private DefaultInputFile inputFile;
-
-  public DefaultHighlighting(SensorStorage storage) {
-    super(storage);
-    syntaxHighlightingRules = new ArrayList<>();
-  }
-
-  public List<SyntaxHighlightingRule> getSyntaxHighlightingRuleSet() {
-    return syntaxHighlightingRules;
-  }
-
-  private void checkOverlappingBoundaries() {
-    if (syntaxHighlightingRules.size() > 1) {
-      Iterator<SyntaxHighlightingRule> 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 (file)
index 22934dc..0000000
+++ /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 (file)
index 7c52766..0000000
+++ /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;
index 2bfe79bfba84898de9fca0ffaaa1690c24773f3b..fde8e22e5ac6948632bd9eff6d0c6e807709c76d 100644 (file)
  */
 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
index f104d0cef649bab4f3364f9ea6dd564e64f3e00d..bb155753d5523523a5cc275477609b7509d84c4d 100644 (file)
 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 (file)
index e82241b..0000000
+++ /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.<FilePredicate>asList(pathPatternPredicate1,
-      AndPredicate.create(Arrays.<FilePredicate>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.<FilePredicate>asList(pathPatternPredicate1,
-      relativePathPredicate, pathPatternPredicate2));
-    assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(relativePathPredicate, pathPatternPredicate1, pathPatternPredicate2);
-  }
-
-  @Test
-  public void simplifyAndExpressionsWhenEmpty() {
-    FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>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.<FilePredicate>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.<FilePredicate>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 (file)
index 6d04f5d..0000000
+++ /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.<String>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.<FilePredicate>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.<FilePredicate>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 (file)
index f19cb24..0000000
+++ /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();
-  }
-}
index 420f433557b5c5ef1630310a18d99d13618a38df..85feccc8581b14f8ed43ed4263eba76ef2587820 100644 (file)
@@ -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 (file)
index a4b187b..0000000
+++ /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 (file)
index 913166d..0000000
+++ /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 (file)
index d0dc4c3..0000000
+++ /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 (file)
index 2592bee..0000000
+++ /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 (file)
index 50bcba8..0000000
+++ /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();
-  }
-}
index 376536e6b7bf72d27f20ad03c52f5b9ebaef38ec..3055be6a41993585bf51a4e07ff8c310657eb6bc 100644 (file)
@@ -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 (file)
index 91d54fa..0000000
+++ /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);
-  }
-
-}
index 60136eec67ae6c555d1dd2b3240e43f015ab72a1..5a728e95faab887597747471e36f9ca59fbbeb61 100644 (file)
@@ -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 (file)
index f5abaf1..0000000
+++ /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 (file)
index 8ca9b7d..0000000
+++ /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<NewRule> 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<NewRule> 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<NewRule> 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 (file)
index 324b191..0000000
+++ /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 (file)
index 9473b04..0000000
+++ /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");
-  }
-}
index e23ccc355ffee86bf83f162853089178fc552d46..5d853e456eac5279359b9708b74c09ad43a57deb 100644 (file)
@@ -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;
 
index 8320cea7544fc47ddfb900a53ff7b6546744ceb7..1adb0c71e5420011b880778b91c77e7928277acd 100644 (file)
@@ -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;
index 2e5e5104489c5f94d6a332a95ecd0d26b70f10fe..ae920c967fed9d85d7b3e021bf70d9736eed7e28 100644 (file)
@@ -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 (file)
index 42cc0e4..0000000
+++ /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<SyntaxHighlightingRule> 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 (file)
index 25a1088..0000000
+++ /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 (file)
index fe3ce41..0000000
+++ /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 (file)
index 493d713..0000000
+++ /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.<Integer>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.<Integer>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.<Integer>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.<Integer>newMeasure()
-      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
-      .forMetric(CoreMetrics.NCLOC)
-      .withValue(2)
-      .save();
-    tester.<Integer>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 (file)
index a2d07c7..0000000
+++ /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 (file)
index 66b5369..0000000
+++ /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<String> customMatcher(String startWith, String endWith) {
-    return new TypeSafeMatcher<String>() {
-      @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 (file)
index 9fc6598..0000000
+++ /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 (file)
index f6133e9..0000000
+++ /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<Integer> newMeasure = new DefaultMeasure<Integer>(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<Integer> newMeasure = new DefaultMeasure<Integer>(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<Integer>()
-      .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 (file)
index 332542f..0000000
+++ /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
index 8f98a84ecfe77028e7f58cde06e509e5bdfcfe4e..c880f7f0bd91a62249312e9ade1c3251e0753be4 100644 (file)
@@ -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;
index b28f70876fd521349f0d1928da345357894bcd9a..76ac2f6758ad724a01129fa60e4071ce602f5fb0 100644 (file)
@@ -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 (file)
index 2cc3e48..0000000
Binary files a/sonar-plugin-api/src/test/resources/org/sonar/api/batch/fs/internal/glyphicons-halflings-regular.woff and /dev/null differ
index 9fc2d130f4a99abee04877f384af45096ea49fd0..d458edd0ca92ed5683c9b813c2173bfebd7f9b29 100644 (file)
@@ -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;
 
index 1c1729634e12dc508427983f6cbf64352b624110..de882ad0c54f85181dc2e0bc930347f7c8067672 100644 (file)
@@ -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 (file)
index a3d0602..0000000
+++ /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 (file)
index 11601e0..0000000
+++ /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<String> 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 (file)
index 13eb77b..0000000
+++ /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 (file)
index f29f11d..0000000
+++ /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<DefaultInputFile> 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<int[]> ignoreIssuesOnlineRanges;
-  private BitSet executableLines;
-
-  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator) {
-    this(indexedFile, metadataGenerator, null);
-  }
-
-  // For testing
-  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> 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<Integer> 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<int[]> 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<Integer> 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<Set<Integer>> 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 (file)
index 5d5947d..0000000
+++ /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, "."));
-  }
-}
index 5d6e8b9bc9c2cc99e189da55bf86807841b0a2e4..eee66064b29fe5b9be1e6f2c73d38822cc117fb8 100644 (file)
@@ -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)
index 60bb37e989654b885c7123ca8d52119917b9cdad..bcda1ac73519bcfe25258e0dee81e10bafe8acb1 100644 (file)
@@ -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}
index 0fdabcbcd3119097ab99b219f01e0aeb391520dc..032d820919bb5b4e3473551e59fdfa73eb1b2d7d 100644 (file)
@@ -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
index c3c23969ac61fc979d0106bdb1294abaa005ab76..1292e10612fe3229b82db0fc925bc276b4b4c02f 100644 (file)
@@ -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;
index dda587711a30119dc931a02bb1a9f372c0e9454a..cd68e1694feddb4d92e5e56ddc062cbb5a4be85f 100644 (file)
@@ -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 {
index 408ad6385c0a14c88e4bef0896aa104105c5b553..60ea28821632395c9fa686061adbb996d0d0dd20 100644 (file)
@@ -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 (file)
index 0000000..42129a2
--- /dev/null
@@ -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<SyntaxHighlightingRule> syntaxHighlightingRules;
+  private DefaultInputFile inputFile;
+
+  public DefaultHighlighting(SensorStorage storage) {
+    super(storage);
+    syntaxHighlightingRules = new ArrayList<>();
+  }
+
+  public List<SyntaxHighlightingRule> getSyntaxHighlightingRuleSet() {
+    return syntaxHighlightingRules;
+  }
+
+  private void checkOverlappingBoundaries() {
+    if (syntaxHighlightingRules.size() > 1) {
+      Iterator<SyntaxHighlightingRule> 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");
+  }
+}
index 415a884380b2c9f6d8b4e8034446f6ffd4b96d26..b9ca180c5983d8987aea8d376522356007e15b34 100644 (file)
@@ -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)) {
index 887f1d02c66cc8de1f1e1998676039140cf89bb3..45933fe1730225b4938129196ebee1af52ddc933 100644 (file)
@@ -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<AdHocRule> allAdHocRules = new ArrayList<>();
   Collection<AnalysisError> allAnalysisErrors = new ArrayList<>();
 
-  Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
+  Map<String, NewHighlighting> highlightingByComponent = new HashMap<>();
   Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>();
   Map<String, List<DefaultCoverage>> coverageByComponent = new HashMap<>();
   Map<String, DefaultSymbolTable> 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)) {
index 21e6d2b8f70a15ae05df724586bb367d6e0af4b2..42e8559e83b0d277f69ebe255a30eb559e0bf7da 100644 (file)
@@ -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;
index 26777fc0a9936c114b6440b3650d36522929cb11..785920220ff15713c56f9811dc71f23f8089ec42 100644 (file)
@@ -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<TypeOfText> 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 (file)
index 0000000..cded69e
--- /dev/null
@@ -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);
+  }
+}
index 19ce32d686cb7ce583f35c5de66514cdeb8824a0..d60f344a516f05ba5bc2a1c8e77e21f3896900e0 100644 (file)
@@ -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;
index 4d63704cae061dac9099d8929d584e8bc23c4214..2c4ed265b275dc7ffa71f992101714d2716141f1 100644 (file)
@@ -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;
index 15cf84a2a18407619ba35ca385166dd60f8fecc3..ed35ee1943d9ff4029e801ccea3b5df87aa84c3e 100644 (file)
@@ -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;
index 3e10ad5dad3cf12563eaf82e0c00c5e4d216e34d..ecc155cd5e54c597ab5ab943795140f7f064b224 100644 (file)
@@ -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;
index 7a0a2f21695cbd23e0cc5db3c9f3472029fc858d..3d7c748603421ce37fdffc97f397f73ae8eac8f0 100644 (file)
@@ -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;
index 155e08b98c4a9dfc5f32c53f7ba36c8e438e5827..596a25f9275354093d3e539036d4f7e7d77495c2 100644 (file)
@@ -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 (file)
index 0000000..74a43db
--- /dev/null
@@ -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 (file)
index 0000000..826edf9
--- /dev/null
@@ -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 (file)
index 0000000..048a030
--- /dev/null
@@ -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 (file)
index 0000000..d3ec2aa
--- /dev/null
@@ -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.<FilePredicate>asList(pathPatternPredicate1,
+      AndPredicate.create(Arrays.<FilePredicate>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.<FilePredicate>asList(pathPatternPredicate1,
+      relativePathPredicate, pathPatternPredicate2));
+    assertThat(((AndPredicate) andPredicate).predicates()).containsExactly(relativePathPredicate, pathPatternPredicate1, pathPatternPredicate2);
+  }
+
+  @Test
+  public void simplifyAndExpressionsWhenEmpty() {
+    FilePredicate andPredicate = AndPredicate.create(Arrays.<FilePredicate>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.<FilePredicate>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.<FilePredicate>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 (file)
index 0000000..d0869f0
--- /dev/null
@@ -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.<String>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.<FilePredicate>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.<FilePredicate>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 (file)
index 0000000..8cae2f4
--- /dev/null
@@ -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 (file)
index 0000000..71c7d1f
--- /dev/null
@@ -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 (file)
index 0000000..0804d1f
--- /dev/null
@@ -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 (file)
index 0000000..b3c9c2d
--- /dev/null
@@ -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();
+  }
+}
index af226b302ee0c52a5f236411c605d34c40e09a1d..b90e6a19dd48c44f4c995e36374cb5e5046e3834 100644 (file)
@@ -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;
 
index 817d7b4aae92b270e9dfa6ccf6fb1e6f5e1c1afb..c9f44cd5b8f0e12118db587866a37590f911769b 100644 (file)
@@ -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;
index eb479cc0bce5363fdf2c9be60a098553e5e0baa6..980ee96bbe8db2996e420ed7abac5617e324a6ef 100644 (file)
@@ -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;
index 50ea80aceb733779f9279731fde504b19dec0299..50c247f5b51fcbbd8cc102bb5ca5bd3bfb868b7e 100644 (file)
@@ -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;
index 80ce4f25eb2dcfc06ae86f3929232a201f849b7e..a656a767f71f520820a645cdcd85e87855c7601f 100644 (file)
@@ -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;
index b52ad14b4af59d9af9a78f3bcdd54fb893d46ad4..6a597ef85b3b78c0818ee6234e76d4a9a11bccd7 100644 (file)
@@ -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;
index ab54b184c7d4c2f75e6a2c018b665757b2b68be8..07c39d82113022b872fc584aa1103370118d98c5 100644 (file)
@@ -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;
 
index f376d56999eb9c2a463238316e1a4ea23c205cc6..16154f5ff0c6bdd82154cdead85e62c0c6070509 100644 (file)
@@ -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;
index 63239c0924a1c44c921df9d0396aba82b7c119a0..fe18fdb725fb86e45d803603c773ca2f1a30a580 100644 (file)
@@ -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;
 
index c715462d0ca1d1c9b7f8da24f4d65d11afc81941..bce232d44f08a1435ddb3ee1661bf8a580dbb260 100644 (file)
@@ -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;
index ea27f1cd1f8781f4e74efc360088e4ce3d9b23f8..b041c6badc87de239cc3944224d2f2d4b2f4bcd9 100644 (file)
@@ -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;
 
index 45c25ef9568dddedd124fac47f13168063517c42..1b604e11b6ebeccb4da9f5aca70e029c3f162293 100644 (file)
@@ -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;
index 2d155cea75600004294d38415990d07279affa21..4d4a3476553b34a9a7e0144f7646dc12894dc207 100644 (file)
@@ -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;
index 41a5c2eeb784628d8450b31fbacb6a5bd47e9cc5..36134513be999c25cfc53fcbe7cb1ea8da2b497f 100644 (file)
@@ -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;
index 3c1d845f7856b1aaaf4c74770d268e877352dc96..7a66973ec2016617c0b3eefff17136f11feed96d 100644 (file)
@@ -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;
index 4028bdae0afb253056edc2b43264c43c1557114c..5f6054f81c997b65fa73bfbe558ee0697f6d7eb0 100644 (file)
@@ -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 (file)
index 0000000..e892510
--- /dev/null
@@ -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 (file)
index 0000000..3beb53f
--- /dev/null
@@ -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<NewRule> 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<NewRule> 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<NewRule> 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 (file)
index 0000000..a3a4e40
--- /dev/null
@@ -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"));
+  }
+}
index faad5baa933a46b4d5ebd22b9fc9225baddc45a7..f7a64f06b630acfb48e14516fa83938f8b945ef6 100644 (file)
@@ -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 (file)
index 0000000..1bb2375
--- /dev/null
@@ -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");
+  }
+}
index be8da961f4021e122cd2e793f13d464211c82b0d..37775d19ae53e6845f494aeba24b56863b4124b5 100644 (file)
@@ -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;
 
index 98785e06e62febbcc052ba5815ee975fe59197a2..04490bd02e4bad5e04f1cfe13de7f8cab01bf7b9 100644 (file)
@@ -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;
index cc4b6bf2485bbc91324e7e875145d835bb44874c..9bd732b9287ce15aab99c81b78f2fb71ad80915b 100644 (file)
@@ -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),
index 29064edd51b8c977836b276014011fe2953012e7..2ead8234b68806eed2a209eea5eb35de2d3292cc 100644 (file)
@@ -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;
index 857f12e9f69e9d8af4151374a5f202c5d4dd2671..ccd56feef74a1dee97ed043cff76490b83fd72aa 100644 (file)
@@ -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;
index 78a9c53a4f36a15b0b24339b358c385eadc8348c..a408dde4a419238d2b3934a5edfea11aeb9e7d43 100644 (file)
@@ -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 (file)
index 0000000..44a53e7
--- /dev/null
@@ -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 (file)
index 0000000..ca91e30
--- /dev/null
@@ -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 (file)
index 0000000..7127039
--- /dev/null
@@ -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<SyntaxHighlightingRule> 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 (file)
index 0000000..96bd593
--- /dev/null
@@ -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<String> customMatcher(String startWith, String endWith) {
+    return new TypeSafeMatcher<String>() {
+      @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 (file)
index 0000000..0ab0b99
--- /dev/null
@@ -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 (file)
index 0000000..4384483
--- /dev/null
@@ -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<Integer> newMeasure = new DefaultMeasure<Integer>(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<Integer> newMeasure = new DefaultMeasure<Integer>(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<Integer>()
+      .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 (file)
index 0000000..a43272b
--- /dev/null
@@ -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");
+  }
+
+}
index bdefb6f3436382cd8682e173f8d8d27ca89ec09b..d0aca624090495bc1ff1801e23125d5e660dcf4c 100644 (file)
@@ -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 (file)
index 0000000..76e4874
--- /dev/null
@@ -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);
+  }
+}
index f64ba90b3f1bbb2d48b90b6a1a31b072604b5205..01d3b6046e89fc55b572f4b7591ffab3508fa60c 100644 (file)
  */
 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;
index 2a31dae65cc2168046cea91550ea9d0b0be9faa8..0a78c6b2984cc7a812f11a87d7d2b515167c422c 100644 (file)
@@ -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 (file)
index 0000000..cf1d452
--- /dev/null
@@ -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.<Integer>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.<Integer>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.<Integer>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.<Integer>newMeasure()
+      .on(new TestInputFileBuilder("foo", "src/Foo.java").build())
+      .forMetric(CoreMetrics.NCLOC)
+      .withValue(2)
+      .save();
+    tester.<Integer>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 (file)
index 0000000..2cc3e48
Binary files /dev/null and b/sonar-scanner-engine/src/test/resources/org/sonar/scanner/fs/glyphicons-halflings-regular.woff differ