aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-css-plugin/src/test
diff options
context:
space:
mode:
authorElena Vilchik2018-06-22 18:03:05 +0200
committerAmaury Levé2018-06-22 18:03:05 +0200
commit88cc2bbfbda30d8ba8148dd4a7d0392a3171fe50 (patch)
tree9fbe1cd5e45c63c1958e63fd0189d761b2afd563 /sonar-css-plugin/src/test
parent7385260825c79419a920bdf835e925cef916b404 (diff)
downloadsonar-css-88cc2bbfbda30d8ba8148dd4a7d0392a3171fe50.tar.bz2
Support import of external stylelint issues report (#65)
Diffstat (limited to 'sonar-css-plugin/src/test')
-rw-r--r--sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java2
-rw-r--r--sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java1
-rw-r--r--sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java27
-rw-r--r--sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintReportSensorTest.java212
-rw-r--r--sonar-css-plugin/src/test/resources/stylelint-report/file.css1
-rw-r--r--sonar-css-plugin/src/test/resources/stylelint-report/invalid-file.json22
-rw-r--r--sonar-css-plugin/src/test/resources/stylelint-report/report.json17
7 files changed, 277 insertions, 5 deletions
diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java
index 1cbade9..c5d9bbd 100644
--- a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java
+++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssPluginTest.java
@@ -36,6 +36,6 @@ public class CssPluginTest {
Plugin.Context context = new Plugin.Context(runtime);
Plugin underTest = new CssPlugin();
underTest.define(context);
- assertThat(context.getExtensions()).hasSize(8);
+ assertThat(context.getExtensions()).hasSize(9);
}
}
diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java
index f86e24f..471c4ef 100644
--- a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java
+++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java
@@ -60,7 +60,6 @@ public class CssRuleSensorTest {
sensor.describe(sensorDescriptor);
assertThat(sensorDescriptor.name()).isEqualTo("SonarCSS Rules");
assertThat(sensorDescriptor.languages()).containsOnly("css");
- assertThat(sensorDescriptor.type()).isEqualTo(Type.MAIN);
}
@Test
diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java
index 7dffb35..167aeef 100644
--- a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java
+++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java
@@ -27,14 +27,35 @@ import static org.assertj.core.api.Assertions.assertThat;
public class CssRulesDefinitionTest {
@Test
- public void test() {
- CssRulesDefinition rulesDefinition = new CssRulesDefinition();
+ public void test_with_external_rules() {
+ CssRulesDefinition rulesDefinition = new CssRulesDefinition(true);
+ RulesDefinition.Context context = new RulesDefinition.Context();
+ rulesDefinition.define(context);
+
+ assertThat(context.repositories()).hasSize(2);
+ RulesDefinition.Repository mainRepository = context.repository("css");
+ RulesDefinition.Repository externalRepository = context.repository("external_stylelint");
+
+ assertThat(externalRepository.name()).isEqualTo("stylelint");
+ assertThat(externalRepository.language()).isEqualTo("css");
+ assertThat(externalRepository.isExternal()).isEqualTo(true);
+ assertThat(externalRepository.rules()).hasSize(170);
+
+ assertThat(mainRepository.name()).isEqualTo("SonarAnalyzer");
+ assertThat(mainRepository.language()).isEqualTo("css");
+ assertThat(mainRepository.isExternal()).isEqualTo(false);
+ assertThat(mainRepository.rules()).hasSize(CssRules.getRuleClasses().size());
+ }
+
+ @Test
+ public void test_no_external_rules() throws Exception {
+ CssRulesDefinition rulesDefinition = new CssRulesDefinition(false);
RulesDefinition.Context context = new RulesDefinition.Context();
rulesDefinition.define(context);
- RulesDefinition.Repository repository = context.repository("css");
assertThat(context.repositories()).hasSize(1);
+ RulesDefinition.Repository repository = context.repository("css");
assertThat(repository.name()).isEqualTo("SonarAnalyzer");
assertThat(repository.language()).isEqualTo("css");
assertThat(repository.isExternal()).isEqualTo(false);
diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintReportSensorTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintReportSensorTest.java
new file mode 100644
index 0000000..bbbc8d8
--- /dev/null
+++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintReportSensorTest.java
@@ -0,0 +1,212 @@
+/*
+ * SonarCSS
+ * Copyright (C) 2018-2018 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.css.plugin;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.Iterator;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.SonarQubeSide;
+import org.sonar.api.SonarRuntime;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
+import org.sonar.api.batch.rule.CheckFactory;
+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.ExternalIssue;
+import org.sonar.api.internal.SonarRuntimeImpl;
+import org.sonar.api.rules.RuleType;
+import org.sonar.api.utils.Version;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StylelintReportSensorTest {
+
+ @Rule
+ public TemporaryFolder tmpDir = new TemporaryFolder();
+
+ @Rule
+ public final LogTester logTester = new LogTester();
+
+ private static final File BASE_DIR = new File("src/test/resources/stylelint-report/").getAbsoluteFile();
+ private static final String CONTENT = ".foo {\n}";
+
+ private SensorContextTester context = SensorContextTester.create(BASE_DIR);
+ private static final CheckFactory EMPTY_CHECK_FACTORY = new CheckFactory(new TestActiveRules());
+ private static final CheckFactory CHECK_FACTORY_WITH_RULE = new CheckFactory(new TestActiveRules("S4647"));
+
+ private StylelintReportSensor stylelintReportSensor = new StylelintReportSensor(EMPTY_CHECK_FACTORY);
+ private DefaultInputFile inputFile = createInputFile(context, CONTENT, "file.css");
+
+ @Before
+ public void setUp() throws Exception {
+ context.setRuntime(getRuntime(7, 2));
+ context.fileSystem().add(inputFile);
+ }
+
+ @Test
+ public void should_add_issues_from_report() throws Exception {
+ setReport("report.json");
+ stylelintReportSensor.execute(context);
+
+ Collection<ExternalIssue> externalIssues = context.allExternalIssues();
+ assertThat(externalIssues).hasSize(2);
+ Iterator<ExternalIssue> iterator = externalIssues.iterator();
+ ExternalIssue first = iterator.next();
+ ExternalIssue second = iterator.next();
+
+ assertThat(first.type()).isEqualTo(RuleType.BUG);
+ assertThat(second.type()).isEqualTo(RuleType.CODE_SMELL);
+
+ assertThat(first.remediationEffort()).isEqualTo(5);
+ assertThat(first.severity()).isEqualTo(Severity.MAJOR);
+ assertThat(first.primaryLocation().message()).isEqualTo("external issue message (color-no-invalid-hex)");
+ assertThat(first.primaryLocation().textRange().start().line()).isEqualTo(1);
+ }
+
+ @Test
+ public void should_support_absolute_file_paths_in_report() throws Exception {
+ String report = "[\n" +
+ " {\n" +
+ " \"source\": \"%s\",\n" +
+ " \"warnings\": [\n" +
+ " {\n" +
+ " \"line\": 1,\n" +
+ " \"rule\": \"color\\-no\\-invalid-hex\",\n" +
+ " \"text\": \"external issue message\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "]\n";
+
+ File reportFile = tmpDir.newFile();
+ FileWriter writer = new FileWriter(reportFile);
+ writer.write(String.format(report, inputFile.absolutePath()));
+ writer.close();
+
+ setReport(reportFile.getAbsolutePath());
+ stylelintReportSensor.execute(context);
+
+ assertThat(context.allExternalIssues()).hasSize(1);
+ }
+
+ @Test
+ public void should_skip_duplicates() throws Exception {
+ // when in SQ CSS profile there is an activated rule matching to an external issue,
+ // that external issue is ignored
+ setReport("report.json");
+ new StylelintReportSensor(CHECK_FACTORY_WITH_RULE).execute(context);
+
+ Collection<ExternalIssue> externalIssues = context.allExternalIssues();
+ assertThat(externalIssues).hasSize(1);
+ assertThat(externalIssues.iterator().next().primaryLocation().message()).isEqualTo("external issue message (comment-no-empty)");
+
+ assertThat(logTester.logs(LoggerLevel.DEBUG))
+ .contains("Stylelint issue for rule 'color-no-invalid-hex' is skipped because this rule is activated in your SonarQube profile for CSS (rule key in SQ css:S4647)");
+ }
+
+ @Test
+ public void should_ignore_report_on_older_sonarqube() throws Exception {
+ context.setRuntime(getRuntime(7, 1));
+ setReport("report.json");
+ stylelintReportSensor.execute(context);
+
+ assertThat(context.allExternalIssues()).isEmpty();
+ assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Import of external issues requires SonarQube 7.2 or greater.");
+ }
+
+ @Test
+ public void should_do_nothing_when_no_report() throws Exception {
+ setReport("");
+ stylelintReportSensor.execute(context);
+
+ assertThat(context.allExternalIssues()).isEmpty();
+ }
+
+ @Test
+ public void should_log_when_not_existing_report_file() throws Exception {
+ setReport("not-exist.json");
+ stylelintReportSensor.execute(context);
+
+ assertThat(context.allExternalIssues()).isEmpty();
+ assertThat(logTester.logs(LoggerLevel.ERROR)).contains("No issues information will be saved as the report file can't be read.");
+ }
+
+ @Test
+ public void should_log_when_not_found_input_file() throws Exception {
+ setReport("invalid-file.json");
+ stylelintReportSensor.execute(context);
+
+ assertThat(context.allExternalIssues()).hasSize(1);
+ assertThat(logTester.logs(LoggerLevel.WARN)).contains("No input file found for not-exist.css. No stylelint issues will be imported on this file.");
+ }
+
+ @Test
+ public void should_accept_absolute_path_to_report() throws Exception {
+ setReport(new File(BASE_DIR, "report.json").getAbsolutePath());
+ stylelintReportSensor.execute(context);
+ assertThat(context.allExternalIssues()).hasSize(2);
+ }
+
+ @Test
+ public void should_accept_several_reports() throws Exception {
+ setReport("report.json, invalid-file.json");
+ stylelintReportSensor.execute(context);
+ assertThat(context.allExternalIssues()).hasSize(3);
+ }
+
+ @Test
+ public void test_descriptor() throws Exception {
+ DefaultSensorDescriptor sensorDescriptor = new DefaultSensorDescriptor();
+ stylelintReportSensor.describe(sensorDescriptor);
+ assertThat(sensorDescriptor.name()).isEqualTo("Import of stylelint issues");
+ assertThat(sensorDescriptor.languages()).containsOnly(CssLanguage.KEY);
+ }
+
+ private void setReport(String reportFileName) {
+ context.settings().setProperty(CssPlugin.STYLELINT_REPORT_PATHS, reportFileName);
+ }
+
+ private SonarRuntime getRuntime(int major, int minor) {
+ return SonarRuntimeImpl.forSonarQube(Version.create(major, minor), SonarQubeSide.SERVER);
+ }
+
+ private static DefaultInputFile createInputFile(SensorContextTester sensorContext, String content, String relativePath) {
+ DefaultInputFile testInputFile = new TestInputFileBuilder("moduleKey", relativePath)
+ .setModuleBaseDir(sensorContext.fileSystem().baseDirPath())
+ .setType(Type.MAIN)
+ .setLanguage(CssLanguage.KEY)
+ .setCharset(StandardCharsets.UTF_8)
+ .setContents(content)
+ .build();
+
+ sensorContext.fileSystem().add(testInputFile);
+ return testInputFile;
+ }
+}
diff --git a/sonar-css-plugin/src/test/resources/stylelint-report/file.css b/sonar-css-plugin/src/test/resources/stylelint-report/file.css
new file mode 100644
index 0000000..59aa5dd
--- /dev/null
+++ b/sonar-css-plugin/src/test/resources/stylelint-report/file.css
@@ -0,0 +1 @@
+File content is set in test file
diff --git a/sonar-css-plugin/src/test/resources/stylelint-report/invalid-file.json b/sonar-css-plugin/src/test/resources/stylelint-report/invalid-file.json
new file mode 100644
index 0000000..0dc724c
--- /dev/null
+++ b/sonar-css-plugin/src/test/resources/stylelint-report/invalid-file.json
@@ -0,0 +1,22 @@
+[
+ {
+ "source": "not-exist.css",
+ "warnings": [
+ {
+ "line": 1,
+ "rule": "color-no-invalid-hex",
+ "text": "external issue message"
+ }
+ ]
+ },
+ {
+ "source": "file.css",
+ "warnings": [
+ {
+ "line": 1,
+ "rule": "comment-no-empty",
+ "text": "external issue message (comment-no-empty)"
+ }
+ ]
+ }
+]
diff --git a/sonar-css-plugin/src/test/resources/stylelint-report/report.json b/sonar-css-plugin/src/test/resources/stylelint-report/report.json
new file mode 100644
index 0000000..6e758b3
--- /dev/null
+++ b/sonar-css-plugin/src/test/resources/stylelint-report/report.json
@@ -0,0 +1,17 @@
+[
+ {
+ "source": "file.css",
+ "warnings": [
+ {
+ "line": 1,
+ "rule": "color-no-invalid-hex",
+ "text": "external issue message (color-no-invalid-hex)"
+ },
+ {
+ "line": 1,
+ "rule": "comment-no-empty",
+ "text": "external issue message (comment-no-empty)"
+ }
+ ]
+ }
+]