diff --git a/.ci/pitest.sh b/.ci/pitest.sh
index 948a9ed1517..c9d8769cbdf 100755
--- a/.ci/pitest.sh
+++ b/.ci/pitest.sh
@@ -41,6 +41,8 @@ pitest-annotation|pitest-design \
|pitest-coding \
|pitest-regexp \
|pitest-meta \
+|pitest-tree-walker \
+|pitest-utils \
|pitest-java-ast-visitor)
mvn --no-transfer-progress -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
declare -a ignoredItems=();
@@ -59,8 +61,6 @@ pitest-main)
pitest-header)
mvn --no-transfer-progress -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
declare -a ignoredItems=(
- "AbstractHeaderCheck.java.html:
catch (final IOException ex) { | "
- "AbstractHeaderCheck.java.html: throw new IllegalArgumentException("unable to load header", ex); | "
"RegexpHeaderCheck.java.html: isMatch = headerLineNo == headerSize | "
"RegexpHeaderCheck.java.html: || isMatch(line, headerLineNo); | "
);
@@ -81,27 +81,15 @@ pitest-common)
mvn --no-transfer-progress -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
declare -a ignoredItems=(
"AuditEventDefaultFormatter.java.html: if (lastDotIndex == -1) { | "
- "AuditEventDefaultFormatter.java.html: checkShortName = checkFullName.substring(0, checkFullName.lastIndexOf(SUFFIX)); | "
- "AuditEventDefaultFormatter.java.html: checkShortName = checkFullName; | "
- "AuditEventDefaultFormatter.java.html: if (checkFullName.endsWith(SUFFIX)) { | "
"Checker.java.html: if (cacheFile != null && cacheFile.isInCache(fileName, timestamp) | "
"DefaultLogger.java.html: closeError = errorStreamOptions == OutputStreamOptions.CLOSE; | "
"DefaultLogger.java.html: closeInfo = infoStreamOptions == OutputStreamOptions.CLOSE; | "
"DefaultLogger.java.html: if (closeError) { | "
"DefaultLogger.java.html: if (closeInfo) { | "
"DefaultLogger.java.html: if (severityLevel != SeverityLevel.IGNORE) { | "
- "ConfigurationLoader.java.html: catch (final CheckstyleException ex) { | "
- "ConfigurationLoader.java.html: + recentModule.getName(), ex); | "
- "ConfigurationLoader.java.html: throw new SAXException( | "
"PackageObjectFactory.java.html: if (instance == null | "
"PackageObjectFactory.java.html: if (!name.contains(PACKAGE_SEPARATOR)) { | "
"PackageObjectFactory.java.html: if (thirdPartyNameToFullModuleNames == null) { | "
- "PackageObjectFactory.java.html: returnValue = Collections.emptyMap(); | "
- "PackageObjectFactory.java.html: catch (IOException ignore) { | "
- "PropertyCacheFile.java.html: if (!cachedHashSum.equals(contentHashSum)) { | "
- "PropertyCacheFile.java.html: changed = true; | "
- "PropertyCacheFile.java.html: catch (final IOException | NoSuchAlgorithmException ex) { | "
- "PropertyCacheFile.java.html: throw new IllegalStateException("Unable to calculate hashcode.", ex); | "
);
checkPitestReport "${ignoredItems[@]}"
;;
@@ -159,25 +147,6 @@ pitest-javadoc)
checkPitestReport "${ignoredItems[@]}"
;;
-pitest-tree-walker)
- mvn --no-transfer-progress -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
- declare -a ignoredItems=(
- "TreeWalker.java.html: if (!commentChecks.isEmpty()) { | "
- "TreeWalker.java.html: if (!ordinaryChecks.isEmpty()) { | "
- "TreeWalker.java.html: if (filters.isEmpty()) { | "
- );
- checkPitestReport "${ignoredItems[@]}"
- ;;
-
-pitest-utils)
- mvn --no-transfer-progress -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
- declare -a ignoredItems=(
- "CommonUtil.java.html: catch (final URISyntaxException ex) { | "
- "CommonUtil.java.html: throw new CheckstyleException(UNABLE_TO_FIND_EXCEPTION_PREFIX + filename, ex); | "
- );
- checkPitestReport "${ignoredItems[@]}"
- ;;
-
# pitesttyle-gui)
# mvn -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage;
# # post validation is skipped, we do not test gui throughly
diff --git a/config/import-control-test.xml b/config/import-control-test.xml
index 7175d138cb8..a3e307ef080 100644
--- a/config/import-control-test.xml
+++ b/config/import-control-test.xml
@@ -17,11 +17,6 @@
-
-
-
-
@@ -35,11 +30,6 @@
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index b7b8d87e9cd..332b013d865 100644
--- a/pom.xml
+++ b/pom.xml
@@ -205,7 +205,7 @@
3.15.0
6.41.0
0.8.7
- 2.0.9
+ 4.1.0
10.6
3.1.2
1.40.0
@@ -316,24 +316,9 @@
test
- org.powermock
- powermock-api-mockito2
- ${powermock.version}
- test
-
-
-
- org.javassist
- javassist
- 3.28.0-GA
- test
-
-
-
- org.powermock
- powermock-module-junit4
- ${powermock.version}
- test
+ org.mockito
+ mockito-inline
+ ${mockito.version}
commons-io
diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/utils/CommonUtil.java b/src/main/java/com/puppycrawl/tools/checkstyle/utils/CommonUtil.java
index 65844acda0b..4cffbca1755 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/utils/CommonUtil.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/utils/CommonUtil.java
@@ -447,7 +447,7 @@ private static URI getFilepathOrClasspathUri(String filename) throws CheckstyleE
public static URI getResourceFromClassPath(String filename) throws CheckstyleException {
final URL configUrl;
if (filename.charAt(0) == '/') {
- configUrl = CommonUtil.class.getResource(filename);
+ configUrl = getCheckstyleResource(filename);
}
else {
configUrl = ClassLoader.getSystemResource(filename);
@@ -468,6 +468,18 @@ public static URI getResourceFromClassPath(String filename) throws CheckstyleExc
return uri;
}
+ /**
+ * Finds a resource with a given name in the Checkstyle resource bundle.
+ * This method is intended only for internal use in Checkstyle tests for
+ * easy mocking to gain 100% coverage.
+ *
+ * @param name name of the desired resource
+ * @return URI of the resource
+ */
+ public static URL getCheckstyleResource(String name) {
+ return CommonUtil.class.getResource(name);
+ }
+
/**
* Puts part of line, which matches regexp into given template
* on positions $n where 'n' is number of matched part in line.
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java
index ac6e1a0d97f..94657fbcb54 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java
@@ -19,7 +19,10 @@
package com.puppycrawl.tools.checkstyle;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
@@ -80,6 +83,40 @@ public void testCalculateBufferLength() throws Exception {
assertEquals(54, result, "Buffer length is not expected");
}
+ @Test
+ public void testFormatModuleNameContainsCheckSuffix() {
+ final AuditEvent mock = mock(AuditEvent.class);
+ when(mock.getSourceName()).thenReturn("TestModuleCheck");
+ when(mock.getSeverityLevel()).thenReturn(SeverityLevel.WARNING);
+ when(mock.getLine()).thenReturn(1);
+ when(mock.getColumn()).thenReturn(1);
+ when(mock.getMessage()).thenReturn("Mocked message.");
+ when(mock.getFileName()).thenReturn("InputMockFile.java");
+ final AuditEventFormatter formatter = new AuditEventDefaultFormatter();
+
+ final String expected = "[WARN] InputMockFile.java:1:1: Mocked message. [TestModule]";
+ assertWithMessage("Invalid format")
+ .that(formatter.format(mock))
+ .isEqualTo(expected);
+ }
+
+ @Test
+ public void testFormatModuleNameDoesNotContainCheckSuffix() {
+ final AuditEvent mock = mock(AuditEvent.class);
+ when(mock.getSourceName()).thenReturn("TestModule");
+ when(mock.getSeverityLevel()).thenReturn(SeverityLevel.WARNING);
+ when(mock.getLine()).thenReturn(1);
+ when(mock.getColumn()).thenReturn(1);
+ when(mock.getMessage()).thenReturn("Mocked message.");
+ when(mock.getFileName()).thenReturn("InputMockFile.java");
+ final AuditEventFormatter formatter = new AuditEventDefaultFormatter();
+
+ final String expected = "[WARN] InputMockFile.java:1:1: Mocked message. [TestModule]";
+ assertWithMessage("Invalid format")
+ .that(formatter.format(mock))
+ .isEqualTo(expected);
+ }
+
private static class TestModuleCheck {
// no code
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
index 3ca13eec930..cdf325b619b 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java
@@ -22,8 +22,11 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.lang.reflect.Constructor;
@@ -36,6 +39,7 @@
import java.util.Properties;
import org.junit.jupiter.api.Test;
+import org.mockito.MockedConstruction;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -618,4 +622,29 @@ public void testConstructors() throws Exception {
assertEquals(1, length, "Unexpected children size");
}
+ @Test
+ public void testConfigWithIgnoreExceptionalAttributes() {
+ try (MockedConstruction mocked = mockConstruction(
+ DefaultConfiguration.class, (mock, context) -> {
+ when(mock.getPropertyNames()).thenReturn(new String[] {"severity"});
+ when(mock.getName()).thenReturn("MemberName");
+ when(mock.getProperty("severity")).thenThrow(CheckstyleException.class);
+ })) {
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> {
+ ConfigurationLoader.loadConfiguration(
+ getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"),
+ new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
+ },
+ "CheckstyleException is expected");
+ final String expectedMessage =
+ "Problem during accessing 'severity' attribute for MemberName";
+ assertWithMessage("Invalid exception cause message")
+ .that(ex)
+ .hasCauseThat()
+ .hasMessageThat()
+ .isEqualTo(expectedMessage);
+ }
+ }
+
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
index fb88473a628..7d9424740be 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java
@@ -19,6 +19,7 @@
package com.puppycrawl.tools.checkstyle;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.puppycrawl.tools.checkstyle.PackageObjectFactory.AMBIGUOUS_MODULE_NAME_EXCEPTION_MESSAGE;
import static com.puppycrawl.tools.checkstyle.PackageObjectFactory.BASE_PACKAGE;
import static com.puppycrawl.tools.checkstyle.PackageObjectFactory.CHECK_SUFFIX;
@@ -31,8 +32,10 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mockStatic;
import java.io.File;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -45,6 +48,8 @@
import java.util.Set;
import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
@@ -52,6 +57,8 @@
import com.puppycrawl.tools.checkstyle.api.Violation;
import com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck;
import com.puppycrawl.tools.checkstyle.internal.utils.CheckUtil;
+import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
+import com.puppycrawl.tools.checkstyle.utils.ModuleReflectionUtil;
/**
* Enter a description of class PackageObjectFactoryTest.java.
@@ -393,6 +400,51 @@ public void testGetShortFromFullModuleNamesThirdParty() {
"Invalid simple check name");
}
+ /**
+ * This method is for testing the case of an exception caught inside
+ * {@code PackageObjectFactory.generateThirdPartyNameToFullModuleName}, a private method used
+ * to initialize private field {@code PackageObjectFactory.thirdPartyNameToFullModuleNames}.
+ * Since the method and the field both are private, the {@link TestUtil} is required to ensure
+ * that the field is changed. Also, the expected exception should be thrown from the static
+ * method {@link ModuleReflectionUtil#getCheckstyleModules}, so {@link Mockito#mockStatic}
+ * is required to mock this exception.
+ *
+ * @throws Exception when the code tested throws an exception
+ */
+ @Test
+ public void testGenerateThirdPartyNameToFullModuleNameWithException() throws Exception {
+ final String name = "String";
+ final String packageName = "java.lang";
+ final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ final Set packages = Collections.singleton(packageName);
+ final PackageObjectFactory objectFactory = new PackageObjectFactory(packages, classLoader,
+ TRY_IN_ALL_REGISTERED_PACKAGES);
+
+ try (MockedStatic utilities =
+ mockStatic(ModuleReflectionUtil.class)) {
+ utilities.when(() -> ModuleReflectionUtil.getCheckstyleModules(packages, classLoader))
+ .thenThrow(new IOException("mock exception"));
+
+ final String internalFieldName = "thirdPartyNameToFullModuleNames";
+ final Map nullMap = TestUtil.getInternalState(objectFactory,
+ internalFieldName);
+ assertWithMessage("Expected uninitialized field")
+ .that(nullMap)
+ .isNull();
+
+ final Object instance = objectFactory.createModule(name);
+ assertWithMessage("Expected empty string")
+ .that(instance)
+ .isEqualTo("");
+
+ final Map emptyMap = TestUtil.getInternalState(objectFactory,
+ internalFieldName);
+ assertWithMessage("Expected empty map")
+ .that(emptyMap)
+ .isEmpty();
+ }
+ }
+
private static final class FailConstructorFileSet extends AbstractFileSetCheck {
private FailConstructorFileSet() {
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
index 04c1f7407cd..ae3f4bce9db 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java
@@ -19,12 +19,16 @@
package com.puppycrawl.tools.checkstyle;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mockStatic;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@@ -32,10 +36,12 @@
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Properties;
@@ -43,10 +49,15 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.MockedStatic;
import com.google.common.io.BaseEncoding;
import com.google.common.io.ByteStreams;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
+import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
public class PropertyCacheFileTest extends AbstractPathTestSupport {
@@ -284,4 +295,132 @@ public void testChangeInConfig() throws Exception {
assertEquals(1, detailsAfterChangeInConfig.size(), "Invalid cache size");
}
+ @Test
+ public void testNonExistentResource() throws IOException {
+ final Configuration config = new DefaultConfiguration("myName");
+ final String filePath = File.createTempFile("junit", null, temporaryFolder).getPath();
+ final PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
+
+ // create cache with one file
+ cache.load();
+ final String myFile = "myFile";
+ cache.put(myFile, 1);
+
+ final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY);
+ assertWithMessage("Config hash key should not be null")
+ .that(hash)
+ .isNotNull();
+
+ try (MockedStatic byteStream = mockStatic(ByteStreams.class)) {
+ byteStream.when(() -> ByteStreams.toByteArray(any(BufferedInputStream.class)))
+ .thenThrow(IOException.class);
+
+ // apply new external resource to clear cache
+ final Set resources = new HashSet<>();
+ final String resource = getPath("InputPropertyCacheFile.header");
+ resources.add(resource);
+ cache.putExternalResources(resources);
+
+ assertWithMessage("Should return false in file is not in cache")
+ .that(cache.isInCache(myFile, 1))
+ .isFalse();
+
+ assertWithMessage("Should return false in file is not in cache")
+ .that(cache.isInCache(resource, 1))
+ .isFalse();
+ }
+ }
+
+ @Test
+ public void testExceptionNoSuchAlgorithmException() throws Exception {
+ final Configuration config = new DefaultConfiguration("myName");
+ final String filePath = File.createTempFile("junit", null, temporaryFolder).getPath();
+ final PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
+ cache.put("myFile", 1);
+
+ try (MockedStatic messageDigest = mockStatic(MessageDigest.class)) {
+ messageDigest.when(() -> MessageDigest.getInstance("SHA-1"))
+ .thenThrow(NoSuchAlgorithmException.class);
+ final InvocationTargetException ex = assertThrows(InvocationTargetException.class,
+ () -> {
+ TestUtil.invokeStaticMethod(PropertyCacheFile.class,
+ "getHashCodeBasedOnObjectContent", config);
+ },
+ "InvocationTargetException is expected");
+ assertWithMessage("Invalid exception cause")
+ .that(ex)
+ .hasCauseThat()
+ .hasCauseThat()
+ .isInstanceOf(NoSuchAlgorithmException.class);
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasCauseThat()
+ .hasMessageThat()
+ .isEqualTo("Unable to calculate hashcode.");
+ }
+ }
+
+ /**
+ * This test invokes {@code putExternalResources} twice to invalidate cache.
+ * And asserts that two different exceptions produces different content,
+ * but two exceptions with same message produces one shared content.
+ *
+ * @param rawMessages exception messages separated by ';'
+ */
+ @ParameterizedTest
+ @ValueSource(strings = {"Same;Same", "First;Second"})
+ public void testPutNonExistentExternalResource(String rawMessages) throws Exception {
+ final File cacheFile = File.createTempFile("junit", null, temporaryFolder);
+ final String[] messages = rawMessages.split(";");
+ // We mock getUriByFilename method of CommonUtil to guarantee that it will
+ // throw CheckstyleException with the specific content.
+ try (MockedStatic commonUtil = mockStatic(CommonUtil.class)) {
+ final int numberOfRuns = messages.length;
+ final String[] configHashes = new String[numberOfRuns];
+ final String[] externalResourceHashes = new String[numberOfRuns];
+ for (int i = 0; i < numberOfRuns; i++) {
+ commonUtil.when(() -> CommonUtil.getUriByFilename(any(String.class)))
+ .thenThrow(new CheckstyleException(messages[i]));
+ final Configuration config = new DefaultConfiguration("myConfig");
+ final PropertyCacheFile cache = new PropertyCacheFile(config, cacheFile.getPath());
+ cache.load();
+
+ configHashes[i] = cache.get(PropertyCacheFile.CONFIG_HASH_KEY);
+ assertWithMessage("Config hash key should not be null")
+ .that(configHashes[i])
+ .isNotNull();
+
+ final Set nonExistentExternalResources = new HashSet<>();
+ final String externalResourceFileName = "non_existent_file.xml";
+ nonExistentExternalResources.add(externalResourceFileName);
+ cache.putExternalResources(nonExistentExternalResources);
+
+ externalResourceHashes[i] = cache.get(PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
+ + externalResourceFileName);
+ assertWithMessage("External resource hashes should not be null")
+ .that(externalResourceHashes[i])
+ .isNotNull();
+
+ cache.persist();
+
+ final Properties cacheDetails = new Properties();
+ try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
+ cacheDetails.load(reader);
+ }
+
+ assertWithMessage("Unexpected number of objects in cache")
+ .that(cacheDetails)
+ .hasSize(2);
+ }
+
+ assertWithMessage("Invalid config hash")
+ .that(configHashes[0])
+ .isEqualTo(configHashes[1]);
+ final boolean sameException = messages[0].equals(messages[1]);
+ assertWithMessage("Invalid external resource hashes")
+ .that(externalResourceHashes[0].equals(externalResourceHashes[1]))
+ .isEqualTo(sameException);
+ }
+ }
+
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
index 6394e70d54b..df0f2c76594 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java
@@ -23,6 +23,10 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import java.io.File;
import java.io.Writer;
@@ -39,18 +43,23 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.mockito.MockedConstruction;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
import org.mockito.internal.util.Checks;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.Context;
+import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FileContents;
import com.puppycrawl.tools.checkstyle.api.FileText;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck;
import com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck;
import com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck;
+import com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck;
import com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck;
import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocPackageCheck;
import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocParagraphCheck;
@@ -96,6 +105,90 @@ public void testProperFileExtension() throws Exception {
verify(checkConfig, file.getPath(), expected1);
}
+ /**
+ * This test is needed for 100% coverage.
+ * The Pitest reports some conditions as redundant, for example:
+ *
+ * if (!collection.isEmpty()) { // This may me omitted.
+ * Object value = doSomeHardJob();
+ * for (Item item : collection) {
+ * item.accept(value);
+ * }
+ * }
+ *
+ * But we really want to avoid calls to {@code doSomeHardJob} method.
+ * To make this condition mandatory, we need to broke one branch.
+ * In this case, mocking {@code TreeWalkerAuditEvent} will cause
+ * {@code getFilteredViolations} to fail. This prevents the condition
+ *
+ * if (filters.isEmpty())
+ *
+ * in {@link TreeWalker#processFiltered(File, FileText)} to survive with Pitest mutations.
+ *
+ * @throws Exception if an error occurs
+ */
+ @Test
+ public void testNoAuditEventsWithoutFilters() throws Exception {
+ final DefaultConfiguration checkConfig = createModuleConfig(OneTopLevelClassCheck.class);
+ final String[] expected = {
+ "5:1: " + getCheckMessage(OneTopLevelClassCheck.class,
+ OneTopLevelClassCheck.MSG_KEY, "InputTreeWalkerInner"),
+ };
+ try (MockedConstruction mocked =
+ Mockito.mockConstruction(TreeWalkerAuditEvent.class, (mock, context) -> {
+ throw new CheckstyleException("No audit events expected");
+ })) {
+ verify(checkConfig, getPath("InputTreeWalker.java"), expected);
+ }
+ }
+
+ /**
+ * This test is needed for 100% coverage. The method {@link Mockito#mockStatic} is used to
+ * ensure that the {@code if (!ordinaryChecks.isEmpty())} condition cannot be removed.
+ */
+ @Test
+ public void testConditionRequiredWithoutOrdinaryChecks() throws Exception {
+ final DefaultConfiguration checkConfig = createModuleConfig(JavadocParagraphCheck.class);
+ final String[] expected = {
+ "3: " + getCheckMessage(JavadocParagraphCheck.class,
+ JavadocParagraphCheck.MSG_REDUNDANT_PARAGRAPH),
+ };
+ final String path = getPath("InputTreeWalkerJavadoc.java");
+ final DetailAST mockAst = mock(DetailAST.class);
+ final DetailAST realAst = JavaParser.parseFile(new File(path),
+ JavaParser.Options.WITH_COMMENTS);
+ // Ensure that there is no calls to walk(..., AstState.ORDINARY)
+ doThrow(IllegalStateException.class).when(mockAst).getFirstChild();
+ try (MockedStatic parser = Mockito.mockStatic(JavaParser.class)) {
+ parser.when(() -> JavaParser.parse(any(FileContents.class))).thenReturn(mockAst);
+ // This will re-enable walk(..., AstState.WITH_COMMENTS)
+ parser.when(() -> JavaParser.appendHiddenCommentNodes(mockAst)).thenReturn(realAst);
+
+ verify(checkConfig, path, expected);
+ }
+ }
+
+ /**
+ * This test is needed for 100% coverage. The method {@link Mockito#mockStatic} is used to
+ * ensure that the {@code if (!commentChecks.isEmpty())} condition cannot be removed.
+ */
+ @Test
+ public void testConditionRequiredWithoutCommentChecks() throws Exception {
+ final DefaultConfiguration checkConfig = createModuleConfig(OneTopLevelClassCheck.class);
+ final String[] expected = {
+ "5:1: " + getCheckMessage(OneTopLevelClassCheck.class,
+ OneTopLevelClassCheck.MSG_KEY, "InputTreeWalkerInner"),
+ };
+ try (MockedStatic parser =
+ Mockito.mockStatic(JavaParser.class, CALLS_REAL_METHODS)) {
+ // Ensure that there is no calls to walk(..., AstState.WITH_COMMENTS)
+ parser.when(() -> JavaParser.appendHiddenCommentNodes(any(DetailAST.class)))
+ .thenThrow(IllegalStateException.class);
+
+ verify(checkConfig, getPath("InputTreeWalker.java"), expected);
+ }
+ }
+
@Test
public void testImproperFileExtension() throws Exception {
final DefaultConfiguration checkConfig =
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java
index 9e0cbc5cbf6..c1c0a64e778 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/header/HeaderCheckTest.java
@@ -23,16 +23,20 @@
import static com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck.MSG_MISMATCH;
import static com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck.MSG_MISSING;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.when;
import java.io.File;
+import java.io.IOException;
+import java.io.LineNumberReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.mockito.MockedConstruction;
import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
@@ -84,22 +88,22 @@ public void testWhitespaceHeader() throws Exception {
public void testNonExistentHeaderFile() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
checkConfig.addProperty("headerFile", getPath("nonExistent.file"));
- try {
- createChecker(checkConfig);
- fail("CheckstyleException is expected");
- }
- catch (CheckstyleException ex) {
- final String messageStart = "cannot initialize module"
- + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- + " - illegal value ";
- final String causeMessageStart = "Unable to find: ";
-
- assertTrue(ex.getMessage().startsWith(messageStart),
- "Invalid exception message, should start with: " + messageStart);
- assertTrue(
- ex.getCause().getCause().getCause().getMessage().startsWith(causeMessageStart),
- "Invalid exception message, should start with: " + causeMessageStart);
- }
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> createChecker(checkConfig),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .startsWith("cannot initialize module"
+ + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ + " - illegal value ");
+ assertWithMessage("Invalid cause exception message")
+ .that(ex)
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasMessageThat()
+ .startsWith("Unable to find: ");
}
@Test
@@ -107,53 +111,60 @@ public void testInvalidCharset() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
checkConfig.addProperty("charset", "XSO-8859-1");
- try {
- createChecker(checkConfig);
- fail("CheckstyleException is expected");
- }
- catch (CheckstyleException ex) {
- assertEquals("cannot initialize module"
- + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- + " - Cannot set property 'charset' to 'XSO-8859-1'",
- ex.getMessage(), "Invalid exception message");
- assertEquals("unsupported charset: 'XSO-8859-1'",
- ex.getCause().getCause().getCause().getMessage(), "Invalid exception message");
- }
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> createChecker(checkConfig),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("cannot initialize module"
+ + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ + " - Cannot set property 'charset' to 'XSO-8859-1'");
+ assertWithMessage("Invalid cause exception message")
+ .that(ex)
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasMessageThat()
+ .startsWith("unsupported charset: 'XSO-8859-1'");
}
@Test
- public void testEmptyFilename() throws Exception {
+ public void testEmptyFilename() {
final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
checkConfig.addProperty("headerFile", "");
- try {
- createChecker(checkConfig);
- fail("Checker creation should not succeed with invalid headerFile");
- }
- catch (CheckstyleException ex) {
- assertEquals("cannot initialize module"
- + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- + " - Cannot set property 'headerFile' to ''",
- ex.getMessage(), "Invalid exception message");
- assertEquals("property 'headerFile' is missing or invalid in module"
- + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck",
- ex.getCause().getCause().getCause().getMessage(), "Invalid exception message");
- }
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> createChecker(checkConfig),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("cannot initialize module"
+ + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ + " - Cannot set property 'headerFile' to ''");
+ assertWithMessage("Invalid cause exception message")
+ .that(ex)
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasCauseThat()
+ .hasMessageThat()
+ .isEqualTo("property 'headerFile' is missing or invalid in module"
+ + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck");
}
@Test
- public void testNullFilename() throws Exception {
+ public void testNullFilename() {
final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
checkConfig.addProperty("headerFile", null);
- try {
- createChecker(checkConfig);
- fail("Checker creation should not succeed with null headerFile");
- }
- catch (CheckstyleException ex) {
- assertEquals("cannot initialize module"
- + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- + " - Cannot set property 'headerFile' to 'null'",
- ex.getMessage(), "Invalid exception message");
- }
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> createChecker(checkConfig),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("cannot initialize module"
+ + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ + " - Cannot set property 'headerFile' to 'null'");
}
@Test
@@ -181,15 +192,14 @@ public void testIgnore() throws Exception {
public void testSetHeaderTwice() {
final HeaderCheck check = new HeaderCheck();
check.setHeader("Header");
- try {
- check.setHeader("Header2");
- fail("ConversionException is expected");
- }
- catch (IllegalArgumentException ex) {
- assertEquals("header has already been set - "
- + "set either header or headerFile, not both", ex.getMessage(),
- "Invalid exception message");
- }
+ final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
+ () -> check.setHeader("Header2"),
+ "IllegalArgumentException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("header has already been set - "
+ + "set either header or headerFile, not both");
}
@Test
@@ -197,17 +207,14 @@ public void testIoExceptionWhenLoadingHeaderFile() throws Exception {
final HeaderCheck check = new HeaderCheck();
check.setHeaderFile(new URI("test://bad"));
- try {
- TestUtil.invokeMethod(check, "loadHeaderFile");
- fail("InvocationTargetException expected");
- }
- catch (InvocationTargetException ex) {
- assertWithMessage("Invalid exception cause message")
- .that(ex)
- .hasCauseThat()
- .hasMessageThat()
- .startsWith("unable to load header file ");
- }
+ final InvocationTargetException ex = assertThrows(InvocationTargetException.class,
+ () -> TestUtil.invokeMethod(check, "loadHeaderFile"),
+ "InvocationTargetException expected");
+ assertWithMessage("Invalid exception cause message")
+ .that(ex)
+ .hasCauseThat()
+ .hasMessageThat()
+ .startsWith("unable to load header file ");
}
@Test
@@ -254,21 +261,18 @@ public void testIgnoreLinesSorted() throws Exception {
}
@Test
- public void testLoadHeaderFileTwice() throws Exception {
+ public void testLoadHeaderFileTwice() {
final HeaderCheck check = new HeaderCheck();
check.setHeader("Header");
- try {
- TestUtil.invokeMethod(check, "loadHeaderFile");
- fail("InvocationTargetException is expected");
- }
- catch (InvocationTargetException ex) {
- assertWithMessage("Invalid exception cause message")
+ final InvocationTargetException ex = assertThrows(InvocationTargetException.class,
+ () -> TestUtil.invokeMethod(check, "loadHeaderFile"),
+ "InvocationTargetException expected");
+ assertWithMessage("Invalid exception cause message")
.that(ex)
- .hasCauseThat()
+ .hasCauseThat()
.hasMessageThat()
- .isEqualTo("header has already been set - "
- + "set either header or headerFile, not both");
- }
+ .isEqualTo("header has already been set - "
+ + "set either header or headerFile, not both");
}
@Test
@@ -294,4 +298,26 @@ public void testExternalResource() throws Exception {
assertEquals(1, results.size(), "Invalid result size");
assertEquals(uri.toString(), results.iterator().next(), "Invalid resource location");
}
+
+ @Test
+ public void testIoExceptionWhenLoadingHeader() {
+ final HeaderCheck check = new HeaderCheck();
+ try (MockedConstruction mocked = mockConstruction(
+ LineNumberReader.class, (mock, context) -> {
+ when(mock.readLine()).thenThrow(IOException.class);
+ })) {
+ final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
+ () -> check.setHeader("header"),
+ "IllegalArgumentException expected");
+ assertWithMessage("Invalid exception cause")
+ .that(ex)
+ .hasCauseThat()
+ .isInstanceOf(IOException.class);
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("unable to load header");
+ }
+ }
+
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoaderTest.java
index 18dc98b04c3..0e75958abe1 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoaderTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoaderTest.java
@@ -19,22 +19,31 @@
package com.puppycrawl.tools.checkstyle.checks.imports;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URL;
import org.junit.jupiter.api.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.AttributesImpl;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
@@ -124,4 +133,27 @@ public void testLoadThrowsException() throws Exception {
}
}
+ @Test
+ public void testInputStreamFailsOnRead() throws Exception {
+ try (InputStream inputStream = mock(InputStream.class)) {
+ final int available = doThrow(IOException.class).when(inputStream).available();
+ final URL url = mock(URL.class);
+ when(url.openStream()).thenReturn(inputStream);
+ final URI uri = mock(URI.class);
+ when(uri.toURL()).thenReturn(url);
+
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> ImportControlLoader.load(uri),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception class")
+ .that(ex)
+ .hasCauseThat()
+ .isInstanceOf(SAXParseException.class);
+ // Workaround for warning "Result of InputStream.available() is ignored"
+ assertWithMessage("")
+ .that(available)
+ .isEqualTo(0);
+ }
+ }
+
}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/AuditEventDefaultFormatterPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/AuditEventDefaultFormatterPowerTest.java
deleted file mode 100644
index b76e6e5c392..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/AuditEventDefaultFormatterPowerTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.puppycrawl.tools.checkstyle.AuditEventDefaultFormatter;
-import com.puppycrawl.tools.checkstyle.AuditEventFormatter;
-import com.puppycrawl.tools.checkstyle.api.AuditEvent;
-import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(AuditEvent.class)
-public class AuditEventDefaultFormatterPowerTest {
-
- @Test
- public void testFormatModuleNameContainsCheckSuffix() {
- final AuditEvent mock = PowerMockito.mock(AuditEvent.class);
- when(mock.getSourceName()).thenReturn("TestModuleCheck");
- when(mock.getSeverityLevel()).thenReturn(SeverityLevel.WARNING);
- when(mock.getLine()).thenReturn(1);
- when(mock.getColumn()).thenReturn(1);
- when(mock.getMessage()).thenReturn("Mocked message.");
- when(mock.getFileName()).thenReturn("InputMockFile.java");
- final AuditEventFormatter formatter = new AuditEventDefaultFormatter();
-
- final String expected = "[WARN] InputMockFile.java:1:1: Mocked message. [TestModule]";
-
- assertEquals("Invalid format", expected, formatter.format(mock));
- }
-
- @Test
- public void testFormatModuleNameDoesNotContainCheckSuffix() {
- final AuditEvent mock = PowerMockito.mock(AuditEvent.class);
- when(mock.getSourceName()).thenReturn("TestModule");
- when(mock.getSeverityLevel()).thenReturn(SeverityLevel.WARNING);
- when(mock.getLine()).thenReturn(1);
- when(mock.getColumn()).thenReturn(1);
- when(mock.getMessage()).thenReturn("Mocked message.");
- when(mock.getFileName()).thenReturn("InputMockFile.java");
- final AuditEventFormatter formatter = new AuditEventDefaultFormatter();
-
- final String expected = "[WARN] InputMockFile.java:1:1: Mocked message. [TestModule]";
-
- assertEquals("Invalid format", expected, formatter.format(mock));
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CommonUtilPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CommonUtilPowerTest.java
deleted file mode 100644
index 9a8f0e581bb..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CommonUtilPowerTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.powermock.api.mockito.PowerMockito.mock;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-import java.net.URISyntaxException;
-import java.net.URL;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
-import com.puppycrawl.tools.checkstyle.utils.CommonUtilTest;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ CommonUtil.class, CommonUtilTest.class })
-public class CommonUtilPowerTest {
-
- @Test
- public void testLoadSuppressionsUriSyntaxException() throws Exception {
- final URL configUrl = mock(URL.class);
-
- when(configUrl.toURI()).thenThrow(URISyntaxException.class);
- mockStatic(CommonUtil.class, Mockito.CALLS_REAL_METHODS);
- final String fileName = "/suppressions_none.xml";
- when(CommonUtil.class.getResource(fileName)).thenReturn(configUrl);
-
- try {
- CommonUtil.getUriByFilename(fileName);
- fail("Exception is expected");
- }
- catch (CheckstyleException ex) {
- assertTrue("Invalid exception cause", ex.getCause() instanceof URISyntaxException);
- assertEquals("Invalid exception message",
- "Unable to find: " + fileName, ex.getMessage());
- }
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ConfigurationLoaderPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ConfigurationLoaderPowerTest.java
deleted file mode 100644
index fc5e4d01f09..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ConfigurationLoaderPowerTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-import java.util.Properties;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
-import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
-import com.puppycrawl.tools.checkstyle.ConfigurationLoader.IgnoredModulesOptions;
-import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
-import com.puppycrawl.tools.checkstyle.PropertiesExpander;
-import com.puppycrawl.tools.checkstyle.ThreadModeSettings;
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({DefaultConfiguration.class, ConfigurationLoader.class})
-public class ConfigurationLoaderPowerTest extends AbstractPathTestSupport {
-
- @Override
- protected String getPackageLocation() {
- return "com/puppycrawl/tools/checkstyle/configurationloader";
- }
-
- @Test
- public void testConfigWithIgnoreExceptionalAttributes() throws Exception {
- // emulate exception from unrelated code, but that is same try-catch
- final DefaultConfiguration tested = PowerMockito.mock(DefaultConfiguration.class);
- when(tested.getPropertyNames()).thenReturn(new String[] {"severity"});
- when(tested.getName()).thenReturn("MemberName");
- when(tested.getProperty("severity")).thenThrow(CheckstyleException.class);
- // to void creation of 2 other mocks for now reason, only one moc is used for all cases
- PowerMockito.whenNew(DefaultConfiguration.class)
- .withArguments("MemberName", ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE)
- .thenReturn(tested);
- PowerMockito.whenNew(DefaultConfiguration.class)
- .withArguments("Checker", ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE)
- .thenReturn(tested);
- PowerMockito.whenNew(DefaultConfiguration.class)
- .withArguments("TreeWalker", ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE)
- .thenReturn(tested);
-
- try {
- ConfigurationLoader.loadConfiguration(
- getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"),
- new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
- fail("Exception is expected");
- }
- catch (CheckstyleException expected) {
- assertEquals("Invalid exception cause message",
- "Problem during accessing 'severity' attribute for MemberName",
- expected.getCause().getMessage());
- }
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/HeaderCheckPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/HeaderCheckPowerTest.java
deleted file mode 100644
index 4ec1aa6710b..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/HeaderCheckPowerTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-
-import java.io.IOException;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
-import com.puppycrawl.tools.checkstyle.checks.header.AbstractHeaderCheck;
-import com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck;
-import com.puppycrawl.tools.checkstyle.checks.header.HeaderCheckTest;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ HeaderCheck.class, HeaderCheckTest.class, AbstractHeaderCheck.class })
-public class HeaderCheckPowerTest extends AbstractModuleTestSupport {
-
- @Override
- protected String getPackageLocation() {
- return "com/puppycrawl/tools/checkstyle/checks/header/header";
- }
-
- /**
- * This test needs powermock because {@code StringReader} can't throw an exception to trigger
- * the catch otherwise unless the reader is mishandled.
- *
- * @throws Exception if there is an error.
- */
- @Test
- public void testIoExceptionWhenLoadingHeader() throws Exception {
- final HeaderCheck check = PowerMockito.spy(new HeaderCheck());
- PowerMockito.doThrow(new IOException("expected exception")).when(check, "loadHeader",
- any());
-
- try {
- check.setHeader("header");
- fail("Exception expected");
- }
- catch (IllegalArgumentException ex) {
- assertTrue("Invalid exception cause", ex.getCause() instanceof IOException);
- assertEquals("Invalid exception message", "unable to load header", ex.getMessage());
- }
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ImportControlLoaderPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ImportControlLoaderPowerTest.java
deleted file mode 100644
index 800cbb8cf03..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ImportControlLoaderPowerTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertSame;
-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 org.xml.sax.SAXParseException;
-
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-import com.puppycrawl.tools.checkstyle.checks.imports.ImportControlLoader;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ImportControlLoader.class, URI.class})
-public class ImportControlLoaderPowerTest {
-
- @Test
- public void testInputStreamFailsOnRead() throws Exception {
- final InputStream inputStream = PowerMockito.mock(InputStream.class);
- final int available = Mockito.doThrow(IOException.class).when(inputStream).available();
-
- 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);
-
- try {
- ImportControlLoader.load(uri);
- // Using available to bypass 'ignored result' warning
- fail("exception expected " + available);
- }
- catch (CheckstyleException ex) {
- assertSame("Invalid exception class",
- SAXParseException.class, ex.getCause().getClass());
- }
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PackageObjectFactoryPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PackageObjectFactoryPowerTest.java
deleted file mode 100644
index 1e17ba4e528..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PackageObjectFactoryPowerTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static com.puppycrawl.tools.checkstyle.PackageObjectFactory.ModuleLoadOption.TRY_IN_ALL_REGISTERED_PACKAGES;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.powermock.api.mockito.PowerMockito.doThrow;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import com.puppycrawl.tools.checkstyle.PackageObjectFactory;
-import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
-import com.puppycrawl.tools.checkstyle.utils.ModuleReflectionUtil;
-
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore(value = "com.puppycrawl.tools.checkstyle.api.*", globalIgnore = false)
-@PrepareForTest(ModuleReflectionUtil.class)
-public class PackageObjectFactoryPowerTest {
-
- /**
- * This method is for testing the case of an exception caught inside
- * {@code PackageObjectFactory.generateThirdPartyNameToFullModuleName}, a private method used
- * to initialize private field {@code PackageObjectFactory.thirdPartyNameToFullModuleNames}.
- * Since the method and the field both are private, the {@link TestUtil#getInternalState} is
- * required to ensure that the field is changed. Also, the expected exception should be thrown
- * from the static method {@link ModuleReflectionUtil#getCheckstyleModules}, so
- * {@link PowerMockito#mockStatic} is required to mock this exception.
- *
- * @throws Exception when the code tested throws an exception
- */
- @Test
- public void testGenerateThirdPartyNameToFullModuleNameWithException() throws Exception {
- final String name = "String";
- final String packageName = "java.lang";
- final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- final Set packages = Collections.singleton(packageName);
- final PackageObjectFactory objectFactory = new PackageObjectFactory(packages, classLoader,
- TRY_IN_ALL_REGISTERED_PACKAGES);
-
- mockStatic(ModuleReflectionUtil.class);
- doThrow(new IOException("mock exception")).when(ModuleReflectionUtil.class);
- ModuleReflectionUtil.getCheckstyleModules(packages, classLoader);
-
- final String internalFieldName = "thirdPartyNameToFullModuleNames";
- final Map nullMap = TestUtil.getInternalState(objectFactory,
- internalFieldName);
- assertNull("Expected uninitialized field", nullMap);
-
- final Object instance = objectFactory.createModule(name);
- assertEquals("Expected empty string", "", instance);
-
- final Map emptyMap = TestUtil.getInternalState(objectFactory,
- internalFieldName);
- assertEquals("Expected empty map", Collections.emptyMap(), emptyMap);
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PropertyCacheFilePowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PropertyCacheFilePowerTest.java
deleted file mode 100644
index 36603b1438e..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PropertyCacheFilePowerTest.java
+++ /dev/null
@@ -1,247 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.file.Files;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-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.google.common.io.ByteStreams;
-import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
-import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
-import com.puppycrawl.tools.checkstyle.PropertyCacheFile;
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-import com.puppycrawl.tools.checkstyle.api.Configuration;
-import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ PropertyCacheFile.class, ByteStreams.class,
- CommonUtil.class})
-public class PropertyCacheFilePowerTest extends AbstractPathTestSupport {
-
- @Rule
- public final TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- @Override
- protected String getPackageLocation() {
- return "com/puppycrawl/tools/checkstyle/propertycachefile";
- }
-
- /**
- * This SuppressWarning("unchecked") required to suppress
- * "Unchecked generics array creation for varargs parameter" during mock.
- *
- * @throws IOException when smth wrong with file creation or cache.load
- */
- @Test
- public void testNonExistentResource() throws IOException {
- final Configuration config = new DefaultConfiguration("myName");
- final String filePath = temporaryFolder.newFile().getPath();
- final PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
-
- // create cache with one file
- cache.load();
- final String myFile = "myFile";
- cache.put(myFile, 1);
-
- final String hash = cache.get(PropertyCacheFile.CONFIG_HASH_KEY);
- assertNotNull("Config hash key should not be null", hash);
-
- mockStatic(ByteStreams.class);
-
- when(ByteStreams.toByteArray(any(BufferedInputStream.class)))
- .thenThrow(IOException.class);
-
- // apply new external resource to clear cache
- final Set resources = new HashSet<>();
- final String resource = getPath("InputPropertyCacheFile.header");
- resources.add(resource);
- cache.putExternalResources(resources);
-
- assertFalse("Should return false in file is not in cache",
- cache.isInCache(myFile, 1));
- assertFalse("Should return false in file is not in cache",
- cache.isInCache(resource, 1));
- }
-
- @Test
- public void testExceptionNoSuchAlgorithmException() throws Exception {
- final Configuration config = new DefaultConfiguration("myName");
- final String filePath = temporaryFolder.newFile().getPath();
- final PropertyCacheFile cache = new PropertyCacheFile(config, filePath);
- cache.put("myFile", 1);
- mockStatic(MessageDigest.class);
-
- when(MessageDigest.getInstance("SHA-1"))
- .thenThrow(NoSuchAlgorithmException.class);
-
- final Class>[] param = new Class>[1];
- param[0] = Serializable.class;
- final Method method =
- PropertyCacheFile.class.getDeclaredMethod("getHashCodeBasedOnObjectContent", param);
- method.setAccessible(true);
- try {
- method.invoke(cache, config);
- fail("InvocationTargetException is expected");
- }
- catch (InvocationTargetException ex) {
- assertTrue("Invalid exception cause",
- ex.getCause().getCause() instanceof NoSuchAlgorithmException);
- assertEquals("Invalid exception message",
- "Unable to calculate hashcode.", ex.getCause().getMessage());
- }
- }
-
- @Test
- public void testPutNonExistentExternalResourceSameExceptionBetweenRuns() throws Exception {
- final File cacheFile = temporaryFolder.newFile();
-
- // We mock getUriByFilename method of CommonUtil to guarantee that it will
- // throw CheckstyleException with the specific content.
- mockStatic(CommonUtil.class);
- final CheckstyleException mockException =
- new CheckstyleException("Cannot get URL for cache file " + cacheFile.getAbsolutePath());
- when(CommonUtil.getUriByFilename(any(String.class)))
- .thenThrow(mockException);
-
- // We invoke 'putExternalResources' twice to invalidate cache
- // and have two identical exceptions which the equal content
- final int numberOfRuns = 2;
- final String[] configHashes = new String[numberOfRuns];
- final String[] externalResourceHashes = new String[numberOfRuns];
- for (int i = 0; i < numberOfRuns; i++) {
- final Configuration config = new DefaultConfiguration("myConfig");
- final PropertyCacheFile cache = new PropertyCacheFile(config, cacheFile.getPath());
- cache.load();
-
- configHashes[i] = cache.get(PropertyCacheFile.CONFIG_HASH_KEY);
- assertNotNull("Config hash key should not be null", configHashes[i]);
-
- final Set nonExistentExternalResources = new HashSet<>();
- final String externalResourceFileName = "non_existent_file.xml";
- nonExistentExternalResources.add(externalResourceFileName);
- cache.putExternalResources(nonExistentExternalResources);
-
- externalResourceHashes[i] = cache.get(PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
- + externalResourceFileName);
- assertNotNull("External resource hashes should not be null",
- externalResourceHashes[i]);
-
- cache.persist();
-
- final Properties cacheDetails = new Properties();
- try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
- cacheDetails.load(reader);
- }
-
- final int expectedNumberOfObjectsInCacheFile = 2;
- assertEquals("Unexpected number of objects in cache",
- expectedNumberOfObjectsInCacheFile, cacheDetails.size());
- }
-
- assertEquals("Invalid config hash", configHashes[0], configHashes[1]);
- assertEquals("Invalid external resource hashes",
- externalResourceHashes[0], externalResourceHashes[1]);
- }
-
- /**
- * It is OK to have long test method name here as it describes the test purpose.
- */
- @Test
- public void testPutNonExistentExternalResourceDifferentExceptionsBetweenRuns()
- throws Exception {
- final File cacheFile = temporaryFolder.newFile();
-
- // We invoke 'putExternalResources' twice to invalidate cache
- // and have two different exceptions with different content.
- final int numberOfRuns = 2;
- final String[] configHashes = new String[numberOfRuns];
- final String[] externalResourceHashes = new String[numberOfRuns];
- for (int i = 0; i < numberOfRuns; i++) {
- final Configuration config = new DefaultConfiguration("myConfig");
- final PropertyCacheFile cache = new PropertyCacheFile(config, cacheFile.getPath());
-
- // We mock getUriByFilename method of CommonUtil to guarantee that it will
- // throw CheckstyleException with the specific content.
- mockStatic(CommonUtil.class);
- final CheckstyleException mockException = new CheckstyleException("Exception #" + i);
- when(CommonUtil.getUriByFilename(any(String.class)))
- .thenThrow(mockException);
-
- cache.load();
-
- configHashes[i] = cache.get(PropertyCacheFile.CONFIG_HASH_KEY);
- assertNotNull("Config hash key should not be null", configHashes[i]);
-
- final Set nonExistentExternalResources = new HashSet<>();
- final String externalResourceFileName = "non_existent_file.xml";
- nonExistentExternalResources.add(externalResourceFileName);
- cache.putExternalResources(nonExistentExternalResources);
-
- externalResourceHashes[i] = cache.get(PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
- + externalResourceFileName);
- assertNotNull("External resource hashes should not be null",
- externalResourceHashes[i]);
-
- cache.persist();
-
- final Properties cacheDetails = new Properties();
- try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
- cacheDetails.load(reader);
- }
-
- final int expectedNumberOfObjectsInCacheFile = 2;
- assertEquals("Unexpected number of objects in cache",
- expectedNumberOfObjectsInCacheFile, cacheDetails.size());
- }
-
- assertEquals("Invalid config hash", configHashes[0], configHashes[1]);
- assertNotEquals("Invalid external resource hashes",
- externalResourceHashes[0], externalResourceHashes[1]);
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TreeWalkerPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TreeWalkerPowerTest.java
deleted file mode 100644
index 0a24cc6dad7..00000000000
--- a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TreeWalkerPowerTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// checkstyle: Checks Java source code for adherence to a set of rules.
-// Copyright (C) 2001-2021 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.internal.powermock;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.times;
-import static org.powermock.api.mockito.PowerMockito.spy;
-import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-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.AbstractModuleTestSupport;
-import com.puppycrawl.tools.checkstyle.PackageObjectFactory;
-import com.puppycrawl.tools.checkstyle.TreeWalker;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-import com.puppycrawl.tools.checkstyle.api.FileContents;
-import com.puppycrawl.tools.checkstyle.api.FileText;
-import com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck;
-import com.puppycrawl.tools.checkstyle.checks.naming.TypeNameCheck;
-import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(TreeWalker.class)
-public class TreeWalkerPowerTest extends AbstractModuleTestSupport {
-
- @Rule
- public final TemporaryFolder temporaryFolder = new TemporaryFolder();
-
- @Override
- protected String getPackageLocation() {
- return "com/puppycrawl/tools/checkstyle/treewalker";
- }
-
- @Test
- public void testBehaviourWithOnlyOrdinaryChecks() throws Exception {
- final TreeWalker treeWalkerSpy = spy(new TreeWalker());
- final Class> classAstState =
- Class.forName("com.puppycrawl.tools.checkstyle.TreeWalker$AstState");
- final PackageObjectFactory factory = new PackageObjectFactory(
- new HashSet<>(), Thread.currentThread().getContextClassLoader());
- treeWalkerSpy.configure(createModuleConfig(TypeNameCheck.class));
- treeWalkerSpy.setModuleFactory(factory);
- treeWalkerSpy.setupChild(createModuleConfig(TypeNameCheck.class));
- final File file = temporaryFolder.newFile("file.java");
- final List lines = new ArrayList<>();
- lines.add("class Test {}");
- final FileText fileText = new FileText(file, lines);
- treeWalkerSpy.setFileContents(new FileContents(fileText));
- TestUtil.invokeMethod(treeWalkerSpy, "processFiltered", file, fileText);
- verifyPrivate(treeWalkerSpy, times(1)).invoke("walk",
- any(DetailAST.class), any(FileContents.class), any(classAstState));
- verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredViolations",
- any(String.class), any(FileContents.class), any(DetailAST.class));
- }
-
- @Test
- public void testBehaviourWithOnlyCommentChecks() throws Exception {
- final TreeWalker treeWalkerSpy = spy(new TreeWalker());
- final Class> classAstState =
- Class.forName("com.puppycrawl.tools.checkstyle.TreeWalker$AstState");
- final PackageObjectFactory factory = new PackageObjectFactory(
- new HashSet<>(), Thread.currentThread().getContextClassLoader());
- treeWalkerSpy.configure(createModuleConfig(CommentsIndentationCheck.class));
- treeWalkerSpy.setModuleFactory(factory);
- treeWalkerSpy.setupChild(createModuleConfig(CommentsIndentationCheck.class));
- final File file = temporaryFolder.newFile("file.java");
- final List lines = new ArrayList<>();
- lines.add("class Test {}");
- final FileText fileText = new FileText(file, lines);
- treeWalkerSpy.setFileContents(new FileContents(fileText));
- TestUtil.invokeMethod(treeWalkerSpy, "processFiltered", file, fileText);
- verifyPrivate(treeWalkerSpy, times(1)).invoke("walk",
- any(DetailAST.class), any(FileContents.class), any(classAstState));
- verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredViolations",
- any(String.class), any(FileContents.class), any(DetailAST.class));
- }
-
-}
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java
index b726d9d2a8d..4c0c764916f 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java
@@ -20,6 +20,7 @@
package com.puppycrawl.tools.checkstyle.utils;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
@@ -29,15 +30,20 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Dictionary;
import java.util.Properties;
@@ -45,10 +51,12 @@
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
public class CommonUtilTest extends AbstractPathTestSupport {
@@ -107,26 +115,24 @@ public void testCreatePattern() {
@Test
public void testBadRegex() {
- try {
- CommonUtil.createPattern("[");
- fail("exception expected");
- }
- catch (IllegalArgumentException ex) {
- assertEquals("Failed to initialise regular expression [", ex.getMessage(),
- "Invalid exception message");
- }
+ final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
+ () -> CommonUtil.createPattern("["),
+ "IllegalArgumentException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("Failed to initialise regular expression [");
}
@Test
public void testBadRegex2() {
- try {
- CommonUtil.createPattern("[", Pattern.MULTILINE);
- fail("exception expected");
- }
- catch (IllegalArgumentException ex) {
- assertEquals("Failed to initialise regular expression [", ex.getMessage(),
- "Invalid exception message");
- }
+ final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
+ () -> CommonUtil.createPattern("[", Pattern.MULTILINE),
+ "IllegalArgumentException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("Failed to initialise regular expression [");
}
@Test
@@ -212,14 +218,13 @@ public void testGetExistingConstructor() throws NoSuchMethodException {
@Test
public void testGetNonExistentConstructor() {
- try {
- CommonUtil.getConstructor(Math.class);
- fail("IllegalStateException is expected");
- }
- catch (IllegalStateException expected) {
- assertSame(NoSuchMethodException.class, expected.getCause().getClass(),
- "Invalid exception cause");
- }
+ final IllegalStateException ex = assertThrows(IllegalStateException.class,
+ () -> CommonUtil.getConstructor(Math.class),
+ "IllegalStateException expected");
+ assertWithMessage("Invalid exception cause")
+ .that(ex)
+ .hasCauseThat()
+ .isInstanceOf(NoSuchMethodException.class);
}
@Test
@@ -235,15 +240,13 @@ public void testInvokeConstructor() throws NoSuchMethodException {
@Test
public void testInvokeConstructorThatFails() throws NoSuchMethodException {
final Constructor constructor = Dictionary.class.getConstructor();
-
- try {
- CommonUtil.invokeConstructor(constructor);
- fail("IllegalStateException is expected");
- }
- catch (IllegalStateException expected) {
- assertSame(InstantiationException.class,
- expected.getCause().getClass(), "Invalid exception cause");
- }
+ final IllegalStateException ex = assertThrows(IllegalStateException.class,
+ () -> CommonUtil.invokeConstructor(constructor),
+ "IllegalStateException expected");
+ assertWithMessage("Invalid exception cause")
+ .that(ex)
+ .hasCauseThat()
+ .isInstanceOf(InstantiationException.class);
}
@Test
@@ -258,15 +261,17 @@ public void testClose() {
@Test
public void testCloseWithException() {
- try {
- CommonUtil.close(() -> {
- throw new IOException("Test IOException");
- });
- fail("exception expected");
- }
- catch (IllegalStateException ex) {
- assertEquals("Cannot close the stream", ex.getMessage(), "Invalid exception message");
- }
+ final IllegalStateException ex = assertThrows(IllegalStateException.class,
+ () -> {
+ CommonUtil.close(() -> {
+ throw new IOException("Test IOException");
+ });
+ },
+ "IllegalStateException expected");
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("Cannot close the stream");
}
@Test
@@ -499,6 +504,29 @@ public void testIsCodePointWhitespace() {
.isFalse();
}
+ @Test
+ public void testLoadSuppressionsUriSyntaxException() throws Exception {
+ final URL configUrl = mock(URL.class);
+ when(configUrl.toURI()).thenThrow(URISyntaxException.class);
+ try (MockedStatic utilities =
+ mockStatic(CommonUtil.class, CALLS_REAL_METHODS)) {
+ final String fileName = "/suppressions_none.xml";
+ utilities.when(() -> CommonUtil.getCheckstyleResource(fileName)).thenReturn(configUrl);
+
+ final CheckstyleException ex = assertThrows(CheckstyleException.class,
+ () -> CommonUtil.getUriByFilename(fileName),
+ "CheckstyleException expected");
+ assertWithMessage("Invalid exception cause")
+ .that(ex)
+ .hasCauseThat()
+ .isInstanceOf(URISyntaxException.class);
+ assertWithMessage("Invalid exception message")
+ .that(ex)
+ .hasMessageThat()
+ .isEqualTo("Unable to find: " + fileName);
+ }
+ }
+
private static class TestCloseable implements Closeable {
private boolean closed;
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerJavadoc.java b/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerJavadoc.java
new file mode 100644
index 00000000000..b04ad091866
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerJavadoc.java
@@ -0,0 +1,5 @@
+package com.puppycrawl.tools.checkstyle.treewalker;
+
+/** Javadoc comment. */ // violation
+public class InputTreeWalkerJavadoc {
+}
diff --git a/src/test/resources/org/powermock/extensions/configuration.properties b/src/test/resources/org/powermock/extensions/configuration.properties
deleted file mode 100644
index ce04b51fd08..00000000000
--- a/src/test/resources/org/powermock/extensions/configuration.properties
+++ /dev/null
@@ -1 +0,0 @@
-powermock.global-ignore=com.sun.org.apache.xerces.*,javax.xml.parsers.*,org.w3c.dom.*,org.xml.sax.*