From: Julien HENRY Date: Mon, 17 Feb 2014 10:51:16 +0000 (+0100) Subject: Ensure that JavaSquidSensor is executed after exclusions initialization X-Git-Tag: 4.2~111 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=5debbecc152bf7aff83601e6a39d4247c8f522df;p=sonarqube.git Ensure that JavaSquidSensor is executed after exclusions initialization --- 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 248c13853ff..c39060a912c 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 @@ -23,8 +23,8 @@ package org.sonar.plugins.core.issue.ignore; import com.google.common.collect.ImmutableList; import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.scanner.RegexpScanner; -import org.sonar.plugins.core.issue.ignore.scanner.SourceScanner; +import org.sonar.plugins.core.issue.ignore.scanner.IgnoreIssuesRegexpScanner; +import org.sonar.plugins.core.issue.ignore.scanner.IgnoreIssuesSourceScanner; import java.util.List; @@ -41,8 +41,8 @@ public final class IgnoreIssuesPlugin { extensions.add( InclusionPatternInitializer.class, ExclusionPatternInitializer.class, - RegexpScanner.class, - SourceScanner.class, + IgnoreIssuesRegexpScanner.class, + IgnoreIssuesSourceScanner.class, EnforceIssuesFilter.class, IgnoreIssuesFilter.class); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java new file mode 100644 index 00000000000..d6fa2d26fa6 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScanner.java @@ -0,0 +1,198 @@ +/* + * 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.scanner; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchExtension; +import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; +import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern; +import org.sonar.plugins.core.issue.ignore.pattern.LineRange; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Set; + +public class IgnoreIssuesRegexpScanner implements BatchExtension { + + private static final Logger LOG = LoggerFactory.getLogger(IgnoreIssuesRegexpScanner.class); + + private ExclusionPatternInitializer exclusionPatternInitializer; + private List allFilePatterns; + private List blockMatchers; + + // fields to be reset at every new scan + private DoubleRegexpMatcher currentMatcher; + private int fileLength; + private List lineExclusions; + private LineExclusion currentLineExclusion; + + public IgnoreIssuesRegexpScanner(ExclusionPatternInitializer patternsInitializer) { + this.exclusionPatternInitializer = patternsInitializer; + + lineExclusions = Lists.newArrayList(); + allFilePatterns = Lists.newArrayList(); + blockMatchers = Lists.newArrayList(); + + for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) { + allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp())); + } + for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) { + blockMatchers.add(new DoubleRegexpMatcher( + java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()), + java.util.regex.Pattern.compile(pattern.getEndBlockRegexp()))); + } + + init(); + } + + private void init() { + currentMatcher = null; + fileLength = 0; + lineExclusions.clear(); + currentLineExclusion = null; + } + + public void scan(String resource, File file, Charset sourcesEncoding) throws IOException { + LOG.debug("Scanning {}", resource); + init(); + + List lines = FileUtils.readLines(file, sourcesEncoding.name()); + int lineIndex = 0; + for (String line : lines) { + lineIndex++; + if (line.trim().length() == 0) { + continue; + } + + // 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()) { + exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeResource(resource); + // nothing more to do on this file + LOG.debug("- Exclusion pattern '{}': every violation in this file will be ignored.", pattern); + return; + } + } + + // then check the double regexps if we're still here + checkDoubleRegexps(line, lineIndex); + } + + if (currentMatcher != null && !currentMatcher.hasSecondPattern()) { + // this will happen when there is a start block regexp but no end block regexp + endExclusion(lineIndex + 1); + } + + // now create the new line-based pattern for this file if there are exclusions + fileLength = lineIndex; + if (!lineExclusions.isEmpty()) { + Set lineRanges = convertLineExclusionsToLineRanges(); + LOG.debug("- Line exclusions found: {}", lineRanges); + exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeLines(resource, lineRanges); + } + } + + private Set convertLineExclusionsToLineRanges() { + Set lineRanges = Sets.newHashSet(); + for (LineExclusion lineExclusion : lineExclusions) { + lineRanges.add(lineExclusion.toLineRange()); + } + return lineRanges; + } + + private void checkDoubleRegexps(String line, int lineIndex) { + if (currentMatcher == null) { + for (DoubleRegexpMatcher matcher : blockMatchers) { + if (matcher.matchesFirstPattern(line)) { + startExclusion(lineIndex); + currentMatcher = matcher; + break; + } + } + } else { + if (currentMatcher.matchesSecondPattern(line)) { + endExclusion(lineIndex); + currentMatcher = null; + } + } + } + + private void startExclusion(int lineIndex) { + currentLineExclusion = new LineExclusion(lineIndex); + lineExclusions.add(currentLineExclusion); + } + + private void endExclusion(int lineIndex) { + currentLineExclusion.setEnd(lineIndex); + currentLineExclusion = null; + } + + private class LineExclusion { + + private int start; + private int end; + + LineExclusion(int start) { + this.start = start; + this.end = -1; + } + + void setEnd(int end) { + this.end = end; + } + + public LineRange toLineRange() { + return new LineRange(start, end == -1 ? fileLength : end); + } + + } + + private static class DoubleRegexpMatcher { + + private java.util.regex.Pattern firstPattern; + private java.util.regex.Pattern secondPattern; + + DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) { + this.firstPattern = firstPattern; + this.secondPattern = secondPattern; + } + + boolean matchesFirstPattern(String line) { + return firstPattern.matcher(line).find(); + } + + boolean matchesSecondPattern(String line) { + return hasSecondPattern() && secondPattern.matcher(line).find(); + } + + boolean hasSecondPattern() { + return StringUtils.isNotEmpty(secondPattern.toString()); + } + } + +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java new file mode 100644 index 00000000000..f88696d7128 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScanner.java @@ -0,0 +1,91 @@ +/* + * 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.scanner; + +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.Phase; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.api.scan.filesystem.FileQuery; +import org.sonar.api.scan.filesystem.InputFile; +import org.sonar.api.scan.filesystem.internal.DefaultInputFile; +import org.sonar.api.utils.SonarException; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; +import org.sonar.java.api.JavaUtils; +import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; +import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer; + +import java.nio.charset.Charset; + +@Phase(name = Phase.Name.PRE) +// Issue Exclusions must be computed before JavaSquidSensor is executed and creates issues +@DependedUpon(value = JavaUtils.BARRIER_BEFORE_SQUID) +public final class IgnoreIssuesSourceScanner implements Sensor { + + private final IgnoreIssuesRegexpScanner regexpScanner; + private final ExclusionPatternInitializer exclusionPatternInitializer; + private final InclusionPatternInitializer inclusionPatternInitializer; + private final DefaultModuleFileSystem fileSystem; + + public IgnoreIssuesSourceScanner(IgnoreIssuesRegexpScanner regexpScanner, ExclusionPatternInitializer exclusionPatternInitializer, InclusionPatternInitializer inclusionPatternInitializer, + DefaultModuleFileSystem fileSystem) { + this.regexpScanner = regexpScanner; + this.exclusionPatternInitializer = exclusionPatternInitializer; + this.inclusionPatternInitializer = inclusionPatternInitializer; + this.fileSystem = fileSystem; + } + + public boolean shouldExecuteOnProject(Project project) { + return inclusionPatternInitializer.hasConfiguredPatterns() + || exclusionPatternInitializer.hasConfiguredPatterns(); + } + + /** + * {@inheritDoc} + */ + public void analyse(Project project, SensorContext context) { + Charset sourcesEncoding = fileSystem.sourceCharset(); + + for (InputFile inputFile : fileSystem.inputFiles(FileQuery.all())) { + try { + String componentEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY); + if (componentEffectiveKey != null) { + String path = inputFile.path(); + inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey); + exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey); + if (exclusionPatternInitializer.hasFileContentPattern()) { + regexpScanner.scan(componentEffectiveKey, inputFile.file(), sourcesEncoding); + } + } + } catch (Exception e) { + throw new SonarException("Unable to read the source file : '" + inputFile.absolutePath() + "' with the charset : '" + + sourcesEncoding.name() + "'.", e); + } + } + } + + @Override + public String toString() { + return "Issues Exclusions - Source Scanner"; + } + +} 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 deleted file mode 100644 index b479000d013..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScanner.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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.scanner; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchExtension; -import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern; -import org.sonar.plugins.core.issue.ignore.pattern.LineRange; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.List; -import java.util.Set; - -public class RegexpScanner implements BatchExtension { - - private static final Logger LOG = LoggerFactory.getLogger(RegexpScanner.class); - - private ExclusionPatternInitializer exclusionPatternInitializer; - private List allFilePatterns; - private List blockMatchers; - - // fields to be reset at every new scan - private DoubleRegexpMatcher currentMatcher; - private int fileLength; - private List lineExclusions; - private LineExclusion currentLineExclusion; - - public RegexpScanner(ExclusionPatternInitializer patternsInitializer) { - this.exclusionPatternInitializer = patternsInitializer; - - lineExclusions = Lists.newArrayList(); - allFilePatterns = Lists.newArrayList(); - blockMatchers = Lists.newArrayList(); - - for (IssuePattern pattern : patternsInitializer.getAllFilePatterns()) { - allFilePatterns.add(java.util.regex.Pattern.compile(pattern.getAllFileRegexp())); - } - for (IssuePattern pattern : patternsInitializer.getBlockPatterns()) { - blockMatchers.add(new DoubleRegexpMatcher( - java.util.regex.Pattern.compile(pattern.getBeginBlockRegexp()), - java.util.regex.Pattern.compile(pattern.getEndBlockRegexp()))); - } - - init(); - } - - private void init() { - currentMatcher = null; - fileLength = 0; - lineExclusions.clear(); - currentLineExclusion = null; - } - - public void scan(String resource, File file, Charset sourcesEncoding) throws IOException { - LOG.debug("Scanning {}", resource); - init(); - - List lines = FileUtils.readLines(file, sourcesEncoding.name()); - int lineIndex = 0; - for (String line : lines) { - lineIndex++; - if (line.trim().length() == 0) { - continue; - } - - // 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()) { - exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeResource(resource); - // nothing more to do on this file - LOG.debug("- Exclusion pattern '{}': every violation in this file will be ignored.", pattern); - return; - } - } - - // then check the double regexps if we're still here - checkDoubleRegexps(line, lineIndex); - } - - if (currentMatcher != null && !currentMatcher.hasSecondPattern()) { - // this will happen when there is a start block regexp but no end block regexp - endExclusion(lineIndex + 1); - } - - // now create the new line-based pattern for this file if there are exclusions - fileLength = lineIndex; - if (!lineExclusions.isEmpty()) { - Set lineRanges = convertLineExclusionsToLineRanges(); - LOG.debug("- Line exclusions found: {}", lineRanges); - exclusionPatternInitializer.getPatternMatcher().addPatternToExcludeLines(resource, lineRanges); - } - } - - private Set convertLineExclusionsToLineRanges() { - Set lineRanges = Sets.newHashSet(); - for (LineExclusion lineExclusion : lineExclusions) { - lineRanges.add(lineExclusion.toLineRange()); - } - return lineRanges; - } - - private void checkDoubleRegexps(String line, int lineIndex) { - if (currentMatcher == null) { - for (DoubleRegexpMatcher matcher : blockMatchers) { - if (matcher.matchesFirstPattern(line)) { - startExclusion(lineIndex); - currentMatcher = matcher; - break; - } - } - } else { - if (currentMatcher.matchesSecondPattern(line)) { - endExclusion(lineIndex); - currentMatcher = null; - } - } - } - - private void startExclusion(int lineIndex) { - currentLineExclusion = new LineExclusion(lineIndex); - lineExclusions.add(currentLineExclusion); - } - - private void endExclusion(int lineIndex) { - currentLineExclusion.setEnd(lineIndex); - currentLineExclusion = null; - } - - private class LineExclusion { - - private int start; - private int end; - - LineExclusion(int start) { - this.start = start; - this.end = -1; - } - - void setEnd(int end) { - this.end = end; - } - - public LineRange toLineRange() { - return new LineRange(start, end == -1 ? fileLength : end); - } - - } - - private static class DoubleRegexpMatcher { - - private java.util.regex.Pattern firstPattern; - private java.util.regex.Pattern secondPattern; - - DoubleRegexpMatcher(java.util.regex.Pattern firstPattern, java.util.regex.Pattern secondPattern) { - this.firstPattern = firstPattern; - this.secondPattern = secondPattern; - } - - boolean matchesFirstPattern(String line) { - return firstPattern.matcher(line).find(); - } - - boolean matchesSecondPattern(String line) { - return hasSecondPattern() && secondPattern.matcher(line).find(); - } - - boolean hasSecondPattern() { - return StringUtils.isNotEmpty(secondPattern.toString()); - } - } - -} 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 deleted file mode 100644 index 23a61888fee..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScanner.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.scanner; - -import org.sonar.api.scan.filesystem.InputFile; - -import org.sonar.api.batch.Phase; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; -import org.sonar.api.scan.filesystem.FileQuery; -import org.sonar.api.scan.filesystem.internal.DefaultInputFile; -import org.sonar.api.utils.SonarException; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer; - -import java.nio.charset.Charset; - -@Phase(name = Phase.Name.PRE) -public final class SourceScanner implements Sensor { - - private final RegexpScanner regexpScanner; - private final ExclusionPatternInitializer exclusionPatternInitializer; - private final InclusionPatternInitializer inclusionPatternInitializer; - private final DefaultModuleFileSystem fileSystem; - - public SourceScanner(RegexpScanner regexpScanner, ExclusionPatternInitializer exclusionPatternInitializer, InclusionPatternInitializer inclusionPatternInitializer, - DefaultModuleFileSystem fileSystem) { - this.regexpScanner = regexpScanner; - this.exclusionPatternInitializer = exclusionPatternInitializer; - this.inclusionPatternInitializer = inclusionPatternInitializer; - this.fileSystem = fileSystem; - } - - public boolean shouldExecuteOnProject(Project project) { - return inclusionPatternInitializer.hasConfiguredPatterns() - || exclusionPatternInitializer.hasConfiguredPatterns(); - } - - /** - * {@inheritDoc} - */ - public void analyse(Project project, SensorContext context) { - Charset sourcesEncoding = fileSystem.sourceCharset(); - - for (InputFile inputFile : fileSystem.inputFiles(FileQuery.all())) { - try { - String componentEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY); - if (componentEffectiveKey != null) { - String path = inputFile.path(); - inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey); - exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey); - if (exclusionPatternInitializer.hasFileContentPattern()) { - regexpScanner.scan(componentEffectiveKey, inputFile.file(), sourcesEncoding); - } - } - } catch (Exception e) { - throw new SonarException("Unable to read the source file : '" + inputFile.absolutePath() + "' with the charset : '" - + sourcesEncoding.name() + "'.", e); - } - } - } - - @Override - public String toString() { - return "Issues Exclusions - Source Scanner"; - } - -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java new file mode 100644 index 00000000000..bfbe6c6aee0 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesRegexpScannerTest.java @@ -0,0 +1,161 @@ +/* + * 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.scanner; + +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.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; +import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern; +import org.sonar.plugins.core.issue.ignore.pattern.LineRange; +import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher; +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 IgnoreIssuesRegexpScannerTest { + + private IgnoreIssuesRegexpScanner regexpScanner; + + private String javaFile; + @Mock + private ExclusionPatternInitializer 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 IgnoreIssuesRegexpScanner(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 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 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 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 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 lineRanges = Sets.newHashSet(); + lineRanges.add(new LineRange(21, 29)); + verify(patternsInitializer).getPatternMatcher(); + 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/IgnoreIssuesSourceScannerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScannerTest.java new file mode 100644 index 00000000000..5fc3a27c648 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/IgnoreIssuesSourceScannerTest.java @@ -0,0 +1,179 @@ +/* + * 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.scanner; + +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.Mockito; +import org.mockito.MockitoAnnotations; +import org.sonar.api.resources.Project; +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 org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; +import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer; +import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher; + +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 IgnoreIssuesSourceScannerTest { + + private IgnoreIssuesSourceScanner scanner; + + @Mock + private IgnoreIssuesRegexpScanner regexpScanner; + @Mock + private InclusionPatternInitializer inclusionPatternInitializer; + @Mock + private ExclusionPatternInitializer exclusionPatternInitializer; + @Mock + private PatternMatcher patternMatcher; + @Mock + private DefaultModuleFileSystem fs; + + private Project project; + + @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); + + Project realProject = new Project("polop"); + project = Mockito.spy(realProject); + Mockito.doReturn("java").when(project).getLanguageKey(); + when(fs.sourceCharset()).thenReturn(UTF_8); + + scanner = new IgnoreIssuesSourceScanner(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.analyse(project, null); + + 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.analyse(project, null); + + 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.analyse(project, null); + } +} 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 deleted file mode 100644 index 3ab03f3e989..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/RegexpScannerTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.scanner; - -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.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.pattern.IssuePattern; -import org.sonar.plugins.core.issue.ignore.pattern.LineRange; -import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher; -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 RegexpScannerTest { - - private RegexpScanner regexpScanner; - - private String javaFile; - @Mock - private ExclusionPatternInitializer 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 RegexpScanner(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 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 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 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 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 lineRanges = Sets.newHashSet(); - lineRanges.add(new LineRange(21, 29)); - verify(patternsInitializer).getPatternMatcher(); - 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 deleted file mode 100644 index 98ec8ec805c..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/ignore/scanner/SourceScannerTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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.scanner; - -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.Mockito; -import org.mockito.MockitoAnnotations; -import org.sonar.api.resources.Project; -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 org.sonar.plugins.core.issue.ignore.pattern.ExclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.pattern.InclusionPatternInitializer; -import org.sonar.plugins.core.issue.ignore.pattern.PatternMatcher; - -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 SourceScannerTest { - - private SourceScanner scanner; - - @Mock - private RegexpScanner regexpScanner; - @Mock - private InclusionPatternInitializer inclusionPatternInitializer; - @Mock - private ExclusionPatternInitializer exclusionPatternInitializer; - @Mock - private PatternMatcher patternMatcher; - @Mock - private DefaultModuleFileSystem fs; - - private Project project; - - @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); - - Project realProject = new Project("polop"); - project = Mockito.spy(realProject); - Mockito.doReturn("java").when(project).getLanguageKey(); - when(fs.sourceCharset()).thenReturn(UTF_8); - - scanner = new SourceScanner(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.analyse(project, null); - - 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.analyse(project, null); - - 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.analyse(project, null); - } -}