Issue #1002: Add optional attribute to suppression filter

This commit is contained in:
liscju 2016-01-03 00:38:15 +01:00 committed by Roman Ivanov
parent 5b3ba10b7a
commit c22cc5801e
4 changed files with 217 additions and 12 deletions

View File

@ -271,7 +271,7 @@
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>1.7.6</version>
<version>1.7.7</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -19,6 +19,10 @@
package com.puppycrawl.tools.checkstyle.filters;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.Objects;
import com.puppycrawl.tools.checkstyle.api.AuditEvent;
@ -26,6 +30,7 @@ import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Filter;
import com.puppycrawl.tools.checkstyle.api.FilterSet;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
/**
* <p>
@ -33,21 +38,32 @@ import com.puppycrawl.tools.checkstyle.api.FilterSet;
* column, as specified in a suppression file.
* </p>
* @author Rick Giles
* @author <a href="mailto:piotr.listkiewicz@gmail.com">liscju</a>
*/
public class SuppressionFilter
extends AutomaticBean
implements Filter {
/** Filename of supression file. */
private String file;
/** Tells whether config file existence is optional. */
private boolean optional;
/** Set of individual suppresses. */
private FilterSet filters = new FilterSet();
/**
* Loads the suppressions for a file.
* Sets name of the supression file.
* @param fileName name of the suppressions file.
* @throws CheckstyleException if there is an error.
*/
public void setFile(String fileName)
throws CheckstyleException {
filters = SuppressionsLoader.loadSuppressions(fileName);
public void setFile(String fileName) {
file = fileName;
}
/**
* Sets whether config file existence is optional.
* @param optional tells if config file existence is optional.
*/
public void setOptional(boolean optional) {
this.optional = optional;
}
@Override
@ -71,4 +87,50 @@ public class SuppressionFilter
public int hashCode() {
return Objects.hash(filters);
}
@Override
protected void finishLocalSetup() throws CheckstyleException {
if (file != null) {
if (optional) {
if (suppressionSourceExists(file)) {
filters = SuppressionsLoader.loadSuppressions(file);
}
else {
filters = new FilterSet();
}
}
else {
filters = SuppressionsLoader.loadSuppressions(file);
}
}
}
/**
* Checks if suppression source with given fileName exists.
* @param fileName name of the suppressions file.
* @return true if suppression file exists, otherwise false
*/
private static boolean suppressionSourceExists(String fileName) {
boolean suppressionSourceExists = true;
InputStream sourceInput = null;
try {
final URI uriByFilename = CommonUtils.getUriByFilename(fileName);
final URL url = uriByFilename.toURL();
sourceInput = url.openStream();
}
catch (CheckstyleException | IOException ignored) {
suppressionSourceExists = false;
}
finally {
if (sourceInput != null) {
try {
sourceInput.close();
}
catch (IOException ignored) {
suppressionSourceExists = false;
}
}
}
return suppressionSourceExists;
}
}

View File

@ -19,14 +19,34 @@
package com.puppycrawl.tools.checkstyle.filters;
import org.junit.Assert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.puppycrawl.tools.checkstyle.api.AuditEvent;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
@RunWith(PowerMockRunner.class)
@PrepareForTest({SuppressionFilter.class, CommonUtils.class})
public class SuppressionFilterTest {
@Test
public void testEqualsAndHashCode() {
@ -39,13 +59,122 @@ public class SuppressionFilterTest {
@Test
public void testAccept() throws CheckstyleException {
final SuppressionFilter filter = new SuppressionFilter();
filter.setFile("src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "suppressions_none.xml");
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "suppressions_none.xml";
final boolean optional = false;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "ATest.java", null);
Assert.assertTrue(filter.accept(ev));
assertTrue(filter.accept(ev));
}
@Test
public void testAcceptOnNullFile() throws CheckstyleException {
final String fileName = null;
final boolean optional = false;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "AnyJava.java", null);
assertTrue(filter.accept(ev));
}
@Test
public void testNonExistanceSuppressionFileWithFalseOptional() throws Exception {
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "non_existance_suppresion_file.xml";
try {
final boolean optional = false;
createSupressionFilter(fileName, optional);
fail("Exception is expected");
}
catch (CheckstyleException ex) {
assertEquals("Unable to find: " + fileName, ex.getMessage());
}
}
@Test
public void testExistanceInvalidSuppressionFileWithTrueOptional() throws Exception {
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "suppressions_invalid_file.xml";
try {
final boolean optional = true;
createSupressionFilter(fileName, optional);
fail("Exception is expected");
}
catch (CheckstyleException ex) {
assertEquals("Unable to parse " + fileName + " - invalid files or checks format",
ex.getMessage());
}
}
@Test
public void testExistingSuppressionFileWithTrueOptional() throws Exception {
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "suppressions_none.xml";
final boolean optional = true;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "AnyFile.java", null);
assertTrue(filter.accept(ev));
}
@Test
public void testExistingConfigWithTrueOptionalThrowsIoErrorWhileClosing()
throws Exception {
final InputStream inputStream = PowerMockito.mock(InputStream.class);
Mockito.doThrow(IOException.class).when(inputStream).close();
final URL url = PowerMockito.mock(URL.class);
BDDMockito.given(url.openStream()).willReturn(inputStream);
final URI uri = PowerMockito.mock(URI.class);
BDDMockito.given(uri.toURL()).willReturn(url);
PowerMockito.mockStatic(CommonUtils.class);
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "suppressions_none.xml";
BDDMockito.given(CommonUtils.getUriByFilename(fileName)).willReturn(uri);
final boolean optional = true;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "AnyFile.java", null);
assertTrue(filter.accept(ev));
}
@Test
public void testNonExistanceSuppressionFileWithTrueOptional() throws Exception {
final String fileName = "src/test/resources/com/puppycrawl/tools/checkstyle/filters/"
+ "non_existance_suppresion_file.xml";
final boolean optional = true;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "AnyFile.java", null);
assertTrue(filter.accept(ev));
}
@Test
public void testNonExistanceSuppressionUrlWithTrueOptional() throws Exception {
final String fileName =
"http://checkstyle.sourceforge.net/non_existing_suppression.xml";
final boolean optional = true;
final SuppressionFilter filter = createSupressionFilter(fileName, optional);
final AuditEvent ev = new AuditEvent(this, "AnyFile.java", null);
assertTrue(filter.accept(ev));
}
private static SuppressionFilter createSupressionFilter(String fileName, boolean optional)
throws CheckstyleException {
final SuppressionFilter suppressionFilter = new SuppressionFilter();
suppressionFilter.setFile(fileName);
suppressionFilter.setOptional(optional);
suppressionFilter.finishLocalSetup();
return suppressionFilter;
}
}

View File

@ -389,7 +389,8 @@ public static void foo() {
audit events for Check errors according to
a <a href="config.html#XML_Structure"><em>suppressions XML
document</em></a> in a file. If there is no configured
suppressions file, the Filter accepts all audit events.
suppressions file or the optional is set to true and
suppressions file was not found the Filter accepts all audit events.
</p>
</subsection>
<subsection name="Properties">
@ -421,6 +422,18 @@ public static void foo() {
<td><a href="property_types.html#string">string</a></td>
<td><code>none</code></td>
</tr>
<tr>
<td>optional</td>
<td>
Tells what to do when the file is not existing. If
optional is set to false the file must exist, or else
it ends with error. On the other hand if optional is
true and file is not found, the filter accept all
audit events.
</td>
<td><a href="property_types.html#boolean">boolean</a></td>
<td><code>false</code></td>
</tr>
</table>
</subsection>
<subsection name="Examples">
@ -433,6 +446,7 @@ public static void foo() {
<source>
&lt;module name=&quot;SuppressionFilter&quot;&gt;
&lt;property name=&quot;file&quot; value=&quot;config/suppressions.xml&quot;/&gt;
&lt;property name=&quot;optional&quot; value=&quot;false&quot;/&gt;
&lt;/module&gt;
</source>
<p>