From ea9ff3965d9c657b5b7bd2d969e075f430635c47 Mon Sep 17 00:00:00 2001
From: Roman Ivanov
Date: Tue, 28 Jul 2015 10:12:18 -0700
Subject: [PATCH] 100% UTs coverage for PropertyCacheFile. Refactoring of
PropertyCacheFile. #1294
---
pom.xml | 1 -
.../tools/checkstyle/PropertyCacheFile.java | 116 +++++++++--------
.../tools/checkstyle/TreeWalker.java | 28 +++-
.../imports/CustomImportOrderCheck.java | 33 +----
.../checks/imports/ImportOrderCheck.java | 29 +----
.../checkstyle/PropertyCacheFileTest.java | 120 ++++++++++++++++++
.../tools/checkstyle/TreeWalkerTest.java | 88 ++++++++++++-
7 files changed, 287 insertions(+), 128 deletions(-)
create mode 100644 src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
diff --git a/pom.xml b/pom.xml
index cd8304247..936791cce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1082,7 +1082,6 @@
.*.DefaultLogger7576
.*.Main8090
.*.PackageNamesLoader7872
- .*.PropertyCacheFile2219
.*.TreeWalker9492
.*.checks.AbstractOptionCheck10080
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java
index 696e92e2a..809315bde 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java
@@ -20,8 +20,8 @@
package com.puppycrawl.tools.checkstyle;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
@@ -31,9 +31,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
import com.google.common.io.Closeables;
import com.google.common.io.Flushables;
import com.puppycrawl.tools.checkstyle.api.Configuration;
@@ -51,8 +48,6 @@ import com.puppycrawl.tools.checkstyle.api.Configuration;
* @author Oliver Burn
*/
final class PropertyCacheFile {
- /** Logger for PropertyCacheFile */
- private static final Log LOG = LogFactory.getLog(PropertyCacheFile.class);
/**
* The property key to use for storing the hashcode of the
@@ -74,84 +69,87 @@ final class PropertyCacheFile {
/** bit shift */
private static final int SHIFT_4 = 4;
- /** name of file to store details **/
- private final String detailsFile;
/** the details on files **/
private final Properties details = new Properties();
+ /** configuration object **/
+ private Configuration config;
+
+ /** file name of cache **/
+ private String fileName;
+
/**
* Creates a new PropertyCacheFile instance.
*
- * @param currentConfig the current configuration, not null
+ * @param config the current configuration, not null
* @param fileName the cache file
*/
- PropertyCacheFile(Configuration currentConfig, String fileName) {
- boolean setInActive = true;
- if (fileName != null) {
- FileInputStream inStream = null;
- // get the current config so if the file isn't found
- // the first time the hash will be added to output file
- final String currentConfigHash = getConfigHashCode(currentConfig);
+ PropertyCacheFile(Configuration config, String fileName) {
+ if (config == null) {
+ throw new IllegalArgumentException("config can not be null");
+ }
+ if (fileName == null) {
+ throw new IllegalArgumentException("fileName can not be null");
+ }
+ this.config = config;
+ this.fileName = fileName;
+ }
+
+ /**
+ * load cached values from file
+ * @throws IOException when there is a problems with file read
+ */
+ void load() throws IOException {
+ FileInputStream inStream = null;
+ // get the current config so if the file isn't found
+ // the first time the hash will be added to output file
+ final String currentConfigHash = getConfigHashCode(config);
+ if (new File(fileName).exists()) {
try {
inStream = new FileInputStream(fileName);
details.load(inStream);
- final String cachedConfigHash =
- details.getProperty(CONFIG_HASH_KEY);
- setInActive = false;
- if (cachedConfigHash == null
- || !cachedConfigHash.equals(currentConfigHash)) {
+ final String cachedConfigHash = details.getProperty(CONFIG_HASH_KEY);
+ if (!currentConfigHash.equals(cachedConfigHash)) {
// Detected configuration change - clear cache
details.clear();
details.put(CONFIG_HASH_KEY, currentConfigHash);
}
}
- catch (final FileNotFoundException e) {
- // Ignore, the cache does not exist
- setInActive = false;
- // put the hash in the file if the file is going to be created
- details.put(CONFIG_HASH_KEY, currentConfigHash);
- }
- catch (final IOException e) {
- LOG.debug("Unable to open cache file, ignoring.", e);
- }
finally {
Closeables.closeQuietly(inStream);
}
}
- detailsFile = setInActive ? null : fileName;
+ else {
+ // put the hash in the file if the file is going to be created
+ details.put(CONFIG_HASH_KEY, currentConfigHash);
+ }
}
- /** Cleans up the object and updates the cache file. **/
- void destroy() {
- if (detailsFile != null) {
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(detailsFile);
- details.store(out, null);
- }
- catch (final IOException e) {
- LOG.debug("Unable to save cache file.", e);
- }
- finally {
- if (out != null) {
- flushAndCloseOutStream(out);
- }
- }
+ /**
+ * Cleans up the object and updates the cache file.
+ * @throws IOException when there is a problems with file save
+ */
+ void persist() throws IOException {
+ FileOutputStream out = null;
+ try {
+ out = new FileOutputStream(fileName);
+ details.store(out, null);
+ }
+ finally {
+ flushAndCloseOutStream(out);
}
}
/**
* Flushes and closes output stream.
* @param stream the output stream
+ * @throws IOException when there is a problems with file flush and close
*/
- private static void flushAndCloseOutStream(OutputStream stream) {
- try {
+ private static void flushAndCloseOutStream(OutputStream stream) throws IOException {
+ if (stream != null) {
Flushables.flush(stream, false);
- Closeables.close(stream, false);
- }
- catch (final IOException ex) {
- LOG.debug("Unable to flush and close output stream.", ex);
}
+ Closeables.close(stream, false);
}
/**
@@ -159,7 +157,7 @@ final class PropertyCacheFile {
* @param timestamp the timestamp of the file to check
* @return whether the specified file has already been checked ok
*/
- boolean alreadyChecked(String fileName, long timestamp) {
+ boolean inCache(String fileName, long timestamp) {
final String lastChecked = details.getProperty(fileName);
return lastChecked != null
&& lastChecked.equals(Long.toString(timestamp));
@@ -170,17 +168,17 @@ final class PropertyCacheFile {
* @param fileName name of the file that checked ok
* @param timestamp the timestamp of the file
*/
- void checkedOk(String fileName, long timestamp) {
+ void put(String fileName, long timestamp) {
details.put(fileName, Long.toString(timestamp));
}
/**
* Calculates the hashcode for a GlobalProperties.
*
- * @param configuration the GlobalProperties
- * @return the hashcode for configuration
+ * @param object the GlobalProperties
+ * @return the hashcode for object
*/
- private static String getConfigHashCode(Serializable configuration) {
+ private static String getConfigHashCode(Serializable object) {
try {
// im-memory serialization of Configuration
@@ -188,7 +186,7 @@ final class PropertyCacheFile {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(baos);
- oos.writeObject(configuration);
+ oos.writeObject(object);
}
finally {
flushAndCloseOutStream(oos);
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java b/src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java
index 05a581fbf..fb7c418ef 100755
--- a/src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java
@@ -20,6 +20,7 @@
package com.puppycrawl.tools.checkstyle;
import java.io.File;
+import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.AbstractMap.SimpleEntry;
@@ -103,7 +104,7 @@ public final class TreeWalker
private int tabWidth = DEFAULT_TAB_WIDTH;
/** cache file **/
- private PropertyCacheFile cache = new PropertyCacheFile(null, null);
+ private PropertyCacheFile cache;
/** class loader to resolve classes with. **/
private ClassLoader classLoader;
@@ -130,6 +131,13 @@ public final class TreeWalker
public void setCacheFile(String fileName) {
final Configuration configuration = getConfiguration();
cache = new PropertyCacheFile(configuration, fileName);
+
+ try {
+ cache.load();
+ }
+ catch (IOException e) {
+ throw new IllegalStateException("cache file load is failed", e);
+ }
}
/** @param classLoader class loader to resolve classes with. */
@@ -178,8 +186,9 @@ public final class TreeWalker
// check if already checked and passed the file
final String fileName = file.getPath();
final long timestamp = file.lastModified();
- if (cache.alreadyChecked(fileName, timestamp)
- || !Utils.fileExtensionMatches(file, getFileExtensions())) {
+ if (cache != null
+ && (cache.inCache(fileName, timestamp)
+ || !Utils.fileExtensionMatches(file, getFileExtensions()))) {
return;
}
@@ -216,8 +225,8 @@ public final class TreeWalker
getMessageCollector().add(createLocalizedMessage(ex.getMessage()));
}
- if (getMessageCollector().size() == 0) {
- cache.checkedOk(fileName, timestamp);
+ if (cache != null && getMessageCollector().size() == 0) {
+ cache.put(fileName, timestamp);
}
}
@@ -466,7 +475,14 @@ public final class TreeWalker
for (Check c : commentChecks) {
c.destroy();
}
- cache.destroy();
+ if (cache != null) {
+ try {
+ cache.persist();
+ }
+ catch (IOException e) {
+ throw new IllegalStateException("Unable to persist cache file", e);
+ }
+ }
super.destroy();
}
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/CustomImportOrderCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/CustomImportOrderCheck.java
index 6e1359946..312fb4598 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/CustomImportOrderCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/CustomImportOrderCheck.java
@@ -117,7 +117,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
* For example:
*
* To configure the check so that it matches default Eclipse formatter configuration
- * (tested on Kepler and Luna releases):
+ * (tested on Kepler, Luna and Mars):
*
* - group of static imports is on the top
* - groups of non-static imports: "java" and "javax" packages
@@ -125,14 +125,6 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
*
- imports will be sorted in the groups
* - groups are separated by, at least, one blank line
*
- * Notes:
- *
- * - "com" package is not mentioned on configuration, because it is
- * ignored by Eclipse Kepler and Luna (looks like Eclipse defect)
- * - configuration below doesn't work in all 100% cases due to inconsistent behavior
- * prior to Mars release, but covers most scenarios
- *
- *
*
*
* <module name="CustomImportOrder">
@@ -145,29 +137,6 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
*
*
*
- * To configure the check so that it matches default Eclipse formatter
- * configuration (tested on Mars release):
- *
- * - group of static imports is on the top
- * - groups of non-static imports: "java" and "javax" packages first,
- * then "org" and "com", then all other imports as one group
- * - imports will be sorted in the groups
- * - groups are separated by, at least, one blank line
- *
- *
- *
- *
- *<module name="CustomImportOrder">
- * <property name="customImportOrderRules"
- * value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS
- * ###THIRD_PARTY_PACKAGE"/>
- * <property name="specialImportsRegExp" value="org"/>
- * <property name="thirdPartyPackageRegExp" value="com"/>
- * <property name="sortImportsInGroupAlphabetically" value="true"/>
- * <property name="separateLineBetweenGroups" value="true"/>
- *</module>
- *
- *
* To configure the check so that it matches default IntelliJ IDEA formatter
* configuration (tested on v14):
*
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java
index a0ed44a6e..42663be92 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportOrderCheck.java
@@ -67,7 +67,7 @@ import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
* Example:
*
* To configure the check so that it matches default Eclipse formatter configuration
- * (tested on Kepler and Luna releases):
+ * (tested on Kepler, Luna and Mars):
*
* - group of static imports is on the top
* - groups of non-static imports: "java" then "javax"
@@ -75,13 +75,6 @@ import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
*
- imports will be sorted in the groups
* - groups are separated by, at least, one blank line
*
- * Notes:
- *
- * - "com" package is not mentioned on configuration, because it is
- * ignored by Eclipse Kepler and Luna (looks like Eclipse defect)
- * - configuration below doesn't work in all 100% cases due to inconsistent behavior
- * prior to Mars release, but covers most scenarios
- *
*
*
* <module name="ImportOrder">
@@ -93,26 +86,6 @@ import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
* </module>
*
*
- * To configure the check so that it matches default Eclipse formatter
- * configuration (tested on Mars release):
- *
- * - group of static imports is on the top
- * - groups of non-static imports: "java" and "javax" packages first,
- * then "org" and "com", then all other imports as one group
- * - imports will be sorted in the groups
- * - groups are separated by, at least, one blank line
- *
- *
- *
- *<module name="ImportOrder">
- * <property name="groups" value="/^javax?\./,org,com"/>
- * <property name="ordered" value="true"/>
- * <property name="separated" value="true"/>
- * <property name="option" value="above"/>
- * <property name="sortStaticImportsAlphabetically" value="true"/>
- *</module>
- *
- *
* To configure the check so that it matches default IntelliJ IDEA formatter configuration
* (tested on v14):
*
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
new file mode 100644
index 000000000..22a97563b
--- /dev/null
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
@@ -0,0 +1,120 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2015 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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 library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.puppycrawl.tools.checkstyle;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+import static org.powermock.api.support.membermodification.MemberMatcher.method;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.puppycrawl.tools.checkstyle.api.Configuration;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ PropertyCacheFile.class, PropertyCacheFileTest.class })
+public class PropertyCacheFileTest {
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Test
+ public void testNonAccessibleFile() throws IOException {
+ Configuration config = new DefaultConfiguration("myname");
+ final File file = temporaryFolder.newFile("file.output");
+ file.setReadable(true, false);
+ file.setWritable(false, false);
+
+ PropertyCacheFile cache = new PropertyCacheFile(config, file.getAbsolutePath());
+ }
+
+ @Test
+ public void testCtor() throws IOException {
+ try {
+ PropertyCacheFile cache = new PropertyCacheFile(null, "");
+ }
+ catch (IllegalArgumentException ex) {
+ assertEquals("config can not be null", ex.getMessage());
+ }
+ try {
+ Configuration config = new DefaultConfiguration("myname");
+ PropertyCacheFile cache = new PropertyCacheFile(config, null);
+ }
+ catch (IllegalArgumentException ex) {
+ assertEquals("fileName can not be null", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testInCache() throws IOException {
+ Configuration config = new DefaultConfiguration("myname");
+ final String filePath = temporaryFolder.newFile().getPath();
+ PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
+ cache.put("myFile", 1);
+ assertTrue(cache.inCache("myFile", 1));
+ assertFalse(cache.inCache("myFile", 2));
+ assertFalse(cache.inCache("myFile1", 1));
+ }
+
+ @Test
+ public void testException_NoSuchAlgorithmException() throws Exception {
+
+ Configuration config = new DefaultConfiguration("myname");
+ final String filePath = temporaryFolder.newFile().getPath();
+ PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
+ cache.put("myFile", 1);
+ mockStatic(MessageDigest.class);
+
+ when(MessageDigest.getInstance("SHA-1"))
+ .thenThrow(NoSuchAlgorithmException.class);
+
+ Class[] param = new Class[1];
+ param[0] = Serializable.class;
+ Method method = PropertyCacheFile.class.getDeclaredMethod("getConfigHashCode", param);
+ method.setAccessible(true);
+ try {
+ method.invoke(cache, config);
+ fail();
+ }
+ catch (InvocationTargetException e) {
+ assertTrue(e.getCause().getCause() instanceof NoSuchAlgorithmException);
+ assertEquals("Unable to calculate hashcode.", e.getCause().getMessage());
+ }
+ catch (Exception e) {
+ fail();
+ }
+ }
+}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
index 8b134326c..bc4ad3d07 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
@@ -25,7 +25,9 @@ import static org.junit.Assert.fail;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
+import java.io.IOException;
import java.io.Writer;
+import java.util.Locale;
import org.junit.Assert;
import org.junit.Rule;
@@ -122,13 +124,95 @@ public class TreeWalkerTest extends BaseCheckTestSupport {
public void testSettersForParameters() throws Exception {
final TreeWalker treeWalker = new TreeWalker();
treeWalker.setTabWidth(1);
+ treeWalker.configure(new DefaultConfiguration("default config"));
treeWalker.setCacheFile(temporaryFolder.newFile().getPath());
}
@Test
- public void testNonExistingCacheFileDoesNotThrowException() {
+ public void testNonExistingCacheFileDoesNotThrowException() throws Exception {
final TreeWalker treeWalker = new TreeWalker();
+ treeWalker.configure(new DefaultConfiguration("default config"));
treeWalker.setCacheFile("/invalid");
- treeWalker.destroy();
+ treeWalker.finishLocalSetup();
+ try {
+ treeWalker.destroy();
+ fail();
+ }
+ catch (IllegalStateException ex) {
+ assertTrue(ex.getCause() instanceof IOException);
+ }
}
+
+ @Test
+ public void testCacheFile() throws Exception {
+ final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
+
+ final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
+ treeWalkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
+ treeWalkerConfig.addChild(checkConfig);
+
+ final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
+ checkerConfig.addAttribute("charset", "UTF-8");
+ checkerConfig.addChild(treeWalkerConfig);
+
+ final Checker checker = new Checker();
+ final Locale locale = Locale.ROOT;
+ checker.setLocaleCountry(locale.getCountry());
+ checker.setLocaleLanguage(locale.getLanguage());
+ checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
+ checker.configure(checkerConfig);
+ checker.addListener(new BriefLogger(stream));
+
+ final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
+ final String[] expected = {
+ };
+
+ verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
+ // one more time to reuse cache
+ verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
+ }
+
+ @Test
+ public void testCacheFile_changeInConfig() throws Exception {
+ final DefaultConfiguration checkConfig = createCheckConfig(HiddenFieldCheck.class);
+
+ final DefaultConfiguration treeWalkerConfig = createCheckConfig(TreeWalker.class);
+ treeWalkerConfig.addAttribute("cacheFile", temporaryFolder.newFile().getPath());
+ treeWalkerConfig.addChild(checkConfig);
+
+ final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
+ checkerConfig.addAttribute("charset", "UTF-8");
+ checkerConfig.addChild(treeWalkerConfig);
+
+ Checker checker = new Checker();
+ final Locale locale = Locale.ROOT;
+ checker.setLocaleCountry(locale.getCountry());
+ checker.setLocaleLanguage(locale.getLanguage());
+ checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
+ checker.configure(checkerConfig);
+ checker.addListener(new BriefLogger(stream));
+
+ final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
+ final String[] expected = {
+ };
+
+ verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
+
+ // update Checker config
+ //checker.destroy();
+ //checker.configure(checkerConfig);
+
+ checker = new Checker();
+ checker.setLocaleCountry(locale.getCountry());
+ checker.setLocaleLanguage(locale.getLanguage());
+ checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
+ checker.configure(checkerConfig);
+ checker.addListener(new BriefLogger(stream));
+ // here is diff with previous checker
+ checkerConfig.addAttribute("fileExtensions", "java,javax");
+
+ // one more time on updated config
+ verify(checker, pathToEmptyFile, pathToEmptyFile, expected);
+ }
+
}