diff options
| author | Elena Vilchik | 2018-06-22 18:03:05 +0200 | 
|---|---|---|
| committer | Amaury Levé | 2018-06-22 18:03:05 +0200 | 
| commit | 88cc2bbfbda30d8ba8148dd4a7d0392a3171fe50 (patch) | |
| tree | 9fbe1cd5e45c63c1958e63fd0189d761b2afd563 /sonar-css-plugin/src/test | |
| parent | 7385260825c79419a920bdf835e925cef916b404 (diff) | |
| download | sonar-css-88cc2bbfbda30d8ba8148dd4a7d0392a3171fe50.tar.bz2 | |
Support import of external stylelint issues report (#65)
Diffstat (limited to 'sonar-css-plugin/src/test')
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)" +      } +    ] +  } +] | 
