diff options
| author | Elena Vilchik | 2018-06-14 17:40:32 +0200 | 
|---|---|---|
| committer | GitHub | 2018-06-14 17:40:32 +0200 | 
| commit | 6383829aa3b6b25975da1fe7c618e3f611d8c6e1 (patch) | |
| tree | 25752e58f8ef71a3a3db849a987dc24a1f54e0f1 /sonar-css-plugin/src | |
| parent | b3887099d35a9d8909c00f43ca194cc02ba0b16a (diff) | |
| download | sonar-css-6383829aa3b6b25975da1fe7c618e3f611d8c6e1.tar.bz2 | |
Integrate stylelint inside plugin (#42)
Diffstat (limited to 'sonar-css-plugin/src')
30 files changed, 1096 insertions, 3 deletions
| diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/BundleHandler.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/BundleHandler.java new file mode 100644 index 0000000..79a7d5b --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/BundleHandler.java @@ -0,0 +1,28 @@ +/* + * 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; + +public interface BundleHandler { + +  void deployBundle(File deployDestination); + +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssPlugin.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssPlugin.java index 65e6453..2835edb 100644 --- a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssPlugin.java +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssPlugin.java @@ -22,6 +22,7 @@ package org.sonar.css.plugin;  import org.sonar.api.Plugin;  import org.sonar.api.config.PropertyDefinition;  import org.sonar.api.resources.Qualifiers; +import org.sonar.css.plugin.bundle.CssBundleHandler;  public class CssPlugin implements Plugin { @@ -37,6 +38,10 @@ public class CssPlugin implements Plugin {        MetricSensor.class,        CssLanguage.class,        SonarWayProfile.class, +      CssRulesDefinition.class, +      CssBundleHandler.class, +      CssRuleSensor.class, +      StylelintExecution.class,        PropertyDefinition.builder(FILE_SUFFIXES_KEY)          .defaultValue(FILE_SUFFIXES_DEFVALUE) diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRuleSensor.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRuleSensor.java new file mode 100644 index 0000000..8b6558b --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRuleSensor.java @@ -0,0 +1,115 @@ +/* + * 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 com.google.gson.Gson; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.rule.CheckFactory; +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.issue.NewIssue; +import org.sonar.api.batch.sensor.issue.NewIssueLocation; + +public class CssRuleSensor implements Sensor { + +  private final BundleHandler bundleHandler; +  private final CssRules cssRules; +  private final LinterCommandProvider linterCommandProvider; + +  public CssRuleSensor(BundleHandler bundleHandler, CheckFactory checkFactory, LinterCommandProvider linterCommandProvider) { +    this.bundleHandler = bundleHandler; +    this.linterCommandProvider = linterCommandProvider; +    this.cssRules = new CssRules(checkFactory); +  } + +  @Override +  public void describe(SensorDescriptor descriptor) { +    descriptor +      .onlyOnLanguage(CssLanguage.KEY) +      .name("SonarCSS Rules") +      .onlyOnFileType(InputFile.Type.MAIN); +  } + +  @Override +  public void execute(SensorContext context) { +    File deployDestination = context.fileSystem().workDir(); +    bundleHandler.deployBundle(deployDestination); + +    File projectBaseDir = context.fileSystem().baseDir(); + +    String[] commandParts = linterCommandProvider.commandParts(deployDestination, projectBaseDir); +    ProcessBuilder processBuilder = new ProcessBuilder(commandParts); + +    try { +      Process process = processBuilder.start(); + +      try (InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)) { +        IssuesPerFile[] issues = new Gson().fromJson(inputStreamReader, IssuesPerFile[].class); +        saveIssues(context, cssRules, issues); +      } + +    } catch (IOException e) { +      String command = String.join(" ", commandParts); +      throw new IllegalStateException(String.format("Failed to run external process '%s'. Re-run analysis with debug option for more information.", command), e); +    } +  } + +  private static void saveIssues(SensorContext context, CssRules cssRules, IssuesPerFile[] issues) { +    FileSystem fileSystem = context.fileSystem(); + +    for (IssuesPerFile issuesPerFile : issues) { +      InputFile inputFile = fileSystem.inputFile(fileSystem.predicates().hasAbsolutePath(issuesPerFile.source)); + +      if (inputFile != null) { +        for (Issue issue : issuesPerFile.warnings) { +          NewIssue sonarIssue = context.newIssue(); + +          NewIssueLocation location = sonarIssue.newLocation() +            .on(inputFile) +            .at(inputFile.selectLine(issue.line)) +            .message(issue.text); + +          sonarIssue +            .at(location) +            .forRule(cssRules.getSonarKey(issue.rule)) +            .save(); +        } +      } +    } +  } + +  static class IssuesPerFile { +    String source; +    Issue[] warnings; +  } + +  static class Issue { +    int line; +    String rule; +    String text; +  } + +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRules.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRules.java new file mode 100644 index 0000000..4ece37e --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRules.java @@ -0,0 +1,70 @@ +/* + * 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.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.sonar.api.batch.rule.CheckFactory; +import org.sonar.api.batch.rule.Checks; +import org.sonar.api.rule.RuleKey; +import org.sonar.css.plugin.rules.CssRule; +import org.sonar.css.plugin.rules.ColorNoInvalidHex; + +public class CssRules { + +  private final Map<String, RuleKey> stylelintKeyToRuleKey; +  private final StylelintConfig config = new StylelintConfig(); + +  public CssRules(CheckFactory checkFactory) { +    Checks<CssRule> checks = checkFactory.<CssRule>create(CssRulesDefinition.REPOSITORY_KEY).addAnnotatedChecks((Iterable) getRuleClasses()); +    Collection<CssRule> enabledRules = checks.all(); +    stylelintKeyToRuleKey = new HashMap<>(); +    for (CssRule rule : enabledRules) { +      stylelintKeyToRuleKey.put(rule.stylelintKey(), checks.ruleKey(rule)); +      config.rules.put(rule.stylelintKey(), true); +    } +  } + +  public static List<Class> getRuleClasses() { +    return Collections.unmodifiableList(Arrays.asList( +      ColorNoInvalidHex.class +    )); +  } + +  public RuleKey getSonarKey(String stylelintKey) { +    RuleKey ruleKey = stylelintKeyToRuleKey.get(stylelintKey); +    if (ruleKey == null) { +      throw new IllegalStateException("Unknown stylelint rule or rule not enabled " + stylelintKey); +    } +    return ruleKey; +  } + +  public StylelintConfig getConfig() { +    return config; +  } + +  public static class StylelintConfig { +    Map<String, Boolean> rules = new HashMap<>(); +  } +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java new file mode 100644 index 0000000..196252f --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/CssRulesDefinition.java @@ -0,0 +1,46 @@ +/* + * 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.util.Collections; +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.css.plugin.rules.ColorNoInvalidHex; +import org.sonarsource.analyzer.commons.RuleMetadataLoader; + +import static org.sonar.css.plugin.SonarWayProfile.PROFILE_PATH; + +public class CssRulesDefinition implements RulesDefinition { + +  public static final String REPOSITORY_KEY = "css"; +  public static final String RULE_REPOSITORY_NAME = "SonarAnalyzer"; + +  public static final String RESOURCE_FOLDER = "org/sonar/l10n/css/rules/css"; + +  @Override +  public void define(Context context) { +    NewRepository repository = context +      .createRepository(REPOSITORY_KEY, CssLanguage.KEY) +      .setName(RULE_REPOSITORY_NAME); + +    RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_FOLDER, PROFILE_PATH); +    ruleMetadataLoader.addRulesByAnnotatedClass(repository, Collections.singletonList(ColorNoInvalidHex.class)); +    repository.done(); +  } +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/LinterCommandProvider.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/LinterCommandProvider.java new file mode 100644 index 0000000..6f06c84 --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/LinterCommandProvider.java @@ -0,0 +1,28 @@ +/* + * 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; + +public interface LinterCommandProvider { + +  String[] commandParts(File deployDestination, File projectBaseDir); + +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java index a54de22..01f6d83 100644 --- a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/SonarWayProfile.java @@ -20,16 +20,20 @@  package org.sonar.css.plugin;  import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; +import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader; + +import static org.sonar.css.plugin.CssRulesDefinition.REPOSITORY_KEY; +import static org.sonar.css.plugin.CssRulesDefinition.RESOURCE_FOLDER;  public class SonarWayProfile implements BuiltInQualityProfilesDefinition {    public static final String PROFILE_NAME = "Sonar way"; -//  private static final String PROFILE_PATH = "org/sonar/l10n/css/rules/css/Sonar_way_profile.json"; +  public static final String PROFILE_PATH = RESOURCE_FOLDER + "/Sonar_way_profile.json";    @Override    public void define(Context context) { -      NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(PROFILE_NAME, CssLanguage.KEY); +    BuiltInQualityProfileJsonLoader.load(profile, REPOSITORY_KEY, PROFILE_PATH);      profile.done();    }  } diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintExecution.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintExecution.java new file mode 100644 index 0000000..c88a0ac --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/StylelintExecution.java @@ -0,0 +1,38 @@ +/* + * 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 org.sonar.api.batch.ScannerSide; + +@ScannerSide +public class StylelintExecution implements LinterCommandProvider { + +  @Override +  public String[] commandParts(File deployDestination, File projectBaseDir) { +    return new String[]{ +      "node", +      new File(deployDestination, "css-bundle/node_modules/stylelint/bin/stylelint").getAbsolutePath(), +      projectBaseDir.getAbsolutePath(), +      "--config", new File(deployDestination, "css-bundle/stylelintconfig.json").getAbsolutePath(), +      "-f", "json" +    }; +  } +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/Zip.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/Zip.java new file mode 100644 index 0000000..62df45e --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/Zip.java @@ -0,0 +1,52 @@ +/* + * 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.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.apache.commons.io.FileUtils; + +public class Zip { + +  private Zip() { +    // utility class +  } + +  public static void extract(InputStream bundle, File destination) throws IOException { +    ZipInputStream zip = new ZipInputStream(bundle); +    ZipEntry entry = zip.getNextEntry(); +    if (entry == null) { +      throw new IllegalStateException("At least one entry expected."); +    } +    while (entry != null) { +      File entryDestination = new File(destination, entry.getName()); +      if (entry.isDirectory()) { +        entryDestination.mkdirs(); +      } else { +        FileUtils.copyToFile(zip, entryDestination); +      } +      zip.closeEntry(); +      entry = zip.getNextEntry(); +    } +  } +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/CssBundleHandler.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/CssBundleHandler.java new file mode 100644 index 0000000..acf9245 --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/CssBundleHandler.java @@ -0,0 +1,55 @@ +/* + * 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.bundle; + +import java.io.File; +import java.io.InputStream; +import org.sonar.api.batch.ScannerSide; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.css.plugin.BundleHandler; +import org.sonar.css.plugin.Zip; + +@ScannerSide +public class CssBundleHandler implements BundleHandler { + +  private static final String BUNDLE_LOCATION = "/css-bundle.zip"; +  private static final Logger LOG = Loggers.get(CssBundleHandler.class); +  String bundleLocation = BUNDLE_LOCATION; + +  /** +   * Extracting "css-bundle.zip" (containing stylelint) +   * to deployDestination (".sonar" directory of the analyzed project). +   */ +  @Override +  public void deployBundle(File deployDestination) { +    InputStream bundle = getClass().getResourceAsStream(bundleLocation); +    if (bundle == null) { +      throw new IllegalStateException("CSS bundle not found at " + bundleLocation); +    } +    try { +      LOG.debug("Deploying bundle to {}", deployDestination.getAbsolutePath()); +      Zip.extract(bundle, deployDestination); +    } catch (Exception e) { +      throw new IllegalStateException("Failed to deploy CSS bundle (with classpath '" + bundleLocation + "')", e); +    } +  } + +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/package-info.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/package-info.java new file mode 100644 index 0000000..003d535 --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/bundle/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.css.plugin.bundle; diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/ColorNoInvalidHex.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/ColorNoInvalidHex.java new file mode 100644 index 0000000..b976abb --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/ColorNoInvalidHex.java @@ -0,0 +1,31 @@ +/* + * 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.rules; + +import org.sonar.check.Rule; + +@Rule(key = "S4647") +public class ColorNoInvalidHex implements CssRule { + +  @Override +  public String stylelintKey() { +    return "color-no-invalid-hex"; +  } +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/CssRule.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/CssRule.java new file mode 100644 index 0000000..237228b --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/CssRule.java @@ -0,0 +1,26 @@ +/* + * 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.rules; + +public interface CssRule { + +  String stylelintKey(); + +} diff --git a/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/package-info.java b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/package-info.java new file mode 100644 index 0000000..2c279a3 --- /dev/null +++ b/sonar-css-plugin/src/main/java/org/sonar/css/plugin/rules/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.css.plugin.rules; diff --git a/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.html b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.html new file mode 100644 index 0000000..10aa560 --- /dev/null +++ b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.html @@ -0,0 +1,29 @@ +<p>An invalid color definition will by default be interpreted as black, which is likely to have unintended impacts on the expected look and feel of +the website.</p> +<p>This rule raises an issue when a color definition <code>color</code>, <code>background-color</code> is not valid. The color definition is +considered valid when it is made of hexadecimal characters:</p> +<p>- longhand: 6 or 8 characters (when alpha is defined)</p> +<p>- shorthand variant: 3 or 4 characters (when alpha is defined)</p> +<h2>Noncompliant Code Example</h2> +<pre> +a { + color: #3c; // Noncompliant: shorthand should be made of 3 characters +} +div { +  background-color: #3cb371a; // Noncompliant: alpha should have 2 characters +} +</pre> +<h2>Compliant Solution</h2> +<pre> +a { + color: #3cc; +} +div { +  background-color: #3cb371ac; +} +</pre> +<h2>See</h2> +<ul> +  <li> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value">Mozilla Web Technology for Developers</a> - CSS Color </li> +</ul> + diff --git a/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.json b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.json new file mode 100644 index 0000000..afb0676 --- /dev/null +++ b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/S4647.json @@ -0,0 +1,16 @@ +{ +  "title": "Color definitions should be valid", +  "type": "BUG", +  "status": "ready", +  "remediation": { +    "func": "Constant\/Issue", +    "constantCost": "1min" +  }, +  "tags": [ +     +  ], +  "defaultSeverity": "Blocker", +  "ruleSpecification": "RSPEC-4647", +  "sqKey": "S4647", +  "scope": "All" +} diff --git a/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/Sonar_way_profile.json b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/Sonar_way_profile.json new file mode 100644 index 0000000..ba5ce46 --- /dev/null +++ b/sonar-css-plugin/src/main/resources/org/sonar/l10n/css/rules/css/Sonar_way_profile.json @@ -0,0 +1,6 @@ +{ +  "name": "Sonar way", +  "ruleKeys": [ +    "S4647" +  ] +} diff --git a/sonar-css-plugin/src/sonarcss-assembly.xml b/sonar-css-plugin/src/sonarcss-assembly.xml new file mode 100644 index 0000000..dcbab0f --- /dev/null +++ b/sonar-css-plugin/src/sonarcss-assembly.xml @@ -0,0 +1,20 @@ +<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" +          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd"> +    <id>sonarcss-assembly</id> +    <formats> +        <format>zip</format> +    </formats> +    <includeBaseDirectory>false</includeBaseDirectory> +    <fileSets> +        <fileSet> +            <directory>css-bundle</directory> +            <includes> +                <include>**/*</include> +            </includes> +            <excludes> +                <exclude>package-lock.json</exclude> +            </excludes> +        </fileSet> +    </fileSets> +</assembly> diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssLanguageTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssLanguageTest.java new file mode 100644 index 0000000..cf5c65a --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssLanguageTest.java @@ -0,0 +1,38 @@ +/* + * 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 org.junit.Test; +import org.sonar.api.config.internal.MapSettings; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CssLanguageTest { + +  @Test +  public void test() throws Exception { +    MapSettings settings = new MapSettings(); +    settings.setProperty(CssPlugin.FILE_SUFFIXES_KEY, CssPlugin.FILE_SUFFIXES_DEFVALUE); +    CssLanguage language = new CssLanguage(settings.asConfig()); +    assertThat(language.getKey()).isEqualTo("css"); +    assertThat(language.getName()).isEqualTo("CSS"); +    assertThat(language.getFileSuffixes()).containsOnly(".css", ".less", ".scss"); +  } +} 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 33bd4dd..1cbade9 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(4); +    assertThat(context.getExtensions()).hasSize(8);    }  } 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 new file mode 100644 index 0000000..a4d5921 --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRuleSensorTest.java @@ -0,0 +1,125 @@ +/* + * 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.IOException; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +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.sensor.internal.DefaultSensorDescriptor; +import org.sonar.api.batch.sensor.internal.SensorContextTester; +import org.sonar.css.plugin.bundle.CssBundleHandler; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CssRuleSensorTest { + +  private static CheckFactory checkFactory = new CheckFactory(new TestActiveRules("S4647")); +  private File BASE_DIR = new File("src/test/resources").getAbsoluteFile(); + +  @Rule +  public TemporaryFolder tmpDir = new TemporaryFolder(); + +  @Test +  public void test_descriptor() throws Exception { +    CssRuleSensor sensor = new CssRuleSensor(new CssBundleHandler(), checkFactory, new StylelintExecution()); +    DefaultSensorDescriptor sensorDescriptor = new DefaultSensorDescriptor(); +    sensor.describe(sensorDescriptor); +    assertThat(sensorDescriptor.name()).isEqualTo("SonarCSS Rules"); +    assertThat(sensorDescriptor.languages()).containsOnly("css"); +    assertThat(sensorDescriptor.type()).isEqualTo(Type.MAIN); +  } + +  @Test +  public void test_execute() throws Exception { +    SensorContextTester context = SensorContextTester.create(BASE_DIR); +    context.fileSystem().setWorkDir(tmpDir.getRoot().toPath()); +    DefaultInputFile inputFile = createInputFile(context, "some css content\n on 2 lines", "dir/file.css"); +    TestLinterCommandProvider rulesExecution = TestLinterCommandProvider.nodeScript("/executables/mockStylelint.js", inputFile.absolutePath()); +    CssRuleSensor sensor = new CssRuleSensor(new TestBundleHandler(), checkFactory, rulesExecution); +    sensor.execute(context); + +    assertThat(context.allIssues()).hasSize(1); +  } + +  private static DefaultInputFile createInputFile(SensorContextTester sensorContext, String content, String relativePath) { +    DefaultInputFile inputFile = new TestInputFileBuilder("moduleKey", relativePath) +      .setModuleBaseDir(sensorContext.fileSystem().baseDirPath()) +      .setType(Type.MAIN) +      .setLanguage(CssLanguage.KEY) +      .setCharset(StandardCharsets.UTF_8) +      .setContents(content) +      .build(); + +    sensorContext.fileSystem().add(inputFile); +    return inputFile; +  } + +  private static class TestLinterCommandProvider implements LinterCommandProvider { + +    private static String nodeExecutable = findNodeExecutable(); + +    private String[] elements; + +    private static String findNodeExecutable() { +      try { +        String nodeFromMavenPlugin = "target/node/node"; +        Runtime.getRuntime().exec(nodeFromMavenPlugin); +        return nodeFromMavenPlugin; +      } catch (IOException e) { +        return "node"; +      } +    } + +    private static String resourceScript(String script) { +      try { +        return new File(TestLinterCommandProvider.class.getResource(script).toURI()).getAbsolutePath(); +      } catch (URISyntaxException e) { +        throw new IllegalStateException(e); +      } +    } + +    static TestLinterCommandProvider nodeScript(String script, String args) { +      TestLinterCommandProvider testRulesExecution = new TestLinterCommandProvider(); +      testRulesExecution.elements = new String[]{ nodeExecutable, resourceScript(script), args}; +      return testRulesExecution; +    } + +    @Override +    public String[] commandParts(File deployDestination, File projectBaseDir) { +      return elements; +    } +  } + +  private static class TestBundleHandler implements BundleHandler { + +    @Override +    public void deployBundle(File deployDestination) { +      // do nothing +    } +  } +} 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 new file mode 100644 index 0000000..7dffb35 --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/CssRulesDefinitionTest.java @@ -0,0 +1,43 @@ +/* + * 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 org.junit.Test; +import org.sonar.api.server.rule.RulesDefinition; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CssRulesDefinitionTest { + +  @Test +  public void test() { +    CssRulesDefinition rulesDefinition = new CssRulesDefinition(); +    RulesDefinition.Context context = new RulesDefinition.Context(); +    rulesDefinition.define(context); +    RulesDefinition.Repository repository = context.repository("css"); + +    assertThat(context.repositories()).hasSize(1); + +    assertThat(repository.name()).isEqualTo("SonarAnalyzer"); +    assertThat(repository.language()).isEqualTo("css"); +    assertThat(repository.isExternal()).isEqualTo(false); +    assertThat(repository.rules()).hasSize(CssRules.getRuleClasses().size()); +  } +} diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/SonarWayProfileTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/SonarWayProfileTest.java new file mode 100644 index 0000000..eba68f5 --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/SonarWayProfileTest.java @@ -0,0 +1,44 @@ +/* + * 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 org.junit.Test; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.Context; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SonarWayProfileTest { + +  @Test +  public void should_create_sonar_way_profile() { +    SonarWayProfile definition = new SonarWayProfile(); +    Context context = new Context(); +    definition.define(context); + +    BuiltInQualityProfile profile = context.profile("css", SonarWayProfile.PROFILE_NAME); + +    assertThat(profile.language()).isEqualTo(CssLanguage.KEY); +    assertThat(profile.name()).isEqualTo(SonarWayProfile.PROFILE_NAME); +    assertThat(profile.rules()).extracting("repoKey").containsOnly(CssRulesDefinition.REPOSITORY_KEY); +    assertThat(profile.rules()).extracting("ruleKey").contains("S4647"); +  } + +} diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintExecutionTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintExecutionTest.java new file mode 100644 index 0000000..4ca78db --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/StylelintExecutionTest.java @@ -0,0 +1,44 @@ +/* + * 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 org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class StylelintExecutionTest { + +  @Test +  public void test() throws Exception { +    StylelintExecution stylelintExecution = new StylelintExecution(); +    File deployDestination = new File("deploy_destination"); +    File baseDir = new File("base_dir"); +    assertThat(stylelintExecution.commandParts(deployDestination, baseDir)).containsExactly( +      "node", +      new File(deployDestination, "css-bundle/node_modules/stylelint/bin/stylelint").getAbsolutePath(), +      baseDir.getAbsolutePath(), +      "--config", +      new File(deployDestination, "css-bundle/stylelintconfig.json").getAbsolutePath(), +      "-f", +      "json" +    ); +  } +} diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/TestActiveRules.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/TestActiveRules.java new file mode 100644 index 0000000..76ae3d7 --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/TestActiveRules.java @@ -0,0 +1,114 @@ +/* + * 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.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.CheckForNull; +import org.sonar.api.batch.rule.ActiveRule; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.rule.RuleKey; + +public class TestActiveRules implements ActiveRules { + +  private final List<ActiveRule> activeRules; + +  public TestActiveRules(String... activeRules) { +    this.activeRules = Arrays.stream(activeRules).map(TestActiveRule::new).collect(Collectors.toList()); +  } + +  @CheckForNull +  @Override +  public ActiveRule find(RuleKey ruleKey) { +    return null; +  } + +  @Override +  public Collection<ActiveRule> findAll() { +    return activeRules; +  } + +  @Override +  public Collection<ActiveRule> findByRepository(String repository) { +    return activeRules; +  } + +  @Override +  public Collection<ActiveRule> findByLanguage(String language) { +    return activeRules; +  } + +  @CheckForNull +  @Override +  public ActiveRule findByInternalKey(String repository, String internalKey) { +    return null; +  } + +  class TestActiveRule implements ActiveRule { + +    final RuleKey ruleKey; + +    public TestActiveRule(String key) { +      ruleKey = RuleKey.of(CssRulesDefinition.REPOSITORY_KEY, key); +    } + +    @Override +    public RuleKey ruleKey() { +      return ruleKey; +    } + +    @Override +    public String severity() { +      return null; +    } + +    @Override +    public String language() { +      return null; +    } + +    @CheckForNull +    @Override +    public String param(String key) { +      return null; +    } + +    @Override +    public Map<String, String> params() { +      return Collections.emptyMap(); +    } + +    @CheckForNull +    @Override +    public String internalKey() { +      return null; +    } + +    @CheckForNull +    @Override +    public String templateRuleKey() { +      return null; +    } +  } +} diff --git a/sonar-css-plugin/src/test/java/org/sonar/css/plugin/bundle/CssBundleHandlerTest.java b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/bundle/CssBundleHandlerTest.java new file mode 100644 index 0000000..b55d050 --- /dev/null +++ b/sonar-css-plugin/src/test/java/org/sonar/css/plugin/bundle/CssBundleHandlerTest.java @@ -0,0 +1,55 @@ +/* + * 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.bundle; + +import java.io.File; +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 CssBundleHandlerTest { + +  @Rule +  public TemporaryFolder temporaryFolder = new TemporaryFolder(); + +  @Rule +  public ExpectedException expectedException = ExpectedException.none(); + +  private File DEPLOY_DESTINATION; + +  @Before +  public void setUp() throws Exception { +    DEPLOY_DESTINATION = temporaryFolder.newFolder("deployDestination"); +  } + +  @Test +  public void test() throws Exception { +    CssBundleHandler bundleHandler = new CssBundleHandler(); +    bundleHandler.bundleLocation = "/bundle/test-bundle.zip"; +    bundleHandler.deployBundle(DEPLOY_DESTINATION); + +    assertThat(new File(DEPLOY_DESTINATION, "test-bundle.js").exists()).isTrue(); +  } + +} diff --git a/sonar-css-plugin/src/test/resources/.DS_Store b/sonar-css-plugin/src/test/resources/.DS_StoreBinary files differ new file mode 100644 index 0000000..63066fe --- /dev/null +++ b/sonar-css-plugin/src/test/resources/.DS_Store diff --git a/sonar-css-plugin/src/test/resources/bundle/.DS_Store b/sonar-css-plugin/src/test/resources/bundle/.DS_StoreBinary files differ new file mode 100644 index 0000000..5008ddf --- /dev/null +++ b/sonar-css-plugin/src/test/resources/bundle/.DS_Store diff --git a/sonar-css-plugin/src/test/resources/bundle/test-bundle.zip b/sonar-css-plugin/src/test/resources/bundle/test-bundle.zipBinary files differ new file mode 100644 index 0000000..446e89f --- /dev/null +++ b/sonar-css-plugin/src/test/resources/bundle/test-bundle.zip diff --git a/sonar-css-plugin/src/test/resources/executables/mockStylelint.js b/sonar-css-plugin/src/test/resources/executables/mockStylelint.js new file mode 100644 index 0000000..e8c1667 --- /dev/null +++ b/sonar-css-plugin/src/test/resources/executables/mockStylelint.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node +var testFile = process.argv[2]; + +var result = [ +  { +    source: testFile, + +    warnings: [ +      { +        text: "some message", +        line: 2, +        rule: "color-no-invalid-hex" +      } +    ] +  } +]; + +var json = JSON.stringify(result); +console.log(json); | 
