aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2013-09-20 14:10:14 +0200
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2013-09-23 08:28:04 +0200
commit501e92cfd1292455f5d93d91a86bfa0cf69fc73c (patch)
treee7c158f28997efd59a0d8b36bba85bef6b761977 /plugins
parent0ac32549b3b249d266376efa3bc7ad0e188c2447 (diff)
downloadsonarqube-501e92cfd1292455f5d93d91a86bfa0cf69fc73c.tar.gz
sonarqube-501e92cfd1292455f5d93d91a86bfa0cf69fc73c.zip
SONAR-4679 Separate pattern matching at filter time from pattern initialization at scan time
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java20
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java3
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java4
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java65
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializer.java37
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java17
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java14
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java68
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java2
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java120
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializerTest.java49
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java20
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java43
13 files changed, 279 insertions, 183 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java
index 7691df8bb59..362a7331d1b 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilter.java
@@ -25,27 +25,23 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.IssueFilter;
import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternsInitializer;
-
-import java.util.List;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
public final class IgnoreIssuesFilter implements IssueFilter {
private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesFilter.class);
- private PatternsInitializer patternsInitializer;
+ private PatternMatcher patternMatcher;
- public IgnoreIssuesFilter(PatternsInitializer patternsInitializer) {
- this.patternsInitializer = patternsInitializer;
+ public IgnoreIssuesFilter(PatternMatcher patternMatcher) {
+ this.patternMatcher = patternMatcher;
}
public boolean accept(Issue issue) {
- List<IssuePattern> patterns = patternsInitializer.getPatternsForComponent(issue.componentKey());
- for (IssuePattern pattern : patterns) {
- if (pattern.match(issue)) {
- logExclusion(issue, pattern);
- return false;
- }
+ IssuePattern pattern = patternMatcher.getMatchingPattern(issue);
+ if (pattern != null) {
+ logExclusion(issue, pattern);
+ return false;
}
return true;
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java
index 9054563223b..e083d44aab2 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPlugin.java
@@ -20,6 +20,8 @@
package org.sonar.plugins.core.issue.ignore;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
+
import com.google.common.collect.ImmutableList;
import org.sonar.plugins.core.issue.ignore.pattern.PatternsInitializer;
import org.sonar.plugins.core.issue.ignore.scanner.RegexpScanner;
@@ -39,6 +41,7 @@ public final class IgnoreIssuesPlugin {
extensions.addAll(IgnoreIssuesConfiguration.getPropertyDefinitions());
extensions.add(
PatternsInitializer.class,
+ PatternMatcher.class,
RegexpScanner.class,
SourceScanner.class,
IgnoreIssuesFilter.class);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java
index 458292a6e80..f4e80ac86cf 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/IssuePattern.java
@@ -143,7 +143,7 @@ public class IssuePattern {
return false;
}
- boolean matchRule(RuleKey rule) {
+ public boolean matchRule(RuleKey rule) {
if (rule == null) {
return false;
}
@@ -152,7 +152,7 @@ public class IssuePattern {
return rulePattern.match(key);
}
- boolean matchResource(String resource) {
+ public boolean matchResource(String resource) {
return resource != null && resourcePattern.match(resource);
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java
new file mode 100644
index 00000000000..40b923d75e3
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.plugins.core.issue.ignore.pattern;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.issue.Issue;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+public class PatternMatcher implements BatchExtension {
+
+ private Multimap<String, IssuePattern> patternByComponent = LinkedHashMultimap.create();
+
+ public IssuePattern getMatchingPattern(Issue issue) {
+ IssuePattern matchingPattern = null;
+ Iterator<IssuePattern> patternIterator = getPatternsForComponent(issue.componentKey()).iterator();
+ while(matchingPattern == null && patternIterator.hasNext()) {
+ IssuePattern nextPattern = patternIterator.next();
+ if (nextPattern.match(issue)) {
+ matchingPattern = nextPattern;
+ }
+ }
+ return matchingPattern;
+ }
+
+ @VisibleForTesting
+ Collection<IssuePattern> getPatternsForComponent(String componentKey) {
+ return patternByComponent.get(componentKey);
+ }
+
+ public void addPatternForComponent(String component, IssuePattern pattern) {
+ patternByComponent.put(component, pattern.forResource(component));
+ }
+
+ public void addPatternToExcludeResource(String resource) {
+ addPatternForComponent(resource, new IssuePattern(resource, "*").setCheckLines(false));
+ }
+
+ public void addPatternToExcludeLines(String resource, Set<LineRange> lineRanges) {
+ addPatternForComponent(resource, new IssuePattern(resource, "*", lineRanges).setCheckLines(true));
+ }
+
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializer.java
index 5be21f823d2..d942d45db95 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializer.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializer.java
@@ -21,17 +21,13 @@
package org.sonar.plugins.core.issue.ignore.pattern;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.BatchExtension;
import org.sonar.api.config.Settings;
import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Strings.nullToEmpty;
@@ -43,7 +39,6 @@ public class PatternsInitializer implements BatchExtension {
private List<IssuePattern> multicriteriaPatterns;
private List<IssuePattern> blockPatterns;
private List<IssuePattern> allFilePatterns;
- private Map<String, List<IssuePattern>> patternByComponent = Maps.newHashMap();
public PatternsInitializer(Settings settings) {
this.settings = settings;
@@ -120,36 +115,4 @@ public class PatternsInitializer implements BatchExtension {
allFilePatterns.add(pattern);
}
}
-
- public void addPatternToExcludeResource(String resource) {
- addPatternForComponent(resource, new IssuePattern(resource, "*").setCheckLines(false));
- }
-
- public void addPatternToExcludeLines(String resource, Set<LineRange> lineRanges) {
- addPatternForComponent(resource, new IssuePattern(resource, "*", lineRanges).setCheckLines(true));
- }
-
- public void configurePatternsForComponent(String componentKey, String path) {
- for (IssuePattern pattern: multicriteriaPatterns) {
- if (pattern.matchResource(path)) {
- addPatternForComponent(componentKey, pattern);
- }
- }
- }
-
- public List<IssuePattern> getPatternsForComponent(String componentKey) {
- if (patternByComponent.containsKey(componentKey)) {
- return patternByComponent.get(componentKey);
- } else {
- return ImmutableList.of();
- }
- }
-
- private void addPatternForComponent(String component, IssuePattern pattern) {
- if (!patternByComponent.containsKey(component)) {
- List<IssuePattern> newList = Lists.newArrayList();
- patternByComponent.put(component, newList);
- }
- patternByComponent.get(component).add(pattern.forResource(component));
- }
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java
index 93af123e7cb..3001337abc8 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java
@@ -20,8 +20,9 @@
package org.sonar.plugins.core.issue.ignore.scanner;
-import org.apache.commons.lang.StringUtils;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
+import org.apache.commons.lang.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.io.FileUtils;
@@ -42,7 +43,7 @@ public class RegexpScanner implements BatchExtension {
private static final Logger LOG = LoggerFactory.getLogger(RegexpScanner.class);
- private PatternsInitializer patternsInitializer;
+ private PatternMatcher patternMatcher;
private List<java.util.regex.Pattern> allFilePatterns;
private List<DoubleRegexpMatcher> blockMatchers;
@@ -52,17 +53,17 @@ public class RegexpScanner implements BatchExtension {
private List<LineExclusion> lineExclusions;
private LineExclusion currentLineExclusion;
- public RegexpScanner(PatternsInitializer patternsInitializer) {
- this.patternsInitializer = patternsInitializer;
+ public RegexpScanner(PatternsInitializer patternsInitializer, PatternMatcher patternMatcher) {
+ this.patternMatcher = patternMatcher;
lineExclusions = Lists.newArrayList();
allFilePatterns = Lists.newArrayList();
blockMatchers = Lists.newArrayList();
- for (IssuePattern pattern : this.patternsInitializer.getAllFilePatterns()) {
+ for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) {
allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp()));
}
- for (IssuePattern pattern : this.patternsInitializer.getBlockPatterns()) {
+ for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) {
blockMatchers.add(new DoubleRegexpMatcher(
java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()),
java.util.regex.Pattern.compile(pattern.getEndBlockRegexp())));
@@ -93,7 +94,7 @@ public class RegexpScanner implements BatchExtension {
// first check the single regexp patterns that can be used to totally exclude a file
for (java.util.regex.Pattern pattern : allFilePatterns) {
if (pattern.matcher(line).find()) {
- patternsInitializer.addPatternToExcludeResource(resource);
+ patternMatcher.addPatternToExcludeResource(resource);
// nothing more to do on this file
LOG.debug("- Exclusion pattern '{}': every violation in this file will be ignored.", pattern);
return;
@@ -114,7 +115,7 @@ public class RegexpScanner implements BatchExtension {
if (!lineExclusions.isEmpty()) {
Set<LineRange> lineRanges = convertLineExclusionsToLineRanges();
LOG.debug("- Line exclusions found: {}", lineRanges);
- patternsInitializer.addPatternToExcludeLines(resource, lineRanges);
+ patternMatcher.addPatternToExcludeLines(resource, lineRanges);
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java
index b6c097e1b3f..8fc73aac95f 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java
@@ -20,6 +20,9 @@
package org.sonar.plugins.core.issue.ignore.scanner;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
+
+import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
@@ -43,12 +46,14 @@ public final class SourceScanner implements Sensor {
private final RegexpScanner regexpScanner;
private final PatternsInitializer patternsInitializer;
+ private final PatternMatcher patternMatcher;
private final ModuleFileSystem fileSystem;
private final PathResolver pathResolver;
- public SourceScanner(RegexpScanner regexpScanner, PatternsInitializer patternsInitializer, ModuleFileSystem fileSystem) {
+ public SourceScanner(RegexpScanner regexpScanner, PatternsInitializer patternsInitializer, PatternMatcher patternMatcher, ModuleFileSystem fileSystem) {
this.regexpScanner = regexpScanner;
this.patternsInitializer = patternsInitializer;
+ this.patternMatcher = patternMatcher;
this.fileSystem = fileSystem;
this.pathResolver = new PathResolver();
}
@@ -82,8 +87,13 @@ public final class SourceScanner implements Sensor {
try {
String componentKey = resolveComponent(inputFile, dirs, project, isTest);
if (componentKey != null) {
+
String relativePath = pathResolver.relativePath(dirs, inputFile).path();
- patternsInitializer.configurePatternsForComponent(componentKey, relativePath);
+ for (IssuePattern pattern: patternsInitializer.getMulticriteriaPatterns()) {
+ if (pattern.matchResource(relativePath)) {
+ patternMatcher.addPatternForComponent(componentKey, pattern);
+ }
+ }
if (patternsInitializer.hasFileContentPattern()) {
regexpScanner.scan(componentKey, inputFile, sourcesEncoding);
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java
index fb229d2114a..c4b4022dff4 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesFilterTest.java
@@ -23,15 +23,8 @@ package org.sonar.plugins.core.issue.ignore;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternDecoder;
-import org.sonar.plugins.core.issue.ignore.pattern.PatternsInitializer;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -39,66 +32,29 @@ import static org.mockito.Mockito.when;
public class IgnoreIssuesFilterTest {
- public static final Rule CHECKSTYLE_RULE = Rule.create("checkstyle", "MagicNumber", "");
- public static final String JAVA_FILE = "org.foo.Hello";
-
- private PatternsInitializer patternsInitializer;
+ private PatternMatcher patternMatcher;
private IgnoreIssuesFilter filter;
+ private Issue issue;
@Before
public void init() {
- patternsInitializer = mock(PatternsInitializer.class);
- when(patternsInitializer.getMulticriteriaPatterns()).thenReturn(Collections.<IssuePattern> emptyList());
-
- filter = new IgnoreIssuesFilter(patternsInitializer);
- }
-
- @Test
- public void shouldBeDeactivatedWhenPropertyIsMissing() {
- assertThat(filter.accept(create(CHECKSTYLE_RULE, JAVA_FILE, null))).isTrue();
- }
-
- @Test
- public void shouldBeIgnoredWithStandardPatterns() throws IOException {
- when(patternsInitializer.getPatternsForComponent(JAVA_FILE)).thenReturn(createPatterns("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+ patternMatcher = mock(PatternMatcher.class);
+ issue = mock(Issue.class);
- assertThat(filter.accept(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isFalse();
+ filter = new IgnoreIssuesFilter(patternMatcher);
}
@Test
- public void shouldNotBeIgnoredWithStandardPatterns() throws IOException {
- when(patternsInitializer.getPatternsForComponent(JAVA_FILE)).thenReturn(createPatterns("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+ public void shouldAcceptIfMatcherHasNoPatternForIssue() {
+ when(patternMatcher.getMatchingPattern(issue)).thenReturn(null);
- assertThat(filter.accept(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isTrue();
+ assertThat(filter.accept(issue)).isTrue();
}
@Test
- public void shouldBeIgnoredWithExtraPattern() throws IOException {
- when(patternsInitializer.getPatternsForComponent(JAVA_FILE)).thenReturn(createPatterns("org.foo.Hello;*;[15-200]"));
-
- assertThat(filter.accept(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isFalse();
- }
-
- @Test
- public void shouldNotBeIgnoredWithExtraPattern() throws IOException {
- when(patternsInitializer.getPatternsForComponent(JAVA_FILE)).thenReturn(createPatterns("org.foo.Hello;*;[15-200]"));
-
- assertThat(filter.accept(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isTrue();
- }
-
- private Issue create(Rule rule, String component, Integer line) {
- Issue mockIssue = mock(Issue.class);
- RuleKey ruleKey = null;
- if (rule != null) {
- ruleKey = rule.ruleKey();
- }
- when(mockIssue.ruleKey()).thenReturn(ruleKey);
- when(mockIssue.componentKey()).thenReturn(component);
- when(mockIssue.line()).thenReturn(line);
- return mockIssue;
- }
+ public void shouldNotAcceptIfMatcherHasPatternForIssue() {
+ when(patternMatcher.getMatchingPattern(issue)).thenReturn(mock(IssuePattern.class));
- private List<IssuePattern> createPatterns(String line) {
- return new PatternDecoder().decode(line);
+ assertThat(filter.accept(issue)).isFalse();
}
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java
index 4c5395a0b06..ca2b2dcf0b5 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/IgnoreIssuesPluginTest.java
@@ -27,6 +27,6 @@ import static org.fest.assertions.Assertions.assertThat;
public class IgnoreIssuesPluginTest {
@Test
public void justForCoverage() {
- assertThat(IgnoreIssuesPlugin.getExtensions()).hasSize(3 /* properties */ + 4 /* extensions */);
+ assertThat(IgnoreIssuesPlugin.getExtensions()).hasSize(3 /* properties */ + 5 /* extensions */);
}
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java
new file mode 100644
index 00000000000..af7f97e9f0e
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternMatcherTest.java
@@ -0,0 +1,120 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.plugins.core.issue.ignore.pattern;
+
+import com.google.common.collect.Sets;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.Rule;
+
+import java.io.IOException;
+import java.util.Set;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PatternMatcherTest {
+
+ public static final Rule CHECKSTYLE_RULE = Rule.create("checkstyle", "MagicNumber", "");
+ public static final String JAVA_FILE = "org.foo.Hello";
+
+ private PatternMatcher patternMatcher;
+
+ @Before
+ public void setUp() {
+ patternMatcher = new PatternMatcher();
+ }
+
+ @Test
+ public void shouldReturnExtraPatternForResource() {
+ String file = "foo";
+ patternMatcher.addPatternToExcludeResource(file);
+
+ IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
+ assertThat(extraPattern.matchResource(file)).isTrue();
+ assertThat(extraPattern.isCheckLines()).isFalse();
+ }
+
+ @Test
+ public void shouldReturnExtraPatternForLinesOfResource() {
+ String file = "foo";
+ Set<LineRange> lineRanges = Sets.newHashSet();
+ lineRanges.add(new LineRange(25, 28));
+ patternMatcher.addPatternToExcludeLines(file, lineRanges);
+
+ IssuePattern extraPattern = patternMatcher.getPatternsForComponent(file).iterator().next();
+ assertThat(extraPattern.matchResource(file)).isTrue();
+ assertThat(extraPattern.getAllLines()).isEqualTo(Sets.newHashSet(25, 26, 27, 28));
+ }
+
+ @Test
+ public void shouldHaveNoMatcherIfNoneDefined() {
+ assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, null))).isNull();
+ }
+
+ @Test
+ public void shouldMatchWithStandardPatterns() throws IOException {
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+
+ assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+ }
+
+ @Test
+ public void shouldNotMatchWithStandardPatterns() throws IOException {
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;checkstyle:MagicNumber;[15-200]"));
+
+ assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+ }
+
+ @Test
+ public void shouldMatchWithExtraPattern() throws IOException {
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+
+ assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 150))).isNotNull();
+ }
+
+ @Test
+ public void shouldNotMatchWithExtraPattern() throws IOException {
+ patternMatcher.addPatternForComponent(JAVA_FILE, createPattern("org.foo.Hello;*;[15-200]"));
+
+ assertThat(patternMatcher.getMatchingPattern(create(CHECKSTYLE_RULE, JAVA_FILE, 5))).isNull();
+ }
+
+ private Issue create(Rule rule, String component, Integer line) {
+ Issue mockIssue = mock(Issue.class);
+ RuleKey ruleKey = null;
+ if (rule != null) {
+ ruleKey = rule.ruleKey();
+ }
+ when(mockIssue.ruleKey()).thenReturn(ruleKey);
+ when(mockIssue.componentKey()).thenReturn(component);
+ when(mockIssue.line()).thenReturn(line);
+ return mockIssue;
+ }
+
+ private IssuePattern createPattern(String line) {
+ return new PatternDecoder().decode(line).get(0);
+ }
+
+}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializerTest.java
index 4abb5358747..aec0ea0d1de 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializerTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/pattern/PatternsInitializerTest.java
@@ -20,8 +20,6 @@
package org.sonar.plugins.core.issue.ignore.pattern;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.PropertyDefinitions;
@@ -29,11 +27,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.core.issue.ignore.IgnoreIssuesConfiguration;
-import java.util.Set;
-
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class PatternsInitializerTest {
@@ -55,28 +49,6 @@ public class PatternsInitializerTest {
}
@Test
- public void shouldReturnExtraPatternForResource() {
- String file = "foo";
- patternsInitializer.addPatternToExcludeResource(file);
-
- IssuePattern extraPattern = patternsInitializer.getPatternsForComponent(file).get(0);
- assertThat(extraPattern.matchResource(file)).isTrue();
- assertThat(extraPattern.isCheckLines()).isFalse();
- }
-
- @Test
- public void shouldReturnExtraPatternForLinesOfResource() {
- String file = "foo";
- Set<LineRange> lineRanges = Sets.newHashSet();
- lineRanges.add(new LineRange(25, 28));
- patternsInitializer.addPatternToExcludeLines(file, lineRanges);
-
- IssuePattern extraPattern = patternsInitializer.getPatternsForComponent(file).get(0);
- assertThat(extraPattern.matchResource(file)).isTrue();
- assertThat(extraPattern.getAllLines()).isEqualTo(Sets.newHashSet(25, 26, 27, 28));
- }
-
- @Test
public void shouldReturnMulticriteriaPattern() {
settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_KEY, "1,2");
settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_MULTICRITERIA_KEY + ".1." + IgnoreIssuesConfiguration.RESOURCE_KEY, "org/foo/Bar.java");
@@ -170,25 +142,4 @@ public class PatternsInitializerTest {
settings.setProperty(IgnoreIssuesConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IgnoreIssuesConfiguration.FILE_REGEXP, "");
patternsInitializer.initPatterns();
}
-
- @Test
- public void shouldConfigurePatternsForComponents() {
- String componentKey = "groupId:artifactId:org.foo.Bar";
- String path = "org/foo/Bar.java";
-
- IssuePattern matching1, matching2, notMatching;
- matching1 = mock(IssuePattern.class);
- when(matching1.matchResource(path)).thenReturn(true);
- matching2 = mock(IssuePattern.class);
- when(matching2.matchResource(path)).thenReturn(true);
- notMatching = mock(IssuePattern.class);
- when(notMatching.matchResource(path)).thenReturn(false);
-
- patternsInitializer.initPatterns();
- patternsInitializer.getMulticriteriaPatterns().addAll(Lists.newArrayList(matching1, matching2, notMatching));
- patternsInitializer.configurePatternsForComponent(componentKey, path);
-
- assertThat(patternsInitializer.getPatternsForComponent(componentKey).size()).isEqualTo(2);
- assertThat(patternsInitializer.getPatternsForComponent("other").size()).isEqualTo(0);
- }
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java
index 109de97e31d..fe7bc1973f9 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java
@@ -20,6 +20,8 @@
package org.sonar.plugins.core.issue.ignore.scanner;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
+
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
@@ -48,6 +50,8 @@ public class RegexpScannerTest {
@Mock
private PatternsInitializer patternsInitializer;
@Mock
+ private PatternMatcher patternMatcher;
+ @Mock
private IssuePattern allFilePattern;
@Mock
private IssuePattern blockPattern1;
@@ -66,7 +70,7 @@ public class RegexpScannerTest {
when(patternsInitializer.getAllFilePatterns()).thenReturn(Arrays.asList(allFilePattern));
when(patternsInitializer.getBlockPatterns()).thenReturn(Arrays.asList(blockPattern1, blockPattern2));
- regexpScanner = new RegexpScanner(patternsInitializer);
+ regexpScanner = new RegexpScanner(patternsInitializer, patternMatcher);
verify(patternsInitializer, times(1)).getAllFilePatterns();
verify(patternsInitializer, times(1)).getBlockPatterns();
@@ -84,7 +88,7 @@ public class RegexpScannerTest {
public void shouldAddPatternToExcludeFile() throws IOException {
regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp.txt"), UTF_8);
- verify(patternsInitializer, times(1)).addPatternToExcludeResource(javaFile);
+ verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -92,7 +96,7 @@ public class RegexpScannerTest {
public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws IOException {
regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp-and-double-regexp.txt"), UTF_8);
- verify(patternsInitializer, times(1)).addPatternToExcludeResource(javaFile);
+ verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -102,7 +106,7 @@ public class RegexpScannerTest {
Set<LineRange> lineRanges = Sets.newHashSet();
lineRanges.add(new LineRange(21, 25));
- verify(patternsInitializer, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -112,7 +116,7 @@ public class RegexpScannerTest {
Set<LineRange> lineRanges = Sets.newHashSet();
lineRanges.add(new LineRange(21, 34));
- verify(patternsInitializer, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -123,7 +127,7 @@ public class RegexpScannerTest {
Set<LineRange> lineRanges = Sets.newHashSet();
lineRanges.add(new LineRange(21, 25));
lineRanges.add(new LineRange(29, 33));
- verify(patternsInitializer, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -133,7 +137,7 @@ public class RegexpScannerTest {
Set<LineRange> lineRanges = Sets.newHashSet();
lineRanges.add(new LineRange(25, 35));
- verify(patternsInitializer, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
verifyNoMoreInteractions(patternsInitializer);
}
@@ -143,7 +147,7 @@ public class RegexpScannerTest {
Set<LineRange> lineRanges = Sets.newHashSet();
lineRanges.add(new LineRange(21, 29));
- verify(patternsInitializer, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
+ verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges);
verifyNoMoreInteractions(patternsInitializer);
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java
index bbcff4d25a9..24860050ee3 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java
@@ -33,6 +33,7 @@ import org.sonar.api.scan.filesystem.FileQuery;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern;
+import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher;
import org.sonar.plugins.core.issue.ignore.pattern.PatternsInitializer;
import java.io.File;
@@ -44,9 +45,11 @@ import java.util.List;
import static com.google.common.base.Charsets.UTF_8;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class SourceScannerTest {
@@ -58,6 +61,8 @@ public class SourceScannerTest {
@Mock
private PatternsInitializer patternsInitializer;
@Mock
+ private PatternMatcher patternMatcher;
+ @Mock
private ModuleFileSystem fileSystem;
private Project project;
@@ -74,7 +79,7 @@ public class SourceScannerTest {
Mockito.doReturn("java").when(project).getLanguageKey();
when(fileSystem.sourceCharset()).thenReturn(UTF_8);
- scanner = new SourceScanner(regexpScanner, patternsInitializer, fileSystem);
+ scanner = new SourceScanner(regexpScanner, patternsInitializer, patternMatcher, fileSystem);
}
@Test
@@ -106,8 +111,6 @@ public class SourceScannerTest {
scanner.analyse(project, null);
- verify(patternsInitializer).configurePatternsForComponent("polop:[default].Foo", "Foo.java");
- verify(patternsInitializer).configurePatternsForComponent("polop:[default].FooTest", "FooTest.java");
verify(regexpScanner).scan("polop:[default].Foo", sourceFile, UTF_8);
verify(regexpScanner).scan("polop:[default].FooTest", testFile, UTF_8);
}
@@ -127,12 +130,39 @@ public class SourceScannerTest {
scanner.analyse(project, null);
- verify(patternsInitializer).configurePatternsForComponent("polop:[default].Foo", "Foo.java");
- verify(patternsInitializer).configurePatternsForComponent("polop:[default].FooTest", "FooTest.java");
verifyNoMoreInteractions(regexpScanner);
}
@Test
+ public void shouldAddExclusionsForMulticriteriaPatterns() throws IOException {
+ File sourceFile = new File("src/main/java/Foo.java");
+ File testFile = new File("src/test/java/FooTest.java");
+
+ when(project.getLanguageKey()).thenReturn("java");
+ when(fileSystem.files(Mockito.isA(FileQuery.class)))
+ .thenReturn(Arrays.asList(sourceFile))
+ .thenReturn(Arrays.asList(testFile));
+ when(fileSystem.sourceDirs()).thenReturn(Arrays.asList(new File("src/main/java")));
+ when(fileSystem.testDirs()).thenReturn(Arrays.asList(new File("src/test/java")));
+
+ IssuePattern pattern1 = mock(IssuePattern.class);
+ when(pattern1.matchResource("Foo.java")).thenReturn(true);
+ when(pattern1.matchResource("FooTest.java")).thenReturn(false);
+ IssuePattern pattern2 = mock(IssuePattern.class);
+ when(pattern2.matchResource("Foo.java")).thenReturn(false);
+ when(pattern2.matchResource("FooTest.java")).thenReturn(true);
+
+ Mockito.doReturn(ImmutableList.of(pattern1, pattern2)).when(patternsInitializer).getMulticriteriaPatterns();
+ when(patternsInitializer.hasFileContentPattern()).thenReturn(false);
+
+ scanner.analyse(project, null);
+
+ verify(patternMatcher).addPatternForComponent("polop:[default].Foo", pattern1);
+ verify(patternMatcher).addPatternForComponent("polop:[default].FooTest", pattern2);
+ verifyZeroInteractions(regexpScanner);
+ }
+
+ @Test
public void shouldAnalyseOtherProject() throws IOException {
File sourceFile = new File("Foo.php");
File testFile = new File("FooTest.php");
@@ -147,8 +177,6 @@ public class SourceScannerTest {
scanner.analyse(project, null);
- verify(patternsInitializer).configurePatternsForComponent("polop:Foo.php", "Foo.php");
- verify(patternsInitializer).configurePatternsForComponent("polop:FooTest.php", "FooTest.php");
verify(regexpScanner).scan("polop:Foo.php", sourceFile, UTF_8);
verify(regexpScanner).scan("polop:FooTest.php", testFile, UTF_8);
}
@@ -197,7 +225,6 @@ public class SourceScannerTest {
when(project.getLanguageKey()).thenReturn("php");
when(fileSystem.files(Mockito.isA(FileQuery.class))).thenReturn(Arrays.asList(sourceFile));
List<IssuePattern> empty = ImmutableList.of();
- when(patternsInitializer.getPatternsForComponent("Foo.php")).thenReturn(empty);
doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:Foo.php", sourceFile, UTF_8);
thrown.expect(SonarException.class);