diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-02-18 15:00:19 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-02-18 15:02:05 +0100 |
commit | c128fb65044ab2664b459e741d2e793112f540e4 (patch) | |
tree | ea10f482f7207c944706ab4463868d1450dbe311 /sonar-batch/src/test/java | |
parent | 9250493c833f593b55be4e09e59fafa8b198339c (diff) | |
download | sonarqube-c128fb65044ab2664b459e741d2e793112f540e4.tar.gz sonarqube-c128fb65044ab2664b459e741d2e793112f540e4.zip |
Issue exclusions patterns are now initialized prior to sensor phase
Diffstat (limited to 'sonar-batch/src/test/java')
11 files changed, 1309 insertions, 0 deletions
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java new file mode 100644 index 00000000000..9c1731097e5 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/EnforceIssuesFilterTest.java @@ -0,0 +1,151 @@ +/* + * 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.batch.issue.ignore; + +import org.sonar.batch.issue.ignore.EnforceIssuesFilter; +import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; +import org.sonar.batch.issue.ignore.pattern.IssuePattern; + +import com.google.common.collect.ImmutableList; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.issue.Issue; +import org.sonar.api.issue.batch.IssueFilterChain; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.WildcardPattern; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +public class EnforceIssuesFilterTest { + + private IssueInclusionPatternInitializer exclusionPatternInitializer; + private EnforceIssuesFilter ignoreFilter; + private Issue issue; + private IssueFilterChain chain; + + @Before + public void init() { + exclusionPatternInitializer = mock(IssueInclusionPatternInitializer.class); + issue = mock(Issue.class); + chain = mock(IssueFilterChain.class); + when(chain.accept(issue)).thenReturn(true); + + ignoreFilter = new EnforceIssuesFilter(exclusionPatternInitializer); + } + + @Test + public void shouldPassToChainIfNoConfiguredPatterns() { + assertThat(ignoreFilter.accept(issue, chain)).isTrue(); + verify(chain).accept(issue); + } + + @Test + public void shouldPassToChainIfRuleDoesNotMatch() { + String rule = "rule"; + RuleKey ruleKey = mock(RuleKey.class); + when(ruleKey.toString()).thenReturn(rule); + when(issue.ruleKey()).thenReturn(ruleKey); + + IssuePattern matching = mock(IssuePattern.class); + WildcardPattern rulePattern = mock(WildcardPattern.class); + when(matching.getRulePattern()).thenReturn(rulePattern); + when(rulePattern.match(rule)).thenReturn(false); + when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching)); + + assertThat(ignoreFilter.accept(issue, chain)).isTrue(); + verify(chain).accept(issue); + } + + @Test + public void shouldAcceptIssueIfFullyMatched() { + String rule = "rule"; + String path = "org/sonar/api/Issue.java"; + String componentKey = "org.sonar.api.Issue"; + RuleKey ruleKey = mock(RuleKey.class); + when(ruleKey.toString()).thenReturn(rule); + when(issue.ruleKey()).thenReturn(ruleKey); + when(issue.componentKey()).thenReturn(componentKey); + + IssuePattern matching = mock(IssuePattern.class); + WildcardPattern rulePattern = mock(WildcardPattern.class); + when(matching.getRulePattern()).thenReturn(rulePattern); + when(rulePattern.match(rule)).thenReturn(true); + WildcardPattern pathPattern = mock(WildcardPattern.class); + when(matching.getResourcePattern()).thenReturn(pathPattern); + when(pathPattern.match(path)).thenReturn(true); + when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching)); + when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path); + + assertThat(ignoreFilter.accept(issue, chain)).isTrue(); + verifyZeroInteractions(chain); + } + + @Test + public void shouldRefuseIssueIfRuleMatchesButNotPath() { + String rule = "rule"; + String path = "org/sonar/api/Issue.java"; + String componentKey = "org.sonar.api.Issue"; + RuleKey ruleKey = mock(RuleKey.class); + when(ruleKey.toString()).thenReturn(rule); + when(issue.ruleKey()).thenReturn(ruleKey); + when(issue.componentKey()).thenReturn(componentKey); + + IssuePattern matching = mock(IssuePattern.class); + WildcardPattern rulePattern = mock(WildcardPattern.class); + when(matching.getRulePattern()).thenReturn(rulePattern); + when(rulePattern.match(rule)).thenReturn(true); + WildcardPattern pathPattern = mock(WildcardPattern.class); + when(matching.getResourcePattern()).thenReturn(pathPattern); + when(pathPattern.match(path)).thenReturn(false); + when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching)); + when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(path); + + assertThat(ignoreFilter.accept(issue, chain)).isFalse(); + verifyZeroInteractions(chain); + } + + @Test + public void shouldRefuseIssueIfRuleMatchesAndPathUnknown() { + String rule = "rule"; + String path = "org/sonar/api/Issue.java"; + String componentKey = "org.sonar.api.Issue"; + RuleKey ruleKey = mock(RuleKey.class); + when(ruleKey.toString()).thenReturn(rule); + when(issue.ruleKey()).thenReturn(ruleKey); + when(issue.componentKey()).thenReturn(componentKey); + + IssuePattern matching = mock(IssuePattern.class); + WildcardPattern rulePattern = mock(WildcardPattern.class); + when(matching.getRulePattern()).thenReturn(rulePattern); + when(rulePattern.match(rule)).thenReturn(true); + WildcardPattern pathPattern = mock(WildcardPattern.class); + when(matching.getResourcePattern()).thenReturn(pathPattern); + when(pathPattern.match(path)).thenReturn(false); + when(exclusionPatternInitializer.getMulticriteriaPatterns()).thenReturn(ImmutableList.of(matching)); + when(exclusionPatternInitializer.getPathForComponent(componentKey)).thenReturn(null); + + assertThat(ignoreFilter.accept(issue, chain)).isFalse(); + verifyZeroInteractions(chain); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java new file mode 100644 index 00000000000..2dae552a56a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IgnoreIssuesFilterTest.java @@ -0,0 +1,69 @@ +/* + * 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.batch.issue.ignore; + +import org.sonar.batch.issue.ignore.IgnoreIssuesFilter; +import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; +import org.sonar.batch.issue.ignore.pattern.IssuePattern; +import org.sonar.batch.issue.ignore.pattern.PatternMatcher; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.issue.Issue; +import org.sonar.api.issue.batch.IssueFilterChain; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class IgnoreIssuesFilterTest { + + private IssueExclusionPatternInitializer exclusionPatternInitializer; + private PatternMatcher exclusionPatternMatcher; + private IgnoreIssuesFilter ignoreFilter; + private Issue issue; + private IssueFilterChain chain; + + @Before + public void init() { + exclusionPatternMatcher = mock(PatternMatcher.class); + exclusionPatternInitializer = mock(IssueExclusionPatternInitializer.class); + when(exclusionPatternInitializer.getPatternMatcher()).thenReturn(exclusionPatternMatcher); + issue = mock(Issue.class); + chain = mock(IssueFilterChain.class); + when(chain.accept(issue)).thenReturn(true); + + ignoreFilter = new IgnoreIssuesFilter(exclusionPatternInitializer); + } + + @Test + public void shouldPassToChainIfMatcherHasNoPatternForIssue() { + when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(null); + + assertThat(ignoreFilter.accept(issue, chain)).isTrue(); + } + + @Test + public void shouldAcceptOrRefuseIfMatcherHasPatternForIssue() { + when(exclusionPatternMatcher.getMatchingPattern(issue)).thenReturn(mock(IssuePattern.class)); + + assertThat(ignoreFilter.accept(issue, chain)).isFalse(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java new file mode 100644 index 00000000000..ef93bd8a4c9 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/IssueExclusionsConfigurationTest.java @@ -0,0 +1,33 @@ +/* + * 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.batch.issue.ignore; + +import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; + +import org.junit.Test; +import static org.fest.assertions.Assertions.assertThat; + +public class IssueExclusionsConfigurationTest { + @Test + public void justForCoverage() { + assertThat(IssueExclusionsConfiguration.getPropertyDefinitions()).hasSize(4); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java new file mode 100644 index 00000000000..fb769ec2569 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java @@ -0,0 +1,142 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; +import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.Settings; +import org.sonar.api.utils.SonarException; +import static org.fest.assertions.Assertions.assertThat; + +public class IssueExclusionPatternInitializerTest { + + private IssueExclusionPatternInitializer patternsInitializer; + + private Settings settings; + + @Before + public void init() { + settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions())); + patternsInitializer = new IssueExclusionPatternInitializer(settings); + } + + @Test + public void testNoConfiguration() { + patternsInitializer.initPatterns(); + assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse(); + assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0); + } + + @Test + public void shouldHavePatternsBasedOnMulticriteriaPattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1,2"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber"); + patternsInitializer.initPatterns(); + + assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); + assertThat(patternsInitializer.hasFileContentPattern()).isFalse(); + assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue(); + assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2); + assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0); + assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0); + + patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar"); + patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz"); + patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello"); + + assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Bar")).hasSize(1); + assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Baz")).hasSize(0); + assertThat(patternsInitializer.getPatternMatcher().getPatternsForComponent("org.foo.Hello")).hasSize(1); + + } + + @Test(expected = SonarException.class) + public void shouldLogInvalidResourceKey() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, ""); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); + patternsInitializer.initPatterns(); + } + + @Test(expected = SonarException.class) + public void shouldLogInvalidRuleKey() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY, "1"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "*"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_EXCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, ""); + patternsInitializer.initPatterns(); + } + + @Test + public void shouldReturnBlockPattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1,2,3"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// SONAR-OFF"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// FOO-OFF"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".2." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// FOO-ON"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, "// IGNORE-TO-EOF"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".3." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, ""); + patternsInitializer.loadFileContentPatterns(); + + assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); + assertThat(patternsInitializer.hasFileContentPattern()).isTrue(); + assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse(); + assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0); + assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(3); + assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(0); + } + + @Test(expected = SonarException.class) + public void shouldLogInvalidStartBlockPattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY, "1"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.BEGIN_BLOCK_REGEXP, ""); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_BLOCK_KEY + ".1." + IssueExclusionsConfiguration.END_BLOCK_REGEXP, "// SONAR-ON"); + patternsInitializer.loadFileContentPatterns(); + } + + @Test + public void shouldReturnAllFilePattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1,2"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, "@SONAR-IGNORE-ALL"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".2." + IssueExclusionsConfiguration.FILE_REGEXP, "//FOO-IGNORE-ALL"); + patternsInitializer.loadFileContentPatterns(); + + assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); + assertThat(patternsInitializer.hasFileContentPattern()).isTrue(); + assertThat(patternsInitializer.hasMulticriteriaPatterns()).isFalse(); + assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(0); + assertThat(patternsInitializer.getBlockPatterns().size()).isEqualTo(0); + assertThat(patternsInitializer.getAllFilePatterns().size()).isEqualTo(2); + } + + @Test(expected = SonarException.class) + public void shouldLogInvalidAllFilePattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY, "1"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_ALLFILE_KEY + ".1." + IssueExclusionsConfiguration.FILE_REGEXP, ""); + patternsInitializer.loadFileContentPatterns(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java new file mode 100644 index 00000000000..59542512bfc --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java @@ -0,0 +1,72 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.IssueExclusionsConfiguration; +import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.Settings; +import static org.fest.assertions.Assertions.assertThat; + +public class IssueInclusionPatternInitializerTest { + + private IssueInclusionPatternInitializer patternsInitializer; + + private Settings settings; + + @Before + public void init() { + settings = new Settings(new PropertyDefinitions(IssueExclusionsConfiguration.getPropertyDefinitions())); + patternsInitializer = new IssueInclusionPatternInitializer(settings); + } + + @Test + public void testNoConfiguration() { + patternsInitializer.initPatterns(); + assertThat(patternsInitializer.hasConfiguredPatterns()).isFalse(); + } + + @Test + public void shouldHavePatternsBasedOnMulticriteriaPattern() { + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY, "1,2"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Bar.java"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".1." + IssueExclusionsConfiguration.RULE_KEY, "*"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RESOURCE_KEY, "org/foo/Hello.java"); + settings.setProperty(IssueExclusionsConfiguration.PATTERNS_MULTICRITERIA_INCLUSION_KEY + ".2." + IssueExclusionsConfiguration.RULE_KEY, "checkstyle:MagicNumber"); + patternsInitializer.initPatterns(); + + assertThat(patternsInitializer.hasConfiguredPatterns()).isTrue(); + assertThat(patternsInitializer.hasMulticriteriaPatterns()).isTrue(); + assertThat(patternsInitializer.getMulticriteriaPatterns().size()).isEqualTo(2); + + patternsInitializer.initializePatternsForPath("org/foo/Bar.java", "org.foo.Bar"); + patternsInitializer.initializePatternsForPath("org/foo/Baz.java", "org.foo.Baz"); + patternsInitializer.initializePatternsForPath("org/foo/Hello.java", "org.foo.Hello"); + + assertThat(patternsInitializer.getPathForComponent("org.foo.Bar")).isEqualTo("org/foo/Bar.java"); + assertThat(patternsInitializer.getPathForComponent("org.foo.Baz")).isEqualTo("org/foo/Baz.java"); + assertThat(patternsInitializer.getPathForComponent("org.foo.Hello")).isEqualTo("org/foo/Hello.java"); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java new file mode 100644 index 00000000000..3c9d43dfe13 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/IssuePatternTest.java @@ -0,0 +1,115 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.pattern.IssuePattern; + +import org.junit.Test; +import org.sonar.api.issue.Issue; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rules.Rule; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class IssuePatternTest { + + @Test + public void shouldMatchLines() { + IssuePattern pattern = new IssuePattern("*", "*"); + pattern.addLine(12).addLine(15).addLineRange(20, 25); + + assertThat(pattern.matchLine(3)).isFalse(); + assertThat(pattern.matchLine(12)).isTrue(); + assertThat(pattern.matchLine(14)).isFalse(); + assertThat(pattern.matchLine(21)).isTrue(); + assertThat(pattern.matchLine(6599)).isFalse(); + } + + @Test + public void shouldMatchJavaFile() { + String javaFile = "org.foo.Bar"; + assertThat(new IssuePattern("org.foo.Bar", "*").matchResource(javaFile)).isTrue(); + assertThat(new IssuePattern("org.foo.*", "*").matchResource(javaFile)).isTrue(); + assertThat(new IssuePattern("*Bar", "*").matchResource(javaFile)).isTrue(); + assertThat(new IssuePattern("*", "*").matchResource(javaFile)).isTrue(); + assertThat(new IssuePattern("org.*.?ar", "*").matchResource(javaFile)).isTrue(); + + assertThat(new IssuePattern("org.other.Hello", "*").matchResource(javaFile)).isFalse(); + assertThat(new IssuePattern("org.foo.Hello", "*").matchResource(javaFile)).isFalse(); + assertThat(new IssuePattern("org.*.??ar", "*").matchResource(javaFile)).isFalse(); + assertThat(new IssuePattern("org.*.??ar", "*").matchResource(null)).isFalse(); + assertThat(new IssuePattern("org.*.??ar", "*").matchResource("plop")).isFalse(); + } + + @Test + public void shouldMatchRule() { + RuleKey rule = Rule.create("checkstyle", "IllegalRegexp", "").ruleKey(); + assertThat(new IssuePattern("*", "*").matchRule(rule)).isTrue(); + assertThat(new IssuePattern("*", "checkstyle:*").matchRule(rule)).isTrue(); + assertThat(new IssuePattern("*", "checkstyle:IllegalRegexp").matchRule(rule)).isTrue(); + assertThat(new IssuePattern("*", "checkstyle:Illegal*").matchRule(rule)).isTrue(); + assertThat(new IssuePattern("*", "*:*Illegal*").matchRule(rule)).isTrue(); + + assertThat(new IssuePattern("*", "pmd:IllegalRegexp").matchRule(rule)).isFalse(); + assertThat(new IssuePattern("*", "pmd:*").matchRule(rule)).isFalse(); + assertThat(new IssuePattern("*", "*:Foo*IllegalRegexp").matchRule(rule)).isFalse(); + } + + @Test + public void shouldMatchViolation() { + Rule rule = Rule.create("checkstyle", "IllegalRegexp", ""); + String javaFile = "org.foo.Bar"; + + IssuePattern pattern = new IssuePattern("*", "*"); + pattern.addLine(12); + + assertThat(pattern.match(create(rule, javaFile, null))).isFalse(); + assertThat(pattern.match(create(rule, javaFile, 12))).isTrue(); + assertThat(pattern.match(create((Rule) null, javaFile, 5))).isFalse(); + assertThat(pattern.match(create(rule, null, null))).isFalse(); + assertThat(pattern.match(create((Rule) null, null, null))).isFalse(); + } + + 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; + } + + @Test + public void shouldNotMatchNullRule() { + assertThat(new IssuePattern("*", "*").matchRule(null)).isFalse(); + } + + @Test + public void shouldPrintPatternToString() { + IssuePattern pattern = new IssuePattern("*", "checkstyle:*"); + + assertThat(pattern.toString()).isEqualTo("IssuePattern[resourcePattern=*,rulePattern=checkstyle:*,lines=[],lineRanges=[],beginBlockRegexp=<null>,endBlockRegexp=<null>,allFileRegexp=<null>,checkLines=true]"); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java new file mode 100644 index 00000000000..21df72ba862 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/LineRangeTest.java @@ -0,0 +1,74 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.pattern.LineRange; + +import org.junit.Test; +import static org.fest.assertions.Assertions.assertThat; + +public class LineRangeTest { + + @Test(expected = IllegalArgumentException.class) + public void lineRangeShouldBeOrdered() { + new LineRange(25, 12); + } + + @Test + public void shouldConvertLineRangeToLines() { + LineRange range = new LineRange(12, 15); + + assertThat(range.toLines()).containsOnly(12, 13, 14, 15); + } + + @Test + public void shouldTestInclusionInRangeOfLines() { + LineRange range = new LineRange(12, 15); + + assertThat(range.in(3)).isFalse(); + assertThat(range.in(12)).isTrue(); + assertThat(range.in(13)).isTrue(); + assertThat(range.in(14)).isTrue(); + assertThat(range.in(15)).isTrue(); + assertThat(range.in(16)).isFalse(); + } + + @Test + public void testToString() throws Exception { + assertThat(new LineRange(12, 15).toString()).isEqualTo("[12-15]"); + } + + @Test + public void testEquals() throws Exception { + LineRange range = new LineRange(12, 15); + assertThat(range).isEqualTo(range); + assertThat(range).isEqualTo(new LineRange(12, 15)); + assertThat(range).isNotEqualTo(new LineRange(12, 2000)); + assertThat(range).isNotEqualTo(new LineRange(1000, 2000)); + assertThat(range).isNotEqualTo(null); + assertThat(range).isNotEqualTo(new StringBuffer()); + } + + @Test + public void testHashCode() throws Exception { + assertThat(new LineRange(12, 15).hashCode()).isEqualTo(new LineRange(12, 15).hashCode()); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java new file mode 100644 index 00000000000..b993e82e8ff --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternDecoderTest.java @@ -0,0 +1,191 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.pattern.IssuePattern; +import org.sonar.batch.issue.ignore.pattern.PatternDecoder; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.SonarException; + +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; + +public class PatternDecoderTest { + + private PatternDecoder decoder = new PatternDecoder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void shouldReadString() { + String patternsList = "# a comment followed by a blank line\n\n" + + "# suppress all violations\n" + + "*;*;*\n\n" + + "# exclude a Java file\n" + + "com.foo.Bar;*;*\n\n" + + "# exclude a Java package\n" + + "com.foo.*;*;*\n\n" + + "# exclude a specific rule\n" + + "*;checkstyle:IllegalRegexp;*\n\n" + + "# exclude a specific rule on a specific file\n" + + "com.foo.Bar;checkstyle:IllegalRegexp;*\n"; + List<IssuePattern> patterns = decoder.decode(patternsList); + + assertThat(patterns).hasSize(5); + } + + @Test + public void shouldCheckFormatOfResource() { + assertThat(PatternDecoder.isResource("")).isFalse(); + assertThat(PatternDecoder.isResource("*")).isTrue(); + assertThat(PatternDecoder.isResource("com.foo.*")).isTrue(); + } + + @Test + public void shouldCheckFormatOfRule() { + assertThat(PatternDecoder.isRule("")).isFalse(); + assertThat(PatternDecoder.isRule("*")).isTrue(); + assertThat(PatternDecoder.isRule("com.foo.*")).isTrue(); + } + + @Test + public void shouldCheckFormatOfLinesRange() { + assertThat(PatternDecoder.isLinesRange("")).isFalse(); + assertThat(PatternDecoder.isLinesRange(" ")).isFalse(); + assertThat(PatternDecoder.isLinesRange("12")).isFalse(); + assertThat(PatternDecoder.isLinesRange("12,212")).isFalse(); + + assertThat(PatternDecoder.isLinesRange("*")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[]")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[13]")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[13,24]")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[13,24,25-500]")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[24-65]")).isTrue(); + assertThat(PatternDecoder.isLinesRange("[13,24-65,84-89,122]")).isTrue(); + } + + @Test + public void shouldReadStarPatterns() { + IssuePattern pattern = decoder.decodeLine("*;*;*"); + + assertThat(pattern.getResourcePattern().toString()).isEqualTo("*"); + assertThat(pattern.getRulePattern().toString()).isEqualTo("*"); + assertThat(pattern.isCheckLines()).isFalse(); + } + + @Test + public void shouldReadLineIds() { + IssuePattern pattern = decoder.decodeLine("*;*;[10,25,98]"); + + assertThat(pattern.isCheckLines()).isTrue(); + assertThat(pattern.getAllLines()).containsOnly(10, 25, 98); + } + + @Test + public void shouldReadRangeOfLineIds() { + IssuePattern pattern = decoder.decodeLine("*;*;[10-12,25,97-100]"); + + assertThat(pattern.isCheckLines()).isTrue(); + assertThat(pattern.getAllLines()).containsOnly(10, 11, 12, 25, 97, 98, 99, 100); + } + + @Test + public void shouldNotExcludeLines() { + // [] is different than * + // - all violations are excluded on * + // * no violations are excluded on [] + IssuePattern pattern = decoder.decodeLine("*;*;[]"); + + assertThat(pattern.isCheckLines()).isTrue(); + assertThat(pattern.getAllLines()).isEmpty(); + } + + @Test + public void shouldReadBlockPattern() { + IssuePattern pattern = decoder.decodeLine("SONAR-OFF;SONAR-ON"); + + assertThat(pattern.getResourcePattern()).isNull(); + assertThat(pattern.getBeginBlockRegexp()).isEqualTo("SONAR-OFF"); + assertThat(pattern.getEndBlockRegexp()).isEqualTo("SONAR-ON"); + } + + @Test + public void shouldReadAllFilePattern() { + IssuePattern pattern = decoder.decodeLine("SONAR-ALL-OFF"); + + assertThat(pattern.getResourcePattern()).isNull(); + assertThat(pattern.getAllFileRegexp()).isEqualTo("SONAR-ALL-OFF"); + } + + @Test + public void shouldFailToReadUncorrectLine1() { + thrown.expect(SonarException.class); + thrown.expectMessage("Exclusions > Issues : Invalid format. The following line has more than 3 fields separated by comma"); + + decoder.decode(";;;;"); + } + + @Test + public void shouldFailToReadUncorrectLine3() { + thrown.expect(SonarException.class); + thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a resource pattern"); + + decoder.decode(";*;*"); + } + + @Test + public void shouldFailToReadUncorrectLine4() { + thrown.expect(SonarException.class); + thrown.expectMessage("Exclusions > Issues : Invalid format. The second field does not define a rule pattern"); + + decoder.decode("*;;*"); + } + + @Test + public void shouldFailToReadUncorrectLine5() { + thrown.expect(SonarException.class); + thrown.expectMessage("Exclusions > Issues : Invalid format. The third field does not define a range of lines"); + + decoder.decode("*;*;blabla"); + } + + @Test + public void shouldFailToReadUncorrectLine6() { + thrown.expect(SonarException.class); + thrown.expectMessage("Exclusions > Issues : Invalid format. The first field does not define a regular expression"); + + decoder.decode(";ON"); + } + + @Test + public void shouldAcceptEmptyEndBlockRegexp() { + IssuePattern pattern = decoder.decodeLine("OFF;"); + + assertThat(pattern.getResourcePattern()).isNull(); + assertThat(pattern.getBeginBlockRegexp()).isEqualTo("OFF"); + assertThat(pattern.getEndBlockRegexp()).isEmpty(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java new file mode 100644 index 00000000000..a948aac47f7 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/pattern/PatternMatcherTest.java @@ -0,0 +1,124 @@ +/* + * 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.batch.issue.ignore.pattern; + +import org.sonar.batch.issue.ignore.pattern.IssuePattern; +import org.sonar.batch.issue.ignore.pattern.LineRange; +import org.sonar.batch.issue.ignore.pattern.PatternDecoder; +import org.sonar.batch.issue.ignore.pattern.PatternMatcher; + +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/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java new file mode 100644 index 00000000000..8f8eba536f7 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java @@ -0,0 +1,175 @@ +/* + * 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.batch.issue.ignore.scanner; + +import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; +import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; +import org.sonar.batch.issue.ignore.pattern.PatternMatcher; +import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; +import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner; + +import com.google.common.base.Charsets; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.scan.filesystem.FileQuery; +import org.sonar.api.scan.filesystem.internal.DefaultInputFile; +import org.sonar.api.scan.filesystem.internal.InputFileBuilder; +import org.sonar.api.utils.SonarException; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +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.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +public class IssueExclusionsLoaderTest { + + private IssueExclusionsLoader scanner; + + @Mock + private IssueExclusionsRegexpScanner regexpScanner; + @Mock + private IssueInclusionPatternInitializer inclusionPatternInitializer; + @Mock + private IssueExclusionPatternInitializer exclusionPatternInitializer; + @Mock + private PatternMatcher patternMatcher; + @Mock + private DefaultModuleFileSystem fs; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private File baseDir; + + @Before + public void init() throws IOException { + baseDir = temp.newFolder(); + MockitoAnnotations.initMocks(this); + + when(fs.sourceCharset()).thenReturn(UTF_8); + + scanner = new IssueExclusionsLoader(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs); + } + + @Test + public void testToString() throws Exception { + assertThat(scanner.toString()).isEqualTo("Issues Exclusions - Source Scanner"); + } + + @Test + public void shouldExecute() throws IOException { + when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true); + when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true); + assertThat(scanner.shouldExecuteOnProject(null)).isTrue(); + + when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true); + when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false); + assertThat(scanner.shouldExecuteOnProject(null)).isTrue(); + + when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false); + when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(true); + assertThat(scanner.shouldExecuteOnProject(null)).isTrue(); + + when(exclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false); + when(inclusionPatternInitializer.hasConfiguredPatterns()).thenReturn(false); + assertThat(scanner.shouldExecuteOnProject(null)).isFalse(); + + } + + @Test + public void shouldAnalyseProject() throws IOException { + File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); + File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); + when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList( + new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java") + .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java") + .build(), + new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java") + .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java") + .build())); + + when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true); + + scanner.execute(); + + verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java"); + verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java"); + verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java"); + verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java"); + verify(regexpScanner).scan("polop:src/main/java/Foo.java", javaFile1, UTF_8); + verify(regexpScanner).scan("polop:src/test/java/FooTest.java", javaTestFile1, UTF_8); + } + + @Test + public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException { + File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); + File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); + when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList( + new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java") + .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java") + .build(), + new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java") + .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java") + .build())); + + when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false); + + scanner.execute(); + + verify(inclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java"); + verify(inclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java"); + verify(exclusionPatternInitializer).initializePatternsForPath("src/main/java/Foo.java", "polop:src/main/java/Foo.java"); + verify(exclusionPatternInitializer).initializePatternsForPath("src/test/java/FooTest.java", "polop:src/test/java/FooTest.java"); + verifyZeroInteractions(regexpScanner); + } + + @Test + public void shouldReportFailure() throws IOException { + File phpFile1 = new File(baseDir, "src/Foo.php"); + when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList( + new InputFileBuilder(phpFile1, Charsets.UTF_8, "src/Foo.php") + .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/Foo.php") + .build())); + + when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true); + doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8); + + thrown.expect(SonarException.class); + thrown.expectMessage("Unable to read the source file"); + + scanner.execute(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java new file mode 100644 index 00000000000..d50c3778e32 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsRegexpScannerTest.java @@ -0,0 +1,163 @@ +/* + * 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.batch.issue.ignore.scanner; + +import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; +import org.sonar.batch.issue.ignore.pattern.IssuePattern; +import org.sonar.batch.issue.ignore.pattern.LineRange; +import org.sonar.batch.issue.ignore.pattern.PatternMatcher; +import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner; + +import com.google.common.collect.Sets; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.test.TestUtils; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Set; + +import static com.google.common.base.Charsets.UTF_8; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +public class IssueExclusionsRegexpScannerTest { + + private IssueExclusionsRegexpScanner regexpScanner; + + private String javaFile; + @Mock + private IssueExclusionPatternInitializer patternsInitializer; + @Mock + private PatternMatcher patternMatcher; + @Mock + private IssuePattern allFilePattern; + @Mock + private IssuePattern blockPattern1; + @Mock + private IssuePattern blockPattern2; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + when(allFilePattern.getAllFileRegexp()).thenReturn("@SONAR-IGNORE-ALL"); + when(blockPattern1.getBeginBlockRegexp()).thenReturn("// SONAR-OFF"); + when(blockPattern1.getEndBlockRegexp()).thenReturn("// SONAR-ON"); + when(blockPattern2.getBeginBlockRegexp()).thenReturn("// FOO-OFF"); + when(blockPattern2.getEndBlockRegexp()).thenReturn("// FOO-ON"); + when(patternsInitializer.getAllFilePatterns()).thenReturn(Arrays.asList(allFilePattern)); + when(patternsInitializer.getBlockPatterns()).thenReturn(Arrays.asList(blockPattern1, blockPattern2)); + when(patternsInitializer.getPatternMatcher()).thenReturn(patternMatcher); + + regexpScanner = new IssueExclusionsRegexpScanner(patternsInitializer); + verify(patternsInitializer, times(1)).getAllFilePatterns(); + verify(patternsInitializer, times(1)).getBlockPatterns(); + + javaFile = "org.sonar.test.MyFile"; + } + + @Test + public void shouldDoNothing() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-no-regexp.txt"), UTF_8); + + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeFile() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp.txt"), UTF_8); + + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeFileEvenIfAlsoDoubleRegexps() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-single-regexp-and-double-regexp.txt"), UTF_8); + + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeResource(javaFile); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeLines() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp.txt"), UTF_8); + + Set<LineRange> lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(21, 25)); + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeLinesTillTheEnd() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-unfinished.txt"), UTF_8); + + Set<LineRange> lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(21, 34)); + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeSeveralLineRanges() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-twice.txt"), UTF_8); + + Set<LineRange> lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(21, 25)); + lineRanges.add(new LineRange(29, 33)); + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeLinesWithWrongOrder() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-wrong-order.txt"), UTF_8); + + Set<LineRange> lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(25, 35)); + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges); + verifyNoMoreInteractions(patternsInitializer); + } + + @Test + public void shouldAddPatternToExcludeLinesWithMess() throws IOException { + regexpScanner.scan(javaFile, TestUtils.getResource(getClass(), "file-with-double-regexp-mess.txt"), UTF_8); + + Set<LineRange> lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(21, 29)); + verify(patternsInitializer).getPatternMatcher(); + verify(patternMatcher, times(1)).addPatternToExcludeLines(javaFile, lineRanges); + verifyNoMoreInteractions(patternsInitializer); + } + +} |