Skip to content

Commit

Permalink
Merge pull request #148 from SonarCommunity/feature/Add_rule_BOM_in_U…
Browse files Browse the repository at this point in the history
…TF8_files

Add rule: use of BOM for UTF-8 files
  • Loading branch information
kalidasya committed Nov 30, 2015
2 parents bb7a5ba + 5dcdb7c commit d35578e
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 3 deletions.
66 changes: 66 additions & 0 deletions css-checks/src/main/java/org/sonar/css/checks/BOMCheck.java
@@ -0,0 +1,66 @@
/*
* SonarQube CSS Plugin
* Copyright (C) 2013 Tamas Kende and David RACODON
* kende.tamas@gmail.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 02
*/
package org.sonar.css.checks;

import com.google.common.base.Charsets;
import com.sonar.sslr.api.AstNode;

import java.nio.charset.Charset;

import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.check.Priority;
import org.sonar.check.Rule;
import org.sonar.css.CharsetAwareVisitor;
import org.sonar.css.parser.CssGrammar;
import org.sonar.squidbridge.annotations.ActivatedByDefault;
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
import org.sonar.squidbridge.checks.SquidCheck;

@Rule(
key = "bom-utf8-files",
name = "BOM should not be used for UTF-8 files",
priority = Priority.MAJOR,
tags = {Tags.PITFALL})
@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.SOFTWARE_RELATED_PORTABILITY)
@SqaleConstantRemediation("5min")
@ActivatedByDefault
public class BOMCheck extends SquidCheck implements CharsetAwareVisitor {

private Charset charset;

@Override
public void setCharset(Charset charset) {
this.charset = charset;
}

@Override
public void init() {
if (charset.equals(Charsets.UTF_8)) {
subscribeTo(CssGrammar.BOM);
}
}

@Override
public void visitNode(AstNode node) {
getContext().createFileViolation(this, "Remove the BOM.");
}

}
Expand Up @@ -37,6 +37,7 @@ public static Collection<Class> getChecks() {
return ImmutableList.<Class>of(
AllGradientDefinitions.class,
AlphabetizeDeclarationsCheck.class,
BOMCheck.class,
BulletproofFontFace.class,
BewareOfBoxModel.class,
CaseCheck.class,
Expand Down
@@ -0,0 +1,5 @@
<p>As stated in the Unicode specifications, use of a BOM is neither required nor recommended for UTF-8 files.</p>
<h2>See</h2>
<ul>
<li><a href="http://www.unicode.org/versions/Unicode8.0.0/ch02.pdf">Unicode Specifications (2.6 Encoding Schemes)</a></li>
</ul>
71 changes: 71 additions & 0 deletions css-checks/src/test/java/org/sonar/css/checks/BOMCheckTest.java
@@ -0,0 +1,71 @@
/*
* SonarQube CSS Plugin
* Copyright (C) 2013 Tamas Kende and David RACODON
* kende.tamas@gmail.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 02
*/
package org.sonar.css.checks;

import com.google.common.base.Charsets;

import java.io.File;

import org.junit.Test;
import org.sonar.css.CssAstScanner;
import org.sonar.css.CssConfiguration;
import org.sonar.squidbridge.api.SourceFile;
import org.sonar.squidbridge.checks.CheckMessagesVerifier;

public class BOMCheckTest {

@Test
public void should_find_that_the_UTF8_file_starts_with_a_BOM_and_raise_an_issue() {
SourceFile file = CssAstScanner.scanSingleFile(
new File("src/test/resources/checks/utf8WithBom.css"),
new BOMCheck());

CheckMessagesVerifier.verify(file.getCheckMessages()).next().withMessage("Remove the BOM.").noMore();
}

@Test
public void should_find_that_the_UTF8_file_does_not_start_with_a_BOM_and_not_raise_any_issue() {
SourceFile file = CssAstScanner.scanSingleFile(
new File("src/test/resources/checks/unknownFunctions.css"),
new BOMCheck());

CheckMessagesVerifier.verify(file.getCheckMessages()).noMore();
}

@Test
public void should_find_that_the_UTF16_files_start_with_a_BOM_but_not_raise_any_issue() {
SourceFile file;

file = CssAstScanner.scanSingleFileWithCustomConfiguration(
new File("src/test/resources/checks/utf16BE.css"),
new CssConfiguration(Charsets.UTF_16BE),
new BOMCheck());

CheckMessagesVerifier.verify(file.getCheckMessages()).noMore();

file = CssAstScanner.scanSingleFileWithCustomConfiguration(
new File("src/test/resources/checks/utf16LE.css"),
new CssConfiguration(Charsets.UTF_16LE),
new BOMCheck());

CheckMessagesVerifier.verify(file.getCheckMessages()).noMore();
}

}
Binary file added css-checks/src/test/resources/checks/utf16BE.css
Binary file not shown.
Binary file added css-checks/src/test/resources/checks/utf16LE.css
Binary file not shown.
3 changes: 3 additions & 0 deletions css-checks/src/test/resources/checks/utf8WithBom.css
@@ -0,0 +1,3 @@
.mybox {
margin-left: 10px;
}
9 changes: 7 additions & 2 deletions css-squid/src/main/java/org/sonar/css/CssAstScanner.java
Expand Up @@ -51,14 +51,19 @@ private CssAstScanner() {
}

/**
* Helper method for testing checks without having to deploy them on a Sonar instance.
* Helper methods for testing checks without having to deploy them on a SonarQube instance.
*/
@VisibleForTesting
public static SourceFile scanSingleFile(File file, SquidAstVisitor<LexerlessGrammar>... visitors) {
return scanSingleFileWithCustomConfiguration(file, new CssConfiguration(Charsets.UTF_8), visitors);
}

@VisibleForTesting
public static SourceFile scanSingleFileWithCustomConfiguration(File file, CssConfiguration conf, SquidAstVisitor<LexerlessGrammar>... visitors) {
if (!file.isFile()) {
throw new IllegalArgumentException("File '" + file + "' not found.");
}
AstScanner scanner = create(new CssConfiguration(Charsets.UTF_8), null, visitors);
AstScanner scanner = create(conf, null, visitors);
scanner.scanFile(file);
Collection<SourceCode> sources = scanner.getIndex().search(new QueryByType(SourceFile.class));
if (sources.size() != 1) {
Expand Down
Expand Up @@ -44,7 +44,7 @@ public void should_create_sonar_way_profile() {

assertThat(profile.getName()).isEqualTo(CssProfile.SONAR_WAY_PROFILE_NAME);
assertThat(profile.getLanguage()).isEqualTo(Css.KEY);
assertThat(profile.getActiveRulesByRepository(CheckList.REPOSITORY_KEY)).hasSize(45);
assertThat(profile.getActiveRulesByRepository(CheckList.REPOSITORY_KEY)).hasSize(46);
assertThat(validation.hasErrors()).isFalse();
}

Expand Down
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
.mybox {
margin-left: 10px;
}

0 comments on commit d35578e

Please sign in to comment.