diff --git a/.ci/pitest.sh b/.ci/pitest.sh index 4f25547cef7..122857b8fa1 100755 --- a/.ci/pitest.sh +++ b/.ci/pitest.sh @@ -34,8 +34,8 @@ case $1 in pitest-annotation|pitest-design \ |pitest-metrics|pitest-modifier|pitest-naming \ |pitest-sizes|pitest-whitespace \ -|pitest-packagenamesloader|pitest-tree-walker|pitest-utils \ -|pitest-common-2|pitest-misc) +|pitest-packagenamesloader \ +|pitest-common-2) mvn -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage; declare -a ignoredItems=(); checkPitestReport "${ignoredItems[@]}" @@ -48,8 +48,10 @@ pitest-xpath) "ElementNode.java.html:
                if (hasChildNodes()) {
" "RootNode.java.html:
        if (detailAst != null) {
" "XpathFileGeneratorAstFilter.java.html:
            if (!xpathQueries.isEmpty()) {
" + "XpathFileGeneratorAuditListener.java.html:
            writer.close();
" "XpathFileGeneratorAuditListener.java.html:
        closeStream = outputStreamOptions == OutputStreamOptions.CLOSE;
" "XpathFileGeneratorAuditListener.java.html:
        if (closeStream) {
" + "XpathFileGeneratorAuditListener.java.html:
        writer.flush();
" "XpathQueryGenerator.java.html:
        if (ast.getParent() == null) {
" "XpathQueryGenerator.java.html:
            if (!result) {
" "XpathQueryGenerator.java.html:
                if (toVisit == null) {
" @@ -72,6 +74,8 @@ pitest-regexp) pitest-header) mvn -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);
" "HeaderCheck.java.html:
        if (list.length == 0) {
" "RegexpHeaderCheck.java.html:
        if (list.length == 0) {
" "RegexpHeaderCheck.java.html:
                    isMatch = headerLineNo == headerSize
" @@ -117,7 +121,6 @@ pitest-api) "FileContents.java.html:
            if (hasIntersection) {
" "FileText.java.html:
        if (lineBreaks == null) {
" "FileText.java.html:
            if (lineNo < lineBreakPositions.length) {
" - "LocalizedMessage.java.html:
                    connection.setUseCaches(!reload);
" ); checkPitestReport "${ignoredItems[@]}" ;; @@ -168,7 +171,17 @@ pitest-common) mvn -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)
" + "Checker.java.html:
                if (fileName != null && cacheFile != null) {
" + "Checker.java.html:
            catch (Error error) {
" + "Checker.java.html:
                    cacheFile.remove(fileName);
" + "Checker.java.html:
                if (fileName != null && cacheFile != null) {
" + "Checker.java.html:
                throw new Error("Error was thrown while processing " + file.getPath(), error);
" + "ConfigurationLoader.java.html:
                if (!qName.equals(METADATA)) {
" + "ConfigurationLoader.java.html:
            else if (qName.equals(MESSAGE)) {
" "ConfigurationLoader.java.html:
            final boolean omitIgnoreModules = ignoredModulesOptions == IgnoredModulesOptions.OMIT;
" "DefaultLogger.java.html:
        closeError = errorStreamOptions == OutputStreamOptions.CLOSE;
" "DefaultLogger.java.html:
        closeInfo = infoStreamOptions == OutputStreamOptions.CLOSE;
" @@ -176,9 +189,28 @@ pitest-common) "DefaultLogger.java.html:
        if (closeInfo) {
" "DefaultLogger.java.html:
        if (infoStream == errorStream) {
" "DefaultLogger.java.html:
        if (severityLevel != SeverityLevel.IGNORE) {
" + "ConfigurationLoader.java.html:
                    catch (final CheckstyleException ex) {
" + "ConfigurationLoader.java.html:
        catch (final ParserConfigurationException | IOException | SAXException ex) {
" + "ConfigurationLoader.java.html:
                                        + recentModule.getName(), ex);
" + "ConfigurationLoader.java.html:
                        throw new SAXException(
" + "ConfigurationLoader.java.html:
                    throw new IllegalStateException("Unknown name:" + qName + ".");
" + "ConfigurationLoader.java.html:
            throw new CheckstyleException(UNABLE_TO_PARSE_EXCEPTION_PREFIX, ex);
" "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:
            Flushables.flush(stream, false);
" + "PropertyCacheFile.java.html:
            flushAndCloseOutStream(oos);
" + "PropertyCacheFile.java.html:
            flushAndCloseOutStream(out);
" + "PropertyCacheFile.java.html:
        Closeables.close(stream, false);
" + "PropertyCacheFile.java.html:
        if (stream != null) {
" + "PropertyCacheFile.java.html:
                    changed = true;
" + "PropertyCacheFile.java.html:
        catch (IOException ex) {
" + "PropertyCacheFile.java.html:
        catch (final IOException | NoSuchAlgorithmException ex) {
" + "PropertyCacheFile.java.html:
            throw new CheckstyleException("Unable to load external resource file " + location, ex);
" + "PropertyCacheFile.java.html:
            throw new IllegalStateException("Unable to calculate hashcode.", ex);
" ); checkPitestReport "${ignoredItems[@]}" ;; @@ -189,6 +221,12 @@ pitest-ant) declare -a ignoredItems=( "CheckstyleAntTask.java.html:
            if (toFile == null || !useFile) {
" "CheckstyleAntTask.java.html:
            if (toFile == null || !useFile) {
" + "CheckstyleAntTask.java.html:
            log("Adding standalone file for audit", Project.MSG_VERBOSE);
" + "CheckstyleAntTask.java.html:
            log("To process the files took " + (processingEndTime - processingStartTime)
" + "CheckstyleAntTask.java.html:
            log("Total execution took " + (endTime - startTime) + TIME_SUFFIX,
" + "CheckstyleAntTask.java.html:
        log("To locate the files took " + (endTime - startTime) + TIME_SUFFIX,
" + "CheckstyleAntTask.java.html:
        catch (CheckstyleException ex) {
" + "CheckstyleAntTask.java.html:
            throw new BuildException("Unable to process files: " + files, ex);
" ); checkPitestReport "${ignoredItems[@]}" ;; @@ -265,6 +303,8 @@ pitest-javadoc) "AbstractTypeAwareCheck.java.html:
            if (dotIdx == -1) {
" "AbstractTypeAwareCheck.java.html:
        imports.clear();
" "AbstractTypeAwareCheck.java.html:
        typeParams.clear();
" + "ClassResolver.java.html:
        catch (final ClassNotFoundException ex) {
" + "ClassResolver.java.html:
            throw new IllegalStateException(ex);
" "JavadocTagInfo.java.html:
            .collect(Collectors.toMap(JavadocTagInfo::getName, tagName -> tagName)));
" "JavadocTagInfo.java.html:
            .collect(Collectors.toMap(JavadocTagInfo::getText, tagText -> tagText)));
" "TagParser.java.html:
                while (column < currentLine.length()
" @@ -272,6 +312,37 @@ pitest-javadoc) checkPitestReport "${ignoredItems[@]}" ;; +pitest-tree-walker) + mvn -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-misc) + mvn -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage; + declare -a ignoredItems=( + "TranslationCheck.java.html:
        if (exception instanceof NoSuchFileException) {
" + "TranslationCheck.java.html:
            args = null;
" + "TranslationCheck.java.html:
            key = "general.fileNotFound";
" + ); + checkPitestReport "${ignoredItems[@]}" + ;; + +pitest-utils) + mvn -e -P$1 clean test org.pitest:pitest-maven:mutationCoverage; + declare -a ignoredItems=( + "CommonUtil.java.html:
                    uri = configUrl.toURI();
" + "CommonUtil.java.html:
                catch (final URISyntaxException ex) {
" + "CommonUtil.java.html:
                }
" + "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 6a54fba0846..0b46547b590 100644 --- a/config/import-control-test.xml +++ b/config/import-control-test.xml @@ -7,6 +7,13 @@ + + + + + + diff --git a/config/suppressions.xml b/config/suppressions.xml index 86c3cdbb1a0..e20b5e6b6c1 100644 --- a/config/suppressions.xml +++ b/config/suppressions.xml @@ -79,7 +79,7 @@ files="(Checker|Main|CheckstyleAntTask|JavadocDetailNodeParser)\.java"/> + |TranslationCheckTest|LocalizedMessageTest)\.java"/> @@ -97,4 +97,6 @@ + + diff --git a/pom.xml b/pom.xml index 445489c3531..6a083839446 100644 --- a/pom.xml +++ b/pom.xml @@ -1827,7 +1827,7 @@ com.puppycrawl.tools.checkstyle.filters.SuppressWarningsFilterTest 100 - 100 + 99 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} @@ -2052,8 +2052,8 @@ *.Input* - 100 - 98 + 98 + 97 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} @@ -2511,8 +2511,8 @@ *.Input* - 100 - 99 + 99 + 96 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} @@ -2627,8 +2627,8 @@ com.puppycrawl.tools.checkstyle.filefilters.BeforeExecutionExclusionFileFilterTest - 100 - 98 + 98 + 94 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} @@ -2820,7 +2820,7 @@ 100 - 100 + 99 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} @@ -2988,7 +2988,7 @@ *.Input* - 100 + 99 100 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} @@ -3108,7 +3108,7 @@ *.Input* 100 - 96 + 93 ${pitest.plugin.timeout.factor} ${pitest.plugin.timeout.constant} ${pitest.plugin.threads} diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java index 8dbef183d27..a62c08fdffc 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/PropertyCacheFile.java @@ -57,7 +57,7 @@ * configuration has changed. * */ -final class PropertyCacheFile { +public final class PropertyCacheFile { /** * The property key to use for storing the hashcode of the @@ -93,7 +93,7 @@ final class PropertyCacheFile { * @param config the current configuration, not null * @param fileName the cache file */ - PropertyCacheFile(Configuration config, String fileName) { + public PropertyCacheFile(Configuration config, String fileName) { if (config == null) { throw new IllegalArgumentException("config can not be null"); } diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoader.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoader.java index 4e1cb7df658..4bcc0614379 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoader.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/imports/ImportControlLoader.java @@ -40,7 +40,7 @@ /** * Responsible for loading the contents of an import control configuration file. */ -final class ImportControlLoader extends XmlLoader { +public final class ImportControlLoader extends XmlLoader { /** The public ID for the configuration dtd. */ private static final String DTD_PUBLIC_ID_1_0 = diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java index 7dbd6ebac3c..eceb00d180f 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/AuditEventDefaultFormatterTest.java @@ -20,23 +20,16 @@ package com.puppycrawl.tools.checkstyle; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.when; import java.lang.reflect.Method; 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 org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.api.AuditEvent; import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; import com.puppycrawl.tools.checkstyle.api.SeverityLevel; -@RunWith(PowerMockRunner.class) -@PrepareForTest(AuditEvent.class) public class AuditEventDefaultFormatterTest { @Test @@ -65,38 +58,6 @@ public void testFormatFullyQualifiedModuleNameDoesNotContainCheckSuffix() { assertEquals("Invalid format", expected, formatter.format(event)); } - @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)); - } - @Test public void testFormatModuleWithModuleId() { final LocalizedMessage message = new LocalizedMessage(1, 1, null, null, null, @@ -124,22 +85,12 @@ public void testCalculateBufferLength() throws Exception { assertEquals("Buffer length is not expected", 54, result); } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class TestModuleCheck { // no code } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class TestModule { // no code diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java index 641bed4cb03..2d53a38db81 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/CheckerTest.java @@ -23,21 +23,17 @@ import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_FINISHED_MESSAGE; import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_STARTED_MESSAGE; import static com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck.MSG_KEY_NO_NEWLINE_EOF; -import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOError; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -62,7 +58,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.powermock.api.mockito.PowerMockito; import org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.api.AbstractCheck; @@ -661,152 +656,6 @@ public void testClearCacheWhenCacheFileIsNotSet() { Whitebox.getInternalState(checker, "cacheFile")); } - @Test - public void testCatchErrorInProcessFilesMethod() throws Exception { - // The idea of the test is to satisfy coverage rate. - // An Error indicates serious problems that a reasonable application should not try to - // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 - // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, - // that is why we use PowerMockito to reproduce them. - final File mock = PowerMockito.mock(File.class); - // Assume that I/O error is happened when we try to invoke 'lastModified()' method. - final String errorMessage = "Java Virtual Machine is broken" - + " or has run out of resources necessary for it to continue operating."; - final Error expectedError = new IOError(new InternalError(errorMessage)); - when(mock.lastModified()).thenThrow(expectedError); - when(mock.getAbsolutePath()).thenReturn("testFile"); - final Checker checker = new Checker(); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. - catch (Error error) { - assertThat("Error cause differs from IOError", - error.getCause(), instanceOf(IOError.class)); - assertThat("Error cause is not InternalError", - error.getCause().getCause(), instanceOf(InternalError.class)); - assertEquals("Error message is not expected", - errorMessage, error.getCause().getCause().getMessage()); - } - } - - @Test - public void testCatchErrorWithNoFileName() throws Exception { - // The idea of the test is to satisfy coverage rate. - // An Error indicates serious problems that a reasonable application should not try to - // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 - // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, - // that is why we use PowerMockito to reproduce them. - final File mock = PowerMockito.mock(File.class); - // Assume that I/O error is happened when we try to invoke 'lastModified()' method. - final String errorMessage = "Java Virtual Machine is broken" - + " or has run out of resources necessary for it to continue operating."; - final Error expectedError = new IOError(new InternalError(errorMessage)); - when(mock.lastModified()).thenThrow(expectedError); - final Checker checker = new Checker(); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. - catch (Error error) { - assertThat("Error cause differs from IOError", - error.getCause(), instanceOf(IOError.class)); - assertThat("Error cause is not InternalError", - error.getCause().getCause(), instanceOf(InternalError.class)); - assertEquals("Error message is not expected", - errorMessage, error.getCause().getCause().getMessage()); - } - } - - @Test - public void testCatchErrorWithCache() throws Exception { - final File cacheFile = temporaryFolder.newFile(); - - final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); - checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); - checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); - - final File mock = PowerMockito.mock(File.class); - final String errorMessage = "Java Virtual Machine is broken" - + " or has run out of resources necessary for it to continue operating."; - final Error expectedError = new IOError(new InternalError(errorMessage)); - when(mock.getAbsolutePath()).thenReturn("testFile"); - when(mock.getAbsoluteFile()).thenThrow(expectedError); - final Checker checker = new Checker(); - checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); - checker.configure(checkerConfig); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. - catch (Error error) { - assertThat("Error cause differs from IOError", - error.getCause(), instanceOf(IOError.class)); - assertEquals("Error message is not expected", - errorMessage, error.getCause().getCause().getMessage()); - - // destroy is called by Main - checker.destroy(); - - final Properties cache = new Properties(); - cache.load(Files.newBufferedReader(cacheFile.toPath())); - - assertEquals("Cache has unexpected size", - 1, cache.size()); - assertNull("testFile is not in cache", - cache.getProperty("testFile")); - } - } - - @Test - public void testCatchErrorWithCacheWithNoFileName() throws Exception { - final File cacheFile = temporaryFolder.newFile(); - - final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); - checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); - checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); - - final File mock = PowerMockito.mock(File.class); - final String errorMessage = "Java Virtual Machine is broken" - + " or has run out of resources necessary for it to continue operating."; - final Error expectedError = new IOError(new InternalError(errorMessage)); - when(mock.getAbsolutePath()).thenThrow(expectedError); - final Checker checker = new Checker(); - checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); - checker.configure(checkerConfig); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. - catch (Error error) { - assertThat("Error cause differs from IOError", - error.getCause(), instanceOf(IOError.class)); - assertEquals("Error message is not expected", - errorMessage, error.getCause().getCause().getMessage()); - - // destroy is called by Main - checker.destroy(); - - final Properties cache = new Properties(); - cache.load(Files.newBufferedReader(cacheFile.toPath())); - - assertEquals("Cache has unexpected size", - 1, cache.size()); - } - } - /** * It is OK to have long test method name here as it describes the test purpose. */ @@ -1029,75 +878,6 @@ public void testExceptionWithCache() throws Exception { } } - @Test - public void testExceptionWithNoFileName() { - // The idea of the test is to satisfy coverage rate. - // An Error indicates serious problems that a reasonable application should not try to - // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 - // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, - // that is why we use PowerMockito to reproduce them. - final File mock = PowerMockito.mock(File.class); - final String errorMessage = "Security Exception"; - final Exception expectedError = new SecurityException(errorMessage); - when(mock.getAbsolutePath()).thenThrow(expectedError); - final Checker checker = new Checker(); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - catch (CheckstyleException ex) { - assertThat("Error cause differs from SecurityException", - ex.getCause(), instanceOf(SecurityException.class)); - assertEquals("Error message is not expected", - errorMessage, ex.getCause().getMessage()); - } - } - - @Test - public void testExceptionWithCacheAndNoFileName() throws Exception { - final File cacheFile = temporaryFolder.newFile(); - - final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); - checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); - checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); - - // The idea of the test is to satisfy coverage rate. - // An Error indicates serious problems that a reasonable application should not try to - // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 - // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, - // that is why we use PowerMockito to reproduce them. - final File mock = PowerMockito.mock(File.class); - final String errorMessage = "Security Exception"; - final Exception expectedError = new SecurityException(errorMessage); - when(mock.getAbsolutePath()).thenThrow(expectedError); - final Checker checker = new Checker(); - checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); - checker.configure(checkerConfig); - final List filesToProcess = new ArrayList<>(); - filesToProcess.add(mock); - try { - checker.process(filesToProcess); - fail("IOError is expected!"); - } - catch (CheckstyleException ex) { - assertThat("Error cause differs from SecurityException", - ex.getCause(), instanceOf(SecurityException.class)); - assertEquals("Error message is not expected", - errorMessage, ex.getCause().getMessage()); - - // destroy is called by Main - checker.destroy(); - - final Properties cache = new Properties(); - cache.load(Files.newBufferedReader(cacheFile.toPath())); - - assertEquals("Cache has unexpected size", - 1, cache.size()); - } - } - @Test public void testHaltOnExceptionOff() throws Exception { final DefaultConfiguration checkConfig = diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java index 7687ba8a003..3b2d2086494 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/ConfigurationLoaderTest.java @@ -23,10 +23,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.powermock.api.mockito.PowerMockito.when; import java.io.File; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Files; @@ -36,12 +34,7 @@ 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 org.powermock.reflect.Whitebox; -import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -51,8 +44,6 @@ /** * Unit test for ConfigurationLoader. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({DefaultConfiguration.class, ConfigurationLoader.class}) public class ConfigurationLoaderTest extends AbstractPathTestSupport { @Override @@ -457,38 +448,6 @@ public void testExternalEntityFromUri() throws Exception { verifyConfigNode(config, "Checker", 2, atts); } - @Test - public void testIncorrectTag() throws Exception { - try { - final Class aClassParent = ConfigurationLoader.class; - final Constructor ctorParent = aClassParent.getDeclaredConstructor( - PropertyResolver.class, boolean.class, ThreadModeSettings.class); - ctorParent.setAccessible(true); - final Object objParent = ctorParent.newInstance(null, true, null); - - final Class aClass = Class.forName("com.puppycrawl.tools.checkstyle." - + "ConfigurationLoader$InternalLoader"); - final Constructor constructor = aClass.getConstructor(objParent.getClass()); - constructor.setAccessible(true); - - final Object obj = constructor.newInstance(objParent); - - final Class[] param = new Class[] {String.class, String.class, - String.class, Attributes.class, }; - final Method method = aClass.getDeclaredMethod("startElement", param); - - method.invoke(obj, "", "", "hello", null); - - fail("Exception is expected"); - } - catch (InvocationTargetException ex) { - assertTrue("Invalid exception cause", - ex.getCause() instanceof IllegalStateException); - assertEquals("Invalid exception cause message", - "Unknown name:" + "hello" + ".", ex.getCause().getMessage()); - } - } - @Test public void testNonExistentPropertyName() throws Exception { try { @@ -597,37 +556,6 @@ public void testLoadConfigurationFromClassPath() throws Exception { 0, children[0].getChildren().length); } - @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.getAttributeNames()).thenReturn(new String[] {"severity"}); - when(tested.getName()).thenReturn("MemberName"); - when(tested.getAttribute("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()), true); - fail("Exception is expected"); - } - catch (CheckstyleException expected) { - assertEquals("Invalid exception cause message", - "Problem during accessing 'severity' attribute for MemberName", - expected.getCause().getMessage()); - } - } - @Test public void testParsePropertyString() throws Exception { final List propertyRefs = new ArrayList<>(); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java index 5e61012233f..952697bafdc 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/DefaultLoggerTest.java @@ -23,9 +23,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import java.io.ByteArrayOutputStream; import java.io.OutputStream; @@ -37,7 +34,6 @@ import com.puppycrawl.tools.checkstyle.api.AuditEvent; import com.puppycrawl.tools.checkstyle.api.AutomaticBean; import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; -import com.puppycrawl.tools.checkstyle.utils.CommonUtil; public class DefaultLoggerTest { @@ -78,43 +74,6 @@ public void testCtorWithTwoParameters() { output.contains("java.lang.IllegalStateException: upsss")); } - @Test - public void testNewCtor() throws Exception { - final OutputStream infoStream = spy(new ByteArrayOutputStream()); - final ByteArrayOutputStream errorStream = spy(new ByteArrayOutputStream()); - final DefaultLogger dl = new DefaultLogger(infoStream, - AutomaticBean.OutputStreamOptions.CLOSE, errorStream, - AutomaticBean.OutputStreamOptions.CLOSE); - dl.auditStarted(null); - dl.addException(new AuditEvent(5000, "myfile"), new IllegalStateException("upsss")); - dl.auditFinished(new AuditEvent(6000, "myfile")); - final String output = errorStream.toString(StandardCharsets.UTF_8.name()); - final LocalizedMessage addExceptionMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.ADD_EXCEPTION_MESSAGE, - new String[] {"myfile"}, null, - getClass(), null); - final LocalizedMessage startMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.AUDIT_STARTED_MESSAGE, - CommonUtil.EMPTY_STRING_ARRAY, null, - getClass(), null); - final LocalizedMessage finishMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.AUDIT_FINISHED_MESSAGE, - CommonUtil.EMPTY_STRING_ARRAY, null, - getClass(), null); - - verify(infoStream, times(1)).close(); - verify(errorStream, times(1)).close(); - final String infoOutput = infoStream.toString(); - assertTrue("Message should contain exception info, but was " + infoOutput, - infoOutput.contains(startMessage.getMessage())); - assertTrue("Message should contain exception info, but was " + infoOutput, - infoOutput.contains(finishMessage.getMessage())); - assertTrue("Message should contain exception info, but was " + output, - output.contains(addExceptionMessage.getMessage())); - assertTrue("Message should contain exception info, but was " + output, - output.contains("java.lang.IllegalStateException: upsss")); - } - @Test public void testNewCtorWithTwoParameters() { final OutputStream infoStream = new ByteArrayOutputStream(); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java index 907872abcae..7d3b6d78131 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java @@ -25,9 +25,6 @@ import static org.junit.Assert.assertNotEquals; 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.io.ByteArrayOutputStream; import java.io.File; @@ -52,9 +49,7 @@ import org.junit.contrib.java.lang.system.SystemErrRule; import org.junit.contrib.java.lang.system.SystemOutRule; import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.api.AuditListener; import com.puppycrawl.tools.checkstyle.api.AutomaticBean; @@ -62,10 +57,7 @@ import com.puppycrawl.tools.checkstyle.api.Configuration; import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; import com.puppycrawl.tools.checkstyle.internal.testmodules.TestRootModuleChecker; -import com.puppycrawl.tools.checkstyle.utils.CommonUtil; -@RunWith(PowerMockRunner.class) -@PrepareForTest({Main.class, CommonUtil.class}) public class MainTest { private static final String SHORT_USAGE = String.format(Locale.ROOT, @@ -626,37 +618,64 @@ public void testExistingDirectoryWithViolations() throws Exception { getPath("")); } + /** + * Test doesn't need to be serialized. + * @noinspection SerializableInnerClassWithNonSerializableOuterClass + */ @Test - @SuppressWarnings("unchecked") public void testListFilesNotFile() throws Exception { - final Class optionsClass = Class.forName(Main.class.getName()); - final Method method = optionsClass.getDeclaredMethod("listFiles", File.class, List.class); - method.setAccessible(true); + final File fileMock = new File("") { + private static final long serialVersionUID = 1L; - final File fileMock = mock(File.class); - when(fileMock.canRead()).thenReturn(true); - when(fileMock.isDirectory()).thenReturn(false); - when(fileMock.isFile()).thenReturn(false); + @Override + public boolean canRead() { + return true; + } - final List result = (List) method.invoke(null, fileMock, - new ArrayList()); + @Override + public boolean isDirectory() { + return false; + } + + @Override + public boolean isFile() { + return false; + } + }; + + final List result = Whitebox.invokeMethod(Main.class, "listFiles", + fileMock, new ArrayList()); assertEquals("Invalid result size", 0, result.size()); } + /** + * Test doesn't need to be serialized. + * @noinspection SerializableInnerClassWithNonSerializableOuterClass + */ @Test - @SuppressWarnings("unchecked") public void testListFilesDirectoryWithNull() throws Exception { - final Class optionsClass = Class.forName(Main.class.getName()); - final Method method = optionsClass.getDeclaredMethod("listFiles", File.class, List.class); - method.setAccessible(true); + final File[] nullResult = null; + final File fileMock = new File("") { + private static final long serialVersionUID = 1L; + + @Override + public boolean canRead() { + return true; + } - final File fileMock = mock(File.class); - when(fileMock.canRead()).thenReturn(true); - when(fileMock.isDirectory()).thenReturn(true); - when(fileMock.listFiles()).thenReturn(null); + @Override + public boolean isDirectory() { + return true; + } - final List result = (List) method.invoke(null, fileMock, - new ArrayList()); + @Override + public File[] listFiles() { + return nullResult; + } + }; + + final List result = Whitebox.invokeMethod(Main.class, "listFiles", + fileMock, new ArrayList()); assertEquals("Invalid result size", 0, result.size()); } @@ -1414,23 +1433,6 @@ public void testModuleNameInMultiThreadMode() throws Exception { } } - /** - * This test is a workaround for the Jacoco limitations. A call to {@link System#exit(int)} - * will never return, so Jacoco coverage probe will be missing. By mocking the {@code System} - * class we turn {@code System.exit()} to noop and the Jacoco coverage probe should succeed. - * - * @throws Exception if error occurs - * @see Jacoco issue 117 - */ - @Test - public void testJacocoWorkaround() throws Exception { - final String expected = "Missing required parameter: " + EOL + SHORT_USAGE; - mockStatic(System.class); - Main.main(); - assertEquals("Unexpected output log", "", systemOut.getLog()); - assertEquals("Unexpected system error log", expected, systemErr.getLog()); - } - @Test public void testMissingFiles() throws Exception { exit.expectSystemExitWithStatus(-1); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java index 4f850c55762..efd97e00aee 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/PackageNamesLoaderTest.java @@ -19,44 +19,34 @@ package com.puppycrawl.tools.checkstyle; -import static com.puppycrawl.tools.checkstyle.utils.CommonUtil.EMPTY_BYTE_ARRAY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; 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.when; -import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; +import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; -import java.util.Iterator; import java.util.Set; 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 org.xml.sax.Attributes; import org.xml.sax.SAXException; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; /** - * Enter a description of class PackageNamesLoaderTest.java. + * Custom class loader is needed to pass URLs to pretend these are loaded from the classpath + * though we can't add/change the files for testing. The class loader is nested in this class, + * so the custom class loader we are using is safe. + * @noinspection ClassLoaderInstantiation */ -@RunWith(PowerMockRunner.class) -@PrepareForTest(PackageNamesLoader.class) public class PackageNamesLoaderTest extends AbstractPathTestSupport { @Override @@ -74,30 +64,21 @@ public void testDefault() packageNames.size()); } - /** - * Tests the loading of package names. This test needs mocking, because the package names would - * have to be placed in {@literal checkstyle_packages.xml}, but this will affect every test, - * which is undesired. - * - * @throws Exception if error occurs - */ @Test - @SuppressWarnings("unchecked") - public void testPackagesFile() throws Exception { - final URLConnection mockConnection = Mockito.mock(URLConnection.class); - when(mockConnection.getInputStream()).thenReturn( - Files.newInputStream(Paths.get(getPath("InputPackageNamesLoaderFile.xml")))); - - final URL url = getMockUrl(mockConnection); + public void testNoPackages() throws Exception { + final Set actualPackageNames = PackageNamesLoader + .getPackageNames(new TestUrlsClassLoader(Collections.emptyEnumeration())); - final Enumeration enumeration = mock(Enumeration.class); - when(enumeration.hasMoreElements()).thenReturn(true).thenReturn(false); - when(enumeration.nextElement()).thenReturn(url); + assertEquals("Invalid package names length.", 0, actualPackageNames.size()); + } - final ClassLoader classLoader = mock(ClassLoader.class); - when(classLoader.getResources("checkstyle_packages.xml")).thenReturn(enumeration); + @Test + public void testPackagesFile() throws Exception { + final Enumeration enumeration = Collections.enumeration(Collections.singleton( + new File(getPath("InputPackageNamesLoaderFile.xml")).toURI().toURL())); - final Set actualPackageNames = PackageNamesLoader.getPackageNames(classLoader); + final Set actualPackageNames = PackageNamesLoader + .getPackageNames(new TestUrlsClassLoader(enumeration)); final String[] expectedPackageNames = { "com.puppycrawl.tools.checkstyle", "com.puppycrawl.tools.checkstyle.checks", @@ -127,69 +108,49 @@ public void testPackagesFile() throws Exception { } @Test - @SuppressWarnings("unchecked") public void testPackagesWithDots() throws Exception { - final Constructor constructor = - PackageNamesLoader.class.getDeclaredConstructor(); - constructor.setAccessible(true); - final PackageNamesLoader loader = constructor.newInstance(); - - final Attributes attributes = mock(Attributes.class); - when(attributes.getValue("name")).thenReturn("coding."); - loader.startElement("", "", "package", attributes); - loader.endElement("", "", "package"); - - final Field field = PackageNamesLoader.class.getDeclaredField("packageNames"); - field.setAccessible(true); - final Set list = (Set) field.get(loader); - assertEquals("Invalid package name", "coding.", list.iterator().next()); + final Enumeration enumeration = Collections.enumeration(Collections.singleton( + new File(getPath("InputPackageNamesLoaderWithDots.xml")).toURI().toURL())); + + final Set actualPackageNames = PackageNamesLoader + .getPackageNames(new TestUrlsClassLoader(enumeration)); + final String[] expectedPackageNames = { + "coding.", + }; + + assertEquals("Invalid package names length.", expectedPackageNames.length, + actualPackageNames.size()); + final Set checkstylePackagesSet = + new HashSet<>(Arrays.asList(expectedPackageNames)); + assertEquals("Invalid names set.", checkstylePackagesSet, actualPackageNames); } @Test - @SuppressWarnings("unchecked") public void testPackagesWithDotsEx() throws Exception { - final Constructor constructor = - PackageNamesLoader.class.getDeclaredConstructor(); - constructor.setAccessible(true); - final PackageNamesLoader loader = constructor.newInstance(); - - final Attributes attributes1 = mock(Attributes.class); - when(attributes1.getValue("name")).thenReturn("coding."); - final Attributes attributes2 = mock(Attributes.class); - when(attributes2.getValue("name")).thenReturn("specific"); - - loader.startElement("", "", "package", attributes1); - loader.startElement("", "", "package", attributes2); - loader.endElement("", "", "package"); - loader.endElement("", "", "package"); - - final Field field = PackageNamesLoader.class.getDeclaredField("packageNames"); - field.setAccessible(true); - final Set list = (Set) field.get(loader); - assertEquals("Invalid list size", 2, list.size()); - final Iterator iterator = list.iterator(); - assertEquals("Invalid package name", "coding.specific", iterator.next()); - assertEquals("Invalid package name", "coding.", iterator.next()); + final Enumeration enumeration = Collections.enumeration(Collections.singleton( + new File(getPath("InputPackageNamesLoaderWithDotsEx.xml")).toURI().toURL())); + + final Set actualPackageNames = PackageNamesLoader + .getPackageNames(new TestUrlsClassLoader(enumeration)); + final String[] expectedPackageNames = { + "coding.specific", + "coding.", + }; + + assertEquals("Invalid package names length.", expectedPackageNames.length, + actualPackageNames.size()); + final Set checkstylePackagesSet = + new HashSet<>(Arrays.asList(expectedPackageNames)); + assertEquals("Invalid names set.", checkstylePackagesSet, actualPackageNames); } @Test - @SuppressWarnings("unchecked") public void testPackagesWithSaxException() throws Exception { - final URLConnection mockConnection = Mockito.mock(URLConnection.class); - when(mockConnection.getInputStream()).thenReturn( - new ByteArrayInputStream(EMPTY_BYTE_ARRAY)); - - final URL url = getMockUrl(mockConnection); - - final Enumeration enumeration = mock(Enumeration.class); - when(enumeration.hasMoreElements()).thenReturn(true); - when(enumeration.nextElement()).thenReturn(url); - - final ClassLoader classLoader = mock(ClassLoader.class); - when(classLoader.getResources("checkstyle_packages.xml")).thenReturn(enumeration); + final Enumeration enumeration = Collections.enumeration(Collections.singleton( + new File(getPath("InputPackageNamesLoaderNotXml.java")).toURI().toURL())); try { - PackageNamesLoader.getPackageNames(classLoader); + PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration)); fail("CheckstyleException is expected"); } catch (CheckstyleException ex) { @@ -198,22 +159,29 @@ public void testPackagesWithSaxException() throws Exception { } @Test - @SuppressWarnings("unchecked") public void testPackagesWithIoException() throws Exception { - final URLConnection mockConnection = Mockito.mock(URLConnection.class); - when(mockConnection.getInputStream()).thenReturn(null); - - final URL url = getMockUrl(mockConnection); + final URLConnection urlConnection = new URLConnection(null) { + @Override + public void connect() { + // no code + } - final Enumeration enumer = mock(Enumeration.class); - when(enumer.hasMoreElements()).thenReturn(true); - when(enumer.nextElement()).thenReturn(url); + @Override + public InputStream getInputStream() { + return null; + } + }; + final URL url = new URL("test", null, 0, "", new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) { + return urlConnection; + } + }); - final ClassLoader classLoader = mock(ClassLoader.class); - when(classLoader.getResources("checkstyle_packages.xml")).thenReturn(enumer); + final Enumeration enumeration = Collections.enumeration(Collections.singleton(url)); try { - PackageNamesLoader.getPackageNames(classLoader); + PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration)); fail("CheckstyleException is expected"); } catch (CheckstyleException ex) { @@ -224,12 +192,9 @@ public void testPackagesWithIoException() throws Exception { } @Test - public void testPackagesWithIoExceptionGetResources() throws Exception { - final ClassLoader classLoader = mock(ClassLoader.class); - when(classLoader.getResources("checkstyle_packages.xml")).thenThrow(IOException.class); - + public void testPackagesWithIoExceptionGetResources() { try { - PackageNamesLoader.getPackageNames(classLoader); + PackageNamesLoader.getPackageNames(new TestIoExceptionClassLoader()); fail("CheckstyleException is expected"); } catch (CheckstyleException ex) { @@ -239,14 +204,34 @@ public void testPackagesWithIoExceptionGetResources() throws Exception { } } - private static URL getMockUrl(final URLConnection connection) throws IOException { - final URLStreamHandler handler = new URLStreamHandler() { - @Override - protected URLConnection openConnection(final URL url) { - return connection; - } - }; - return new URL("http://foo.bar", "foo.bar", 80, "", handler); + /** + * Custom class loader is needed to pass URLs to pretend these are loaded from the classpath + * though we can't add/change the files for testing. + * @noinspection CustomClassloader + */ + private static class TestUrlsClassLoader extends ClassLoader { + + private final Enumeration urls; + + TestUrlsClassLoader(Enumeration urls) { + this.urls = urls; + } + + @Override + public Enumeration getResources(String name) { + return urls; + } + } + + /** + * Custom class loader is needed to throw an exception to test a catch statement. + * @noinspection CustomClassloader + */ + private static class TestIoExceptionClassLoader extends ClassLoader { + @Override + public Enumeration getResources(String name) throws IOException { + throw new IOException("test"); + } } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java index fa6a80657e6..a5f9708989f 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/PackageObjectFactoryTest.java @@ -31,13 +31,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.mockStatic; import java.io.File; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; @@ -49,12 +45,6 @@ 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 org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; @@ -62,15 +52,11 @@ import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; import com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck; import com.puppycrawl.tools.checkstyle.internal.utils.CheckUtil; -import com.puppycrawl.tools.checkstyle.utils.ModuleReflectionUtil; /** * Enter a description of class PackageObjectFactoryTest.java. * */ -@RunWith(PowerMockRunner.class) -@PowerMockIgnore(value = "com.puppycrawl.tools.checkstyle.api.*", globalIgnore = false) -@PrepareForTest(ModuleReflectionUtil.class) public class PackageObjectFactoryTest { private final PackageObjectFactory factory = new PackageObjectFactory( @@ -334,43 +320,6 @@ public void testCreateCheckWithPartialPackageNameByBruteForce() throws Exception assertNotNull("Check should not be null when creating module from name", check); } - /** - * 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 Whitebox} 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 = Whitebox.getInternalState(objectFactory, - internalFieldName); - assertNull("Expected uninitialized field", nullMap); - - final Object instance = objectFactory.createModule(name); - assertEquals("Expected empty string", "", instance); - - final Map emptyMap = Whitebox.getInternalState(objectFactory, - internalFieldName); - assertEquals("Expected empty map", Collections.emptyMap(), emptyMap); - } - @Test public void testJoinPackageNamesWithClassName() throws Exception { final Class clazz = PackageObjectFactory.class; @@ -432,11 +381,6 @@ public void testGetShortFromFullModuleNamesThirdParty() { PackageObjectFactory.getShortFromFullModuleNames(fullName)); } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ 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 8dc9efb329c..e811fc0ac90 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/PropertyCacheFileTest.java @@ -21,32 +21,20 @@ 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.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.powermock.api.mockito.PowerMockito.doNothing; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.verifyStatic; -import static org.powermock.api.mockito.PowerMockito.when; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; 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; @@ -55,22 +43,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.ArgumentMatchers; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import com.google.common.io.BaseEncoding; import com.google.common.io.ByteStreams; -import com.google.common.io.Closeables; -import com.google.common.io.Flushables; -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, Closeables.class, Flushables.class}) public class PropertyCacheFileTest extends AbstractPathTestSupport { @Rule @@ -127,26 +105,6 @@ public void testResetIfFileDoesNotExist() throws IOException { cache.get(PropertyCacheFile.CONFIG_HASH_KEY)); } - @Test - public void testCloseAndFlushOutputStreamAfterCreatingHashCode() throws IOException { - mockStatic(Closeables.class); - doNothing().when(Closeables.class); - Closeables.close(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); - mockStatic(Flushables.class); - doNothing().when(Flushables.class); - Flushables.flush(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); - - final Configuration config = new DefaultConfiguration("myName"); - final PropertyCacheFile cache = new PropertyCacheFile(config, "fileDoesNotExist.txt"); - cache.load(); - - verifyStatic(Closeables.class, times(1)); - Closeables.close(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); - - verifyStatic(Flushables.class, times(1)); - Flushables.flush(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); - } - @Test public void testPopulateDetails() throws IOException { final Configuration config = new DefaultConfiguration("myName"); @@ -262,64 +220,6 @@ public void testExternalResourceIsSavedInCache() throws Exception { cache.get("module-resource*?:" + pathToResource)); } - /** - * 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 testFlushAndCloseCacheFileOutputStream() throws IOException { - mockStatic(Closeables.class); - doNothing().when(Closeables.class); - Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); - mockStatic(Flushables.class); - doNothing().when(Flushables.class); - Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); - - final Configuration config = new DefaultConfiguration("myName"); - final PropertyCacheFile cache = new PropertyCacheFile(config, - temporaryFolder.newFile().getPath()); - - cache.put("CheckedFileName.java", System.currentTimeMillis()); - cache.persist(); - - verifyStatic(Closeables.class, times(1)); - Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); - verifyStatic(Flushables.class, times(1)); - Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); - } - @Test public void testCacheDirectoryDoesNotExistAndShouldBeCreated() throws IOException { final Configuration config = new DefaultConfiguration("myName"); @@ -345,138 +245,6 @@ public void testPathToCacheContainsOnlyFileName() throws IOException { Files.delete(Paths.get(filePath)); } - @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(); - cacheDetails.load(Files.newBufferedReader(cacheFile.toPath())); - - 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(); - cacheDetails.load(Files.newBufferedReader(cacheFile.toPath())); - - 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]); - } - @Test public void testChangeInConfig() throws Exception { final DefaultConfiguration config = new DefaultConfiguration("myConfig"); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java index f8e39a28d99..02f1925bffc 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/TreeWalkerTest.java @@ -23,10 +23,6 @@ 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 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.io.Writer; @@ -43,18 +39,13 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; import org.mockito.internal.util.Checks; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; 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; @@ -71,8 +62,6 @@ import com.puppycrawl.tools.checkstyle.filters.SuppressionXpathFilter; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; -@RunWith(PowerMockRunner.class) -@PrepareForTest(TreeWalker.class) public class TreeWalkerTest extends AbstractModuleTestSupport { @Rule @@ -353,46 +342,6 @@ public void testBehaviourWithZeroChecks() throws Exception { assertTrue("No checks -> No parsing", checks.isEmpty()); } - @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 {}"); - treeWalkerSpy.processFiltered(file, new FileText(file, lines)); - verifyPrivate(treeWalkerSpy, times(1)).invoke("walk", - any(DetailAST.class), any(FileContents.class), any(classAstState)); - verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredMessages", - 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 {}"); - treeWalkerSpy.processFiltered(file, new FileText(file, lines)); - verifyPrivate(treeWalkerSpy, times(1)).invoke("walk", - any(DetailAST.class), any(FileContents.class), any(classAstState)); - verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredMessages", - any(String.class), any(FileContents.class), any(DetailAST.class)); - } - @Test public void testBehaviourWithOrdinaryAndCommentChecks() throws Exception { final TreeWalker treeWalker = new TreeWalker(); @@ -560,11 +509,6 @@ public void testExternalResourceFiltersWithNoExternalResource() throws Exception verify(checkerConfig, filePath, expected); } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class BadJavaDocCheck extends AbstractCheck { @Override @@ -584,11 +528,6 @@ public int[] getRequiredTokens() { } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class VerifyInitCheck extends AbstractCheck { private static boolean initWasCalled; @@ -620,11 +559,6 @@ public static boolean isInitWasCalled() { } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class VerifyDestroyCheck extends AbstractCheck { private static boolean destroyWasCalled; @@ -660,11 +594,6 @@ public static boolean isDestroyWasCalled() { } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class VerifyDestroyCommentCheck extends VerifyDestroyCheck { @Override @@ -674,11 +603,6 @@ public boolean isCommentNodesRequired() { } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class RequiredTokenIsNotInDefaultsCheck extends AbstractCheck { @Override @@ -698,11 +622,6 @@ public int[] getAcceptableTokens() { } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class RequiredTokenIsEmptyIntArray extends AbstractCheck { @Override diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java index 472e681ef61..4a5bb0d2eab 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java @@ -22,13 +22,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @@ -146,7 +142,7 @@ public void testAddException() { } @Test - public void testCorrectOne() throws IOException { + public void testCorrectOne() { final AuditEvent event = createAuditEvent("InputXpathFileGeneratorAuditListener.java", FIRST_MESSAGE); @@ -169,7 +165,7 @@ public void testCorrectOne() throws IOException { } @Test - public void testCorrectTwo() throws IOException { + public void testCorrectTwo() { final AuditEvent event1 = createAuditEvent("InputXpathFileGeneratorAuditListener.java", SECOND_MESSAGE); @@ -199,7 +195,7 @@ public void testCorrectTwo() throws IOException { } @Test - public void testOnlyOneMatching() throws IOException { + public void testOnlyOneMatching() { final AuditEvent event1 = createAuditEvent("InputXpathFileGeneratorAuditListener.java", 10, 5, MethodParamPadCheck.class); @@ -269,8 +265,8 @@ private static String getPath(String filename) { + filename; } - private static void verifyOutput(String expected, AuditEvent... events) throws IOException { - final OutputStream out = spy(new ByteArrayOutputStream()); + private static void verifyOutput(String expected, AuditEvent... events) { + final OutputStream out = new ByteArrayOutputStream(); final XpathFileGeneratorAuditListener listener = new XpathFileGeneratorAuditListener(out, AutomaticBean.OutputStreamOptions.CLOSE); @@ -280,9 +276,6 @@ private static void verifyOutput(String expected, AuditEvent... events) throws I listener.auditFinished(null); - verify(out, times(1)).flush(); - verify(out, times(1)).close(); - final String actual = out.toString(); assertEquals("Invalid suppressions file content", expected, actual); } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/ant/CheckstyleAntTaskTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/ant/CheckstyleAntTaskTest.java index 015c2c25300..2ee7e84b586 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/ant/CheckstyleAntTaskTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/ant/CheckstyleAntTaskTest.java @@ -25,15 +25,12 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mockStatic; import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -47,10 +44,6 @@ import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.resources.FileResource; 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 org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport; @@ -61,8 +54,6 @@ import com.puppycrawl.tools.checkstyle.internal.testmodules.CheckerStub; import com.puppycrawl.tools.checkstyle.internal.testmodules.TestRootModuleChecker; -@RunWith(PowerMockRunner.class) -@PrepareForTest(CheckstyleAntTask.class) public class CheckstyleAntTaskTest extends AbstractPathTestSupport { private static final String FLAWLESS_INPUT = @@ -148,16 +139,16 @@ public final void testPathsFileWithLogVerification() throws IOException { antTask.execute(); // then - final List loggedMessages = antTask.getLoggedMessages(); + final List loggedMessages = antTask.getLoggedMessages(); assertEquals("Scanning path was not logged", 1, loggedMessages.stream().filter( - msg -> msg.getMsg().startsWith("1) Scanning path")).count()); + msg -> msg.startsWith("1) Scanning path")).count()); assertEquals("Scanning path was not logged", 1, loggedMessages.stream().filter( - msg -> msg.getMsg().startsWith("1) Adding 1 files from path")).count()); + msg -> msg.startsWith("1) Adding 1 files from path")).count()); assertEquals("Scanning empty was logged", 0, loggedMessages.stream().filter( - msg -> msg.getMsg().startsWith("2) Adding 0 files from path ")).count()); + msg -> msg.startsWith("2) Adding 0 files from path ")).count()); assertTrue("Checker is not processed", TestRootModuleChecker.isProcessed()); @@ -638,9 +629,8 @@ public void testSetClasspath() { antTask.setClasspath(new Path(project, path1)); antTask.setClasspath(new Path(project, path2)); - assertNotNull("Classpath should not be null", - Whitebox.getInternalState(antTask, "classpath")); final Path classpath = Whitebox.getInternalState(antTask, "classpath"); + assertNotNull("Classpath should not be null", classpath); assertTrue("Classpath contain provided path", classpath.toString().contains(path1)); assertTrue("Classpath contain provided path", classpath.toString().contains(path2)); } @@ -729,138 +719,24 @@ public void testClassloaderInRootModule() throws IOException { classLoader instanceof AntClassLoader); } - @Test - public void testCheckerException() throws IOException { - final CheckstyleAntTask antTask = new CheckstyleAntTaskStub(); - antTask.setConfig(getPath(CONFIG_FILE)); - antTask.setProject(new Project()); - antTask.setFile(new File("")); - try { - antTask.execute(); - fail("Exception is expected"); - } - catch (BuildException ex) { - assertTrue("Error message is unexpected", - ex.getMessage().startsWith("Unable to process files:")); - } - } - - @Test - public final void testExecuteLogOutput() throws Exception { - final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub(); - final URL url = new File(getPath(CONFIG_FILE)).toURI().toURL(); - antTask.setProject(new Project()); - antTask.setConfig(url.toString()); - antTask.setFile(new File(getPath(FLAWLESS_INPUT))); - - mockStatic(System.class); - when(System.currentTimeMillis()).thenReturn(1L); - - antTask.execute(); - - final LocalizedMessage auditStartedMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, "DefaultLogger.auditStarted", - null, null, - getClass(), null); - final LocalizedMessage auditFinishedMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, "DefaultLogger.auditFinished", - null, null, - getClass(), null); - - final List expectedList = Arrays.asList( - new MessageLevelPair("checkstyle version ", Project.MSG_VERBOSE), - new MessageLevelPair("Adding standalone file for audit", Project.MSG_VERBOSE), - new MessageLevelPair("To locate the files took 0 ms.", Project.MSG_VERBOSE), - new MessageLevelPair("Running Checkstyle ", Project.MSG_INFO), - new MessageLevelPair("Using configuration ", Project.MSG_VERBOSE), - new MessageLevelPair(auditStartedMessage.getMessage(), Project.MSG_DEBUG), - new MessageLevelPair(auditFinishedMessage.getMessage(), Project.MSG_DEBUG), - new MessageLevelPair("To process the files took 0 ms.", Project.MSG_VERBOSE), - new MessageLevelPair("Total execution took 0 ms.", Project.MSG_VERBOSE) - ); - - final List loggedMessages = antTask.getLoggedMessages(); - - assertEquals("Amount of log messages is unexpected", - expectedList.size(), loggedMessages.size()); - for (int i = 0; i < expectedList.size(); i++) { - final MessageLevelPair expected = expectedList.get(i); - final MessageLevelPair actual = loggedMessages.get(i); - assertTrue("Log messages were expected", - actual.getMsg().startsWith(expected.getMsg())); - assertEquals("Log messages were expected", - expected.getLevel(), actual.getLevel()); - } - } - - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ - private static class CheckstyleAntTaskStub extends CheckstyleAntTask { - - @Override - protected List scanFileSets() { - final File mock = PowerMockito.mock(File.class); - // Assume that I/O error is happened when we try to invoke 'lastModified()' method. - final Exception expectedError = new RuntimeException(""); - when(mock.lastModified()).thenThrow(expectedError); - final List list = new ArrayList<>(); - list.add(mock); - return list; - } - - } - - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class CheckstyleAntTaskLogStub extends CheckstyleAntTask { - private final List loggedMessages = new ArrayList<>(); + private final List loggedMessages = new ArrayList<>(); @Override public void log(String msg, int msgLevel) { - loggedMessages.add(new MessageLevelPair(msg, msgLevel)); + loggedMessages.add(msg); } @Override public void log(String msg, Throwable t, int msgLevel) { - loggedMessages.add(new MessageLevelPair(msg, msgLevel)); + loggedMessages.add(msg); } - public List getLoggedMessages() { + public List getLoggedMessages() { return Collections.unmodifiableList(loggedMessages); } } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ - private static final class MessageLevelPair { - - private final String msg; - private final int level; - - MessageLevelPair(String msg, int level) { - this.msg = msg; - this.level = level; - } - - public String getMsg() { - return msg; - } - - public int getLevel() { - return level; - } - - } - } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/api/AbstractCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/api/AbstractCheckTest.java index fa9216c122c..11ecee66634 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/api/AbstractCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/api/AbstractCheckTest.java @@ -19,9 +19,8 @@ package com.puppycrawl.tools.checkstyle.api; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import java.io.File; import java.nio.charset.Charset; @@ -29,7 +28,6 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Assert; import org.junit.Test; import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport; @@ -61,7 +59,7 @@ public int[] getRequiredTokens() { } }; // Eventually it will become clear abstract method - Assert.assertArrayEquals("Invalid number of tokens, should be empty", + assertArrayEquals("Invalid number of tokens, should be empty", CommonUtil.EMPTY_INT_ARRAY, check.getRequiredTokens()); } @@ -84,33 +82,17 @@ public int[] getRequiredTokens() { } }; // Eventually it will become clear abstract method - Assert.assertArrayEquals("Invalid number of tokens, should be empty", + assertArrayEquals("Invalid number of tokens, should be empty", CommonUtil.EMPTY_INT_ARRAY, check.getAcceptableTokens()); } @Test public void testVisitToken() { - final AbstractCheck check = new AbstractCheck() { - @Override - public int[] getDefaultTokens() { - return CommonUtil.EMPTY_INT_ARRAY; - } - - @Override - public int[] getAcceptableTokens() { - return CommonUtil.EMPTY_INT_ARRAY; - } - - @Override - public int[] getRequiredTokens() { - return CommonUtil.EMPTY_INT_ARRAY; - } - }; - final AbstractCheck checkSpy = spy(check); + final VisitCounterCheck check = new VisitCounterCheck(); // Eventually it will become clear abstract method - checkSpy.visitToken(null); + check.visitToken(null); - verify(checkSpy, times(1)).visitToken(null); + assertEquals("expected call count", 1, check.count); } @Test @@ -135,7 +117,7 @@ public int[] getRequiredTokens() { new File(getPath("InputAbstractCheckTestFileContents.java")), Charset.defaultCharset().name()))); - Assert.assertEquals("Invalid line content", " * I'm a javadoc", check.getLine(3)); + assertEquals("Invalid line content", " * I'm a javadoc", check.getLine(3)); } @Test @@ -159,7 +141,7 @@ public int[] getRequiredTokens() { final int tabWidth = 4; check.setTabWidth(tabWidth); - Assert.assertEquals("Invalid tab width", tabWidth, check.getTabWidth()); + assertEquals("Invalid tab width", tabWidth, check.getTabWidth()); } @Test @@ -183,7 +165,7 @@ public int[] getRequiredTokens() { final ClassLoader classLoader = ClassLoader.getSystemClassLoader(); check.setClassLoader(classLoader); - Assert.assertEquals("Invalid classloader", classLoader, check.getClassLoader()); + assertEquals("Invalid classloader", classLoader, check.getClassLoader()); } @Test @@ -208,11 +190,11 @@ public int[] getRequiredTokens() { } }; - Assert.assertArrayEquals("Invalid default tokens", + assertArrayEquals("Invalid default tokens", defaultTokens, check.getDefaultTokens()); - Assert.assertArrayEquals("Invalid acceptable tokens", + assertArrayEquals("Invalid acceptable tokens", defaultTokens, check.getAcceptableTokens()); - Assert.assertArrayEquals("Invalid required tokens", + assertArrayEquals("Invalid required tokens", requiredTokens, check.getRequiredTokens()); } @@ -221,9 +203,9 @@ public void testClearMessages() { final AbstractCheck check = new DummyAbstractCheck(); check.log(1, "key", "args"); - Assert.assertEquals("Invalid message size", 1, check.getMessages().size()); + assertEquals("Invalid message size", 1, check.getMessages().size()); check.clearMessages(); - Assert.assertEquals("Invalid message size", 0, check.getMessages().size()); + assertEquals("Invalid message size", 0, check.getMessages().size()); } private static final class DummyAbstractCheck extends AbstractCheck { @@ -254,4 +236,30 @@ protected Map getCustomMessages() { } + private static final class VisitCounterCheck extends AbstractCheck { + + private int count; + + @Override + public int[] getDefaultTokens() { + return CommonUtil.EMPTY_INT_ARRAY; + } + + @Override + public int[] getAcceptableTokens() { + return CommonUtil.EMPTY_INT_ARRAY; + } + + @Override + public int[] getRequiredTokens() { + return CommonUtil.EMPTY_INT_ARRAY; + } + + @Override + public void visitToken(DetailAST ast) { + super.visitToken(ast); + count++; + } + } + } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/api/LocalizedMessageTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/api/LocalizedMessageTest.java index 632e8241fe8..dd116ab92f6 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/api/LocalizedMessageTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/api/LocalizedMessageTest.java @@ -21,14 +21,10 @@ import static com.puppycrawl.tools.checkstyle.utils.CommonUtil.EMPTY_OBJECT_ARRAY; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; import java.io.IOException; import java.io.InputStream; @@ -38,6 +34,7 @@ import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.After; import org.junit.Test; @@ -46,6 +43,12 @@ import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.EqualsVerifierReport; +/** + * Custom class loader is needed to pass URLs to pretend these are loaded from the classpath + * though we can't add/change the files for testing. The class loader is nested in this class, + * so the custom class loader we are using is safe. + * @noinspection ClassLoaderInstantiation + */ public class LocalizedMessageTest { private static final Locale DEFAULT_LOCALE = Locale.getDefault(); @@ -82,58 +85,115 @@ public void testBundleReloadUrlNull() throws IOException { assertNull("Bundle should be null when reload is true and URL is null", bundle); } + /** + * Ignore resource errors for testing. + * @noinspection resource, IOResourceOpenedButNotSafelyClosed + */ @Test public void testBundleReloadUrlNotNull() throws IOException { - final ClassLoader classloader = mock(ClassLoader.class); - final String resource = - "com/puppycrawl/tools/checkstyle/checks/coding/messages_en.properties"; - final URLConnection mockUrlCon = mock(URLConnection.class); - final URLStreamHandler stubUrlHandler = new URLStreamHandler() { + final AtomicBoolean closed = new AtomicBoolean(); + + final InputStream inputStream = new InputStream() { @Override - protected URLConnection openConnection(URL u) { - return mockUrlCon; + public int read() { + return -1; + } + + @Override + public void close() { + closed.set(true); } }; - final URL url = new URL("foo", "bar", 99, "/foobar", stubUrlHandler); - final InputStream inputStreamMock = mock(InputStream.class); - when(classloader.getResource(resource)).thenReturn(url); - when(mockUrlCon.getInputStream()).thenReturn(inputStreamMock); - when(inputStreamMock.read(any(), anyInt(), anyInt())).thenReturn(-1); + final URLConnection urlConnection = new URLConnection(null) { + @Override + public void connect() { + // no code + } + + @Override + public InputStream getInputStream() { + return inputStream; + } + }; + final URL url = new URL("test", null, 0, "", new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) { + return urlConnection; + } + }); final LocalizedMessage.Utf8Control control = new LocalizedMessage.Utf8Control(); - control.newBundle("com.puppycrawl.tools.checkstyle.checks.coding.messages", - Locale.ENGLISH, "java.class", - classloader, true); + final ResourceBundle bundle = control.newBundle( + "com.puppycrawl.tools.checkstyle.checks.coding.messages", Locale.ENGLISH, + "java.class", new TestUrlsClassLoader(url), true); - verify(mockUrlCon, times(1)).setUseCaches(false); - verify(inputStreamMock, times(1)).close(); + assertNotNull("Bundle should not be null when stream is not null", bundle); + assertFalse("connection should not be using caches", urlConnection.getUseCaches()); + assertTrue("connection should be closed", closed.get()); } + /** + * Ignore resource errors for testing. + * @noinspection resource, IOResourceOpenedButNotSafelyClosed + */ @Test - public void testBundleReloadUrlNotNullStreamNull() throws IOException { - final ClassLoader classloader = mock(ClassLoader.class); - final String resource = - "com/puppycrawl/tools/checkstyle/checks/coding/messages_en.properties"; + public void testBundleReloadUrlNotNullFalseReload() throws IOException { + final AtomicBoolean closed = new AtomicBoolean(); - final URL url = getMockUrl(null); - when(classloader.getResource(resource)).thenReturn(url); + final InputStream inputStream = new InputStream() { + @Override + public int read() { + return -1; + } + + @Override + public void close() { + closed.set(true); + } + }; + final URLConnection urlConnection = new URLConnection(null) { + @Override + public void connect() { + // no code + } + + @Override + public InputStream getInputStream() { + return inputStream; + } + }; + final URL url = new URL("test", null, 0, "", new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) { + return urlConnection; + } + }); final LocalizedMessage.Utf8Control control = new LocalizedMessage.Utf8Control(); final ResourceBundle bundle = control.newBundle( - "com.puppycrawl.tools.checkstyle.checks.coding.messages", - Locale.ENGLISH, "java.class", - classloader, true); - assertNull("Bundle should be null when stream is null", bundle); + "com.puppycrawl.tools.checkstyle.checks.coding.messages", Locale.ENGLISH, + "java.class", new TestUrlsClassLoader(url), false); + + assertNotNull("Bundle should not be null when stream is not null", bundle); + assertTrue("connection should not be using caches", urlConnection.getUseCaches()); + assertTrue("connection should be closed", closed.get()); } - private static URL getMockUrl(final URLConnection connection) throws IOException { - final URLStreamHandler handler = new URLStreamHandler() { + @Test + public void testBundleReloadUrlNotNullStreamNull() throws IOException { + final URL url = new URL("test", null, 0, "", new URLStreamHandler() { @Override - protected URLConnection openConnection(final URL url) { - return connection; + protected URLConnection openConnection(URL u) { + return null; } - }; - return new URL("http://foo.bar", "foo.bar", 80, "", handler); + }); + + final LocalizedMessage.Utf8Control control = new LocalizedMessage.Utf8Control(); + final ResourceBundle bundle = control.newBundle( + "com.puppycrawl.tools.checkstyle.checks.coding.messages", + Locale.ENGLISH, "java.class", + new TestUrlsClassLoader(url), true); + assertNull("Bundle should be null when stream is null", bundle); } @Test @@ -255,4 +315,23 @@ public void tearDown() { LocalizedMessage.setLocale(DEFAULT_LOCALE); } + /** + * Custom class loader is needed to pass URLs to pretend these are loaded from the classpath + * though we can't add/change the files for testing. + * @noinspection CustomClassloader + */ + private static class TestUrlsClassLoader extends ClassLoader { + + private final URL url; + + TestUrlsClassLoader(URL url) { + this.url = url; + } + + @Override + public URL getResource(String name) { + return url; + } + } + } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/NewlineAtEndOfFileCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/NewlineAtEndOfFileCheckTest.java index 061c3393d9e..c5212ddd5e4 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/NewlineAtEndOfFileCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/NewlineAtEndOfFileCheckTest.java @@ -25,20 +25,17 @@ 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.when; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.junit.Test; +import org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; import com.puppycrawl.tools.checkstyle.DefaultConfiguration; @@ -203,29 +200,26 @@ public void testWrongFile() throws Exception { @Test public void testWrongSeparatorLength() throws Exception { - final NewlineAtEndOfFileCheck check = new NewlineAtEndOfFileCheck(); - final DefaultConfiguration checkConfig = createModuleConfig(NewlineAtEndOfFileCheck.class); - check.configure(checkConfig); + final RandomAccessFile file = new RandomAccessFile( + getPath("InputNewlineAtEndOfFileLf.java"), "r") { + @Override + public int read(byte[] bytes) { + return 0; + } + }; - final Method method = NewlineAtEndOfFileCheck.class - .getDeclaredMethod("endsWithNewline", RandomAccessFile.class); - method.setAccessible(true); - final RandomAccessFile file = mock(RandomAccessFile.class); - when(file.length()).thenReturn(2_000_000L); try { - method.invoke(new NewlineAtEndOfFileCheck(), file); + Whitebox.invokeMethod(new NewlineAtEndOfFileCheck(), "endsWithNewline", file); fail("Exception is expected"); } - catch (InvocationTargetException ex) { - assertTrue("Error type is unexpected", - ex.getCause() instanceof IOException); + catch (IOException ex) { if (System.getProperty("os.name").toLowerCase(ENGLISH).startsWith("windows")) { assertEquals("Error message is unexpected", - "Unable to read 2 bytes, got 0", ex.getCause().getMessage()); + "Unable to read 2 bytes, got 0", ex.getMessage()); } else { assertEquals("Error message is unexpected", - "Unable to read 1 bytes, got 0", ex.getCause().getMessage()); + "Unable to read 1 bytes, got 0", ex.getMessage()); } } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/SuppressWarningsHolderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/SuppressWarningsHolderTest.java index 8107b5b64a0..d4de553c0f1 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/SuppressWarningsHolderTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/SuppressWarningsHolderTest.java @@ -24,22 +24,18 @@ 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.mock; import java.io.File; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; +import org.junit.After; 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 org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; import com.puppycrawl.tools.checkstyle.Checker; @@ -58,8 +54,6 @@ import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; -@RunWith(PowerMockRunner.class) -@PrepareForTest(SuppressWarningsHolder.class) public class SuppressWarningsHolderTest extends AbstractModuleTestSupport { @Override @@ -67,6 +61,17 @@ protected String getPackageLocation() { return "com/puppycrawl/tools/checkstyle/checks/suppresswarningsholder"; } + @After + public void cleanUp() { + // clear cache that may have been set by tests + + new SuppressWarningsHolder().beginTree(null); + + final Map map = Whitebox.getInternalState(SuppressWarningsHolder.class, + "CHECK_ALIAS_MAP"); + map.clear(); + } + @Test public void testGet() { final SuppressWarningsHolder checkObj = new SuppressWarningsHolder(); @@ -168,7 +173,7 @@ public void testSetAliasListWrong() { @Test public void testIsSuppressed() throws Exception { - createHolder("MockEntry", 100, 100, 350, 350); + populateHolder("MockEntry", 100, 100, 350, 350); final AuditEvent event = createAuditEvent("check", 100, 10); assertFalse("Event is not suppressed", SuppressWarningsHolder.isSuppressed(event)); @@ -176,7 +181,8 @@ public void testIsSuppressed() throws Exception { @Test public void testIsSuppressedByName() throws Exception { - final SuppressWarningsHolder holder = createHolder("check", 100, 100, 350, 350); + populateHolder("check", 100, 100, 350, 350); + final SuppressWarningsHolder holder = new SuppressWarningsHolder(); final AuditEvent event = createAuditEvent("id", 110, 10); holder.setAliasList(MemberNameCheck.class.getName() + "=check"); @@ -185,7 +191,7 @@ public void testIsSuppressedByName() throws Exception { @Test public void testIsSuppressedByModuleId() throws Exception { - createHolder("check", 100, 100, 350, 350); + populateHolder("check", 100, 100, 350, 350); final AuditEvent event = createAuditEvent("check", 350, 350); assertTrue("Event is not suppressed", SuppressWarningsHolder.isSuppressed(event)); @@ -193,7 +199,7 @@ public void testIsSuppressedByModuleId() throws Exception { @Test public void testIsSuppressedAfterEventEnd() throws Exception { - createHolder("check", 100, 100, 350, 350); + populateHolder("check", 100, 100, 350, 350); final AuditEvent event = createAuditEvent("check", 350, 352); assertFalse("Event is not suppressed", SuppressWarningsHolder.isSuppressed(event)); @@ -201,7 +207,7 @@ public void testIsSuppressedAfterEventEnd() throws Exception { @Test public void testIsSuppressedAfterEventEnd2() throws Exception { - createHolder("check", 100, 100, 350, 350); + populateHolder("check", 100, 100, 350, 350); final AuditEvent event = createAuditEvent("check", 400, 10); assertFalse("Event is not suppressed", SuppressWarningsHolder.isSuppressed(event)); @@ -209,7 +215,7 @@ public void testIsSuppressedAfterEventEnd2() throws Exception { @Test public void testIsSuppressedAfterEventStart() throws Exception { - createHolder("check", 100, 100, 350, 350); + populateHolder("check", 100, 100, 350, 350); final AuditEvent event = createAuditEvent("check", 100, 100); assertTrue("Event is not suppressed", SuppressWarningsHolder.isSuppressed(event)); @@ -217,7 +223,7 @@ public void testIsSuppressedAfterEventStart() throws Exception { @Test public void testIsSuppressedWithAllArgument() throws Exception { - createHolder("all", 100, 100, 350, 350); + populateHolder("all", 100, 100, 350, 350); final Checker source = new Checker(); final LocalizedMessage firstMessageForTest = @@ -393,9 +399,9 @@ public void testClearState() throws Exception { entries -> ((ThreadLocal>) entries).get().isEmpty())); } - private static SuppressWarningsHolder createHolder(String checkName, int firstLine, - int firstColumn, int lastLine, - int lastColumn) throws Exception { + private static void populateHolder(String checkName, int firstLine, + int firstColumn, int lastLine, + int lastColumn) throws Exception { final Class entry = Class .forName("com.puppycrawl.tools.checkstyle.checks.SuppressWarningsHolder$Entry"); final Constructor entryConstr = entry.getDeclaredConstructor(String.class, int.class, @@ -405,17 +411,9 @@ private static SuppressWarningsHolder createHolder(String checkName, int firstLi final Object entryInstance = entryConstr.newInstance(checkName, firstLine, firstColumn, lastLine, lastColumn); - final List entriesList = new ArrayList<>(); - entriesList.add(entryInstance); - - final ThreadLocal threadLocal = mock(ThreadLocal.class); - PowerMockito.doReturn(entriesList).when(threadLocal, "get"); - - final SuppressWarningsHolder holder = new SuppressWarningsHolder(); - final Field entries = holder.getClass().getDeclaredField("ENTRIES"); - entries.setAccessible(true); - entries.set(holder, threadLocal); - return holder; + final ThreadLocal> entries = Whitebox + .getInternalState(SuppressWarningsHolder.class, "ENTRIES"); + entries.get().add(entryInstance); } private static AuditEvent createAuditEvent(String moduleId, int line, int column) { diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/TranslationCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/TranslationCheckTest.java index fa24d1bc3c7..eddebdeae78 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/TranslationCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/TranslationCheckTest.java @@ -23,35 +23,22 @@ import static com.puppycrawl.tools.checkstyle.checks.TranslationCheck.MSG_KEY_MISSING_TRANSLATION_FILE; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.endsWith; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; import java.io.Writer; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Collection; import java.util.Collections; -import java.util.Set; -import java.util.SortedSet; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mockito; -import org.powermock.modules.junit4.PowerMockRunner; import com.google.common.collect.ImmutableMap; import com.puppycrawl.tools.checkstyle.AbstractXmlTestSupport; @@ -63,19 +50,14 @@ import com.puppycrawl.tools.checkstyle.api.Configuration; import com.puppycrawl.tools.checkstyle.api.FileText; import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; -import com.puppycrawl.tools.checkstyle.api.MessageDispatcher; import com.puppycrawl.tools.checkstyle.internal.utils.XmlUtil; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; -@RunWith(PowerMockRunner.class) public class TranslationCheckTest extends AbstractXmlTestSupport { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); - @Captor - private ArgumentCaptor> captor; - @Override protected String getPackageLocation() { return "com/puppycrawl/tools/checkstyle/checks/translation"; @@ -236,55 +218,6 @@ public void testOnePropertyFileSet() throws Exception { expected); } - @Test - @SuppressWarnings("unchecked") - public void testLogIoExceptionFileNotFound() throws Exception { - //I can't put wrong file here. Checkstyle fails before check started. - //I saw some usage of file or handling of wrong file in Checker, or somewhere - //in checks running part. So I had to do it with reflection to improve coverage. - final TranslationCheck check = new TranslationCheck(); - final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class); - final MessageDispatcher dispatcher = mock(MessageDispatcher.class); - check.configure(checkConfig); - check.setMessageDispatcher(dispatcher); - - final Method loadKeys = - check.getClass().getDeclaredMethod("getTranslationKeys", File.class); - loadKeys.setAccessible(true); - final Set keys = (Set) loadKeys.invoke(check, new File(".no.such.file")); - assertTrue("Translation keys should be empty when File is not found", keys.isEmpty()); - - Mockito.verify(dispatcher, times(1)).fireErrors(any(String.class), captor.capture()); - final String actual = captor.getValue().first().getMessage(); - final LocalizedMessage localizedMessage = new LocalizedMessage(1, - Definitions.CHECKSTYLE_BUNDLE, "general.fileNotFound", - null, null, getClass(), null); - assertEquals("Invalid message", localizedMessage.getMessage(), actual); - } - - @Test - public void testLogIoException() throws Exception { - //I can't put wrong file here. Checkstyle fails before check started. - //I saw some usage of file or handling of wrong file in Checker, or somewhere - //in checks running part. So I had to do it with reflection to improve coverage. - final TranslationCheck check = new TranslationCheck(); - final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class); - final MessageDispatcher dispatcher = mock(MessageDispatcher.class); - check.configure(checkConfig); - check.setMessageDispatcher(dispatcher); - - final Method logException = check.getClass().getDeclaredMethod("logException", - Exception.class, - File.class); - logException.setAccessible(true); - final File file = new File(""); - logException.invoke(check, new IOException("test exception"), file); - - Mockito.verify(dispatcher, times(1)).fireErrors(any(String.class), captor.capture()); - final String actual = captor.getValue().first().getMessage(); - assertThat("Invalid message: " + actual, actual, endsWith("test exception")); - } - @Test public void testLogIllegalArgumentException() throws Exception { final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class); 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 ebd6d5cce4b..f48beeb41d9 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 @@ -24,22 +24,14 @@ 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.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.URI; 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.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; @@ -47,8 +39,6 @@ import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ HeaderCheck.class, HeaderCheckTest.class, AbstractHeaderCheck.class }) public class HeaderCheckTest extends AbstractModuleTestSupport { @Rule @@ -203,40 +193,18 @@ public void testSetHeaderTwice() { } } - @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()); - } - } - @Test public void testIoExceptionWhenLoadingHeaderFile() throws Exception { - final HeaderCheck check = PowerMockito.spy(new HeaderCheck()); - PowerMockito.doThrow(new IOException("expected exception")).when(check, "loadHeader", - any()); - - check.setHeaderFile(CommonUtil.getUriByFilename(getPath("InputHeaderRegexp.java"))); + final HeaderCheck check = new HeaderCheck(); + check.setHeaderFile(new URI("test://bad")); - final Method loadHeaderFile = AbstractHeaderCheck.class.getDeclaredMethod("loadHeaderFile"); - loadHeaderFile.setAccessible(true); try { - loadHeaderFile.invoke(check); + Whitebox.invokeMethod(check, "loadHeaderFile"); fail("Exception expected"); } - catch (InvocationTargetException ex) { - assertTrue("Invalid exception cause", ex.getCause() instanceof CheckstyleException); + catch (CheckstyleException ex) { assertTrue("Invalid exception cause message", - ex.getCause().getMessage().startsWith("unable to load header file ")); + ex.getMessage().startsWith("unable to load header file ")); } } 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 5f21823447f..bd3ecb1ae93 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 @@ -26,31 +26,19 @@ import static org.junit.Assert.fail; 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.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.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; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ImportControlLoader.class, URI.class}) public class ImportControlLoaderTest { private static String getPath(String filename) { @@ -136,51 +124,4 @@ public void testLoadThrowsException() throws Exception { } } - @Test - public void testInputStreamThatFailsOnClose() throws Exception { - final InputStream inputStream = PowerMockito.mock(InputStream.class); - Mockito.doThrow(IOException.class).when(inputStream).close(); - 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) { - final Throwable[] suppressed = ex.getSuppressed(); - assertEquals("Expected one suppressed exception", 1, suppressed.length); - assertSame("Invalid exception class", IOException.class, suppressed[0].getClass()); - } - Mockito.verify(inputStream).close(); - } - - @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/checks/javadoc/ClassResolverTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/ClassResolverTest.java index 2ba571dc2d5..a5239c1a535 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/ClassResolverTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/ClassResolverTest.java @@ -20,23 +20,14 @@ package com.puppycrawl.tools.checkstyle.checks.javadoc; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; 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 java.util.HashSet; 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.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ClassResolver.class, ClassResolverTest.class }) public class ClassResolverTest { @Test @@ -120,52 +111,4 @@ public void testResolveInnerClassWithEmptyPackage() { } } - @Test - public void testResolveQualifiedNameFails() throws Exception { - final Set imports = new HashSet<>(); - imports.add("java.applet.someClass"); - - final ClassResolver classResolver = PowerMockito.spy(new ClassResolver(Thread - .currentThread().getContextClassLoader(), "", imports)); - - PowerMockito.doThrow(new ClassNotFoundException("expected exception")) - .when(classResolver, "safeLoad", any()); - PowerMockito.doReturn(true).when(classResolver, "isLoadable", any()); - - try { - classResolver.resolve("someClass", ""); - fail("IllegalStateException is expected"); - } - catch (IllegalStateException ex) { - // exception is expected - final String expected = "expected exception"; - assertTrue("Invalid exception cause, should be: ClassNotFoundException", - ex.getCause() instanceof ClassNotFoundException); - assertTrue("Invalid exception message, should end with: " + expected, - ex.getMessage().endsWith(expected)); - } - } - - /** - * This test exists to prevent any possible regression and let of - * https://github.com/checkstyle/checkstyle/issues/1192 to be persistent - * event is not very obvious. - * - * @throws Exception when smth is not expected - */ - @Test - public void testIsLoadableWithNoClassDefFoundError() throws Exception { - final Set imports = new HashSet<>(); - imports.add("java.applet.someClass"); - - final ClassResolver classResolver = PowerMockito.spy(new ClassResolver(Thread - .currentThread().getContextClassLoader(), "", imports)); - - PowerMockito.doThrow(new NoClassDefFoundError("expected exception")) - .when(classResolver, "safeLoad", any()); - - final boolean result = classResolver.isLoadable("someClass"); - assertFalse("result should be false", result); - } - } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocPackageCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocPackageCheckTest.java index 88fc6e1c7db..b4d93fed4ac 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocPackageCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocPackageCheckTest.java @@ -23,8 +23,6 @@ import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocPackageCheck.MSG_PACKAGE_INFO; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; import java.io.File; import java.util.Collections; @@ -132,27 +130,6 @@ public void testAnnotation() throws Exception { + File.separator + "package-info.java"), expected); } - /** - * Test require readable file with no parent to be used. - * Usage of Mockito.spy() is the only way to satisfy these requirements - * without the need to create new file in current working directory. - * - * @throws Exception if error occurs - */ - @Test - public void testWithFileWithoutParent() throws Exception { - final DefaultConfiguration moduleConfig = createModuleConfig(JavadocPackageCheck.class); - final File fileWithoutParent = spy(new File(getPath("noparentfile" - + File.separator + "package-info.java"))); - when(fileWithoutParent.getParent()).thenReturn(null); - when(fileWithoutParent.getParentFile()).thenReturn(null); - final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; - verify(createChecker(moduleConfig), - new File[] {fileWithoutParent}, - getPath("annotation" - + File.separator + "package-info.java"), expected); - } - /** * Using direct call to check here because there is no other way * to reproduce exception with invalid canonical path. diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/regexp/RegexpOnFilenameCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/regexp/RegexpOnFilenameCheckTest.java index 232251c2158..f18161552d4 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/regexp/RegexpOnFilenameCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/regexp/RegexpOnFilenameCheckTest.java @@ -23,8 +23,6 @@ import static com.puppycrawl.tools.checkstyle.checks.regexp.RegexpOnFilenameCheck.MSG_MISMATCH; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; import java.io.File; import java.util.regex.Pattern; @@ -255,23 +253,4 @@ public void testException() throws Exception { } } - /** - * Test require readable file with no parent to be used. - * Usage of Mockito.spy() is the only way to satisfy these requirements - * without the need to create new file in current working directory. - * - * @throws Exception if error occurs - */ - @Test - public void testWithFileWithoutParent() throws Exception { - final DefaultConfiguration moduleConfig = createModuleConfig(RegexpOnFilenameCheck.class); - final File fileWithoutParent = spy(new File(getPath("package-info.java"))); - when(fileWithoutParent.getParent()).thenReturn(null); - when(fileWithoutParent.getParentFile()).thenReturn(null); - final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; - verify(createChecker(moduleConfig), - new File[] {fileWithoutParent}, - getPath("package-info.java"), expected); - } - } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java index 29027cc1abe..e39c98f8fe7 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionsLoaderTest.java @@ -24,18 +24,12 @@ import static org.junit.Assert.fail; import java.io.IOException; -import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; import java.util.Set; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import org.xml.sax.InputSource; @@ -47,13 +41,8 @@ /** * Tests SuppressionsLoader. */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({ SuppressionsLoader.class, SuppressionsLoaderTest.class }) public class SuppressionsLoaderTest extends AbstractPathTestSupport { - @Rule - public final ExpectedException thrown = ExpectedException.none(); - @Override protected String getPackageLocation() { return "com/puppycrawl/tools/checkstyle/filters/suppressionsloader"; @@ -232,34 +221,32 @@ private static boolean isUrlReachable(String url) { @Test public void testUnableToFindSuppressions() throws Exception { - final Class loaderClass = SuppressionsLoader.class; - final Method loadSuppressions = - loaderClass.getDeclaredMethod("loadSuppressions", InputSource.class, String.class); - loadSuppressions.setAccessible(true); - final String sourceName = "InputSuppressionsLoaderNone.xml"; - final InputSource inputSource = new InputSource(sourceName); - thrown.expect(CheckstyleException.class); - thrown.expectMessage("Unable to find: " + sourceName); - - loadSuppressions.invoke(loaderClass, inputSource, sourceName); + try { + Whitebox.invokeMethod(SuppressionsLoader.class, "loadSuppressions", + new InputSource(sourceName), sourceName); + fail("CheckstyleException is expected"); + } + catch (CheckstyleException ex) { + assertEquals("Invalid exception message", "Unable to find: " + sourceName, + ex.getMessage()); + } } @Test public void testUnableToReadSuppressions() throws Exception { - final Class loaderClass = SuppressionsLoader.class; - final Method loadSuppressions = - loaderClass.getDeclaredMethod("loadSuppressions", InputSource.class, String.class); - loadSuppressions.setAccessible(true); - - final InputSource inputSource = new InputSource(); - - thrown.expect(CheckstyleException.class); final String sourceName = "InputSuppressionsLoaderNone.xml"; - thrown.expectMessage("Unable to read " + sourceName); - loadSuppressions.invoke(loaderClass, inputSource, sourceName); + try { + Whitebox.invokeMethod(SuppressionsLoader.class, "loadSuppressions", + new InputSource(), sourceName); + fail("CheckstyleException is expected"); + } + catch (CheckstyleException ex) { + assertEquals("Invalid exception message", "Unable to read " + sourceName, + ex.getMessage()); + } } @Test diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/gui/MainFrameModelTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/gui/MainFrameModelTest.java index 350d57c338e..e8511669382 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/gui/MainFrameModelTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/gui/MainFrameModelTest.java @@ -32,21 +32,14 @@ import org.junit.Before; 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 org.powermock.reflect.Whitebox; import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; import com.puppycrawl.tools.checkstyle.api.CheckstyleException; import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode; -@RunWith(PowerMockRunner.class) public class MainFrameModelTest extends AbstractModuleTestSupport { private static final String FILE_NAME_TEST_DATA = "InputMainFrameModel.java"; - private static final String FILE_NAME_NON_JAVA = "NotJavaFile.notjava"; private static final String FILE_NAME_NON_EXISTENT = "non-existent.file"; private static final String FILE_NAME_NON_COMPILABLE = "InputMainFrameModelIncorrectClass.java"; @@ -86,28 +79,6 @@ public void testParseModeEnum() { } } - @Test - public void testShouldAcceptFile() throws IOException { - final File directory = PowerMockito.mock(File.class); - PowerMockito.when(directory.isDirectory()).thenReturn(true); - assertTrue("MainFrame should accept directory", - MainFrameModel.shouldAcceptFile(directory)); - - final File javaFile = new File(getPath(FILE_NAME_TEST_DATA)); - assertTrue("MainFrame should accept java file", - MainFrameModel.shouldAcceptFile(javaFile)); - - final File nonJavaFile = PowerMockito.mock(File.class); - PowerMockito.when(nonJavaFile.isDirectory()).thenReturn(false); - PowerMockito.when(nonJavaFile.getName()).thenReturn(FILE_NAME_NON_JAVA); - assertFalse("MainFrame should not accept nonJava file", - MainFrameModel.shouldAcceptFile(nonJavaFile)); - - final File nonExistentFile = new File(getPath(FILE_NAME_NON_EXISTENT)); - assertFalse("MainFrame should not accept nonexistent file", - MainFrameModel.shouldAcceptFile(nonExistentFile)); - } - @Test public void testOpenFileWithParseModePlainJava() throws Exception { // Default parse mode: Plain Java @@ -134,31 +105,6 @@ public void testOpenFileWithParseModeJavaWithJavadocAndComments() throws Excepti verifyCorrectTestDataInFrameModel(); } - @Test - @PrepareForTest(ParseMode.class) - public void testOpenFileWithUnknownParseMode() throws CheckstyleException { - final ParseMode unknownParseMode = PowerMockito.mock(ParseMode.class); - Whitebox.setInternalState(unknownParseMode, "ordinal", 3); - - PowerMockito.when(unknownParseMode.toString()).thenReturn("Unknown parse mode"); - PowerMockito.mockStatic(ParseMode.class); - PowerMockito.when(ParseMode.values()).thenReturn( - new ParseMode[] { - ParseMode.PLAIN_JAVA, ParseMode.JAVA_WITH_COMMENTS, - ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS, unknownParseMode, }); - - try { - model.setParseMode(unknownParseMode); - model.openFile(testData); - - fail("Expected IllegalArgumentException is not thrown."); - } - catch (IllegalArgumentException ex) { - assertEquals("Invalid exception message", - "Unknown mode: Unknown parse mode", ex.getMessage()); - } - } - @Test public void testOpenFileNullParameter() throws Exception { model.openFile(testData); 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 new file mode 100644 index 00000000000..5b95f98b90e --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/AuditEventDefaultFormatterPowerTest.java @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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/CheckerPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CheckerPowerTest.java new file mode 100644 index 00000000000..598d3fc0398 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CheckerPowerTest.java @@ -0,0 +1,266 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.IOError; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.powermock.api.mockito.PowerMockito; + +import com.puppycrawl.tools.checkstyle.Checker; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; + +public class CheckerPowerTest { + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testCatchErrorInProcessFilesMethod() throws Exception { + // The idea of the test is to satisfy coverage rate. + // An Error indicates serious problems that a reasonable application should not try to + // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 + // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, + // that is why we use PowerMockito to reproduce them. + final File mock = PowerMockito.mock(File.class); + // Assume that I/O error is happened when we try to invoke 'lastModified()' method. + final String errorMessage = "Java Virtual Machine is broken" + + " or has run out of resources necessary for it to continue operating."; + final Error expectedError = new IOError(new InternalError(errorMessage)); + when(mock.lastModified()).thenThrow(expectedError); + when(mock.getAbsolutePath()).thenReturn("testFile"); + final Checker checker = new Checker(); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. + catch (Error error) { + assertThat("Error cause differs from IOError", + error.getCause(), instanceOf(IOError.class)); + assertThat("Error cause is not InternalError", + error.getCause().getCause(), instanceOf(InternalError.class)); + assertEquals("Error message is not expected", + errorMessage, error.getCause().getCause().getMessage()); + } + } + + @Test + public void testCatchErrorWithNoFileName() throws Exception { + // The idea of the test is to satisfy coverage rate. + // An Error indicates serious problems that a reasonable application should not try to + // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 + // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, + // that is why we use PowerMockito to reproduce them. + final File mock = PowerMockito.mock(File.class); + // Assume that I/O error is happened when we try to invoke 'lastModified()' method. + final String errorMessage = "Java Virtual Machine is broken" + + " or has run out of resources necessary for it to continue operating."; + final Error expectedError = new IOError(new InternalError(errorMessage)); + when(mock.lastModified()).thenThrow(expectedError); + final Checker checker = new Checker(); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. + catch (Error error) { + assertThat("Error cause differs from IOError", + error.getCause(), instanceOf(IOError.class)); + assertThat("Error cause is not InternalError", + error.getCause().getCause(), instanceOf(InternalError.class)); + assertEquals("Error message is not expected", + errorMessage, error.getCause().getCause().getMessage()); + } + } + + @Test + public void testCatchErrorWithCache() throws Exception { + final File cacheFile = temporaryFolder.newFile(); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); + checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); + checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); + + final File mock = PowerMockito.mock(File.class); + final String errorMessage = "Java Virtual Machine is broken" + + " or has run out of resources necessary for it to continue operating."; + final Error expectedError = new IOError(new InternalError(errorMessage)); + when(mock.getAbsolutePath()).thenReturn("testFile"); + when(mock.getAbsoluteFile()).thenThrow(expectedError); + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. + catch (Error error) { + assertThat("Error cause differs from IOError", + error.getCause(), instanceOf(IOError.class)); + assertEquals("Error message is not expected", + errorMessage, error.getCause().getCause().getMessage()); + + // destroy is called by Main + checker.destroy(); + + final Properties cache = new Properties(); + cache.load(Files.newBufferedReader(cacheFile.toPath())); + + assertEquals("Cache has unexpected size", + 1, cache.size()); + assertNull("testFile is not in cache", + cache.getProperty("testFile")); + } + } + + @Test + public void testCatchErrorWithCacheWithNoFileName() throws Exception { + final File cacheFile = temporaryFolder.newFile(); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); + checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); + checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); + + final File mock = PowerMockito.mock(File.class); + final String errorMessage = "Java Virtual Machine is broken" + + " or has run out of resources necessary for it to continue operating."; + final Error expectedError = new IOError(new InternalError(errorMessage)); + when(mock.getAbsolutePath()).thenThrow(expectedError); + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + // -@cs[IllegalCatchExtended] Testing for catch Error is part of 100% coverage. + catch (Error error) { + assertThat("Error cause differs from IOError", + error.getCause(), instanceOf(IOError.class)); + assertEquals("Error message is not expected", + errorMessage, error.getCause().getCause().getMessage()); + + // destroy is called by Main + checker.destroy(); + + final Properties cache = new Properties(); + cache.load(Files.newBufferedReader(cacheFile.toPath())); + + assertEquals("Cache has unexpected size", + 1, cache.size()); + } + } + + @Test + public void testExceptionWithNoFileName() { + // The idea of the test is to satisfy coverage rate. + // An Error indicates serious problems that a reasonable application should not try to + // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 + // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, + // that is why we use PowerMockito to reproduce them. + final File mock = PowerMockito.mock(File.class); + final String errorMessage = "Security Exception"; + final Exception expectedError = new SecurityException(errorMessage); + when(mock.getAbsolutePath()).thenThrow(expectedError); + final Checker checker = new Checker(); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + catch (CheckstyleException ex) { + assertThat("Error cause differs from SecurityException", + ex.getCause(), instanceOf(SecurityException.class)); + assertEquals("Error message is not expected", + errorMessage, ex.getCause().getMessage()); + } + } + + @Test + public void testExceptionWithCacheAndNoFileName() throws Exception { + final File cacheFile = temporaryFolder.newFile(); + + final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration"); + checkerConfig.addAttribute("charset", StandardCharsets.UTF_8.name()); + checkerConfig.addAttribute("cacheFile", cacheFile.getPath()); + + // The idea of the test is to satisfy coverage rate. + // An Error indicates serious problems that a reasonable application should not try to + // catch, but due to issue https://github.com/checkstyle/checkstyle/issues/2285 + // we catch errors in 'processFiles' method. Most such errors are abnormal conditions, + // that is why we use PowerMockito to reproduce them. + final File mock = PowerMockito.mock(File.class); + final String errorMessage = "Security Exception"; + final Exception expectedError = new SecurityException(errorMessage); + when(mock.getAbsolutePath()).thenThrow(expectedError); + final Checker checker = new Checker(); + checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader()); + checker.configure(checkerConfig); + final List filesToProcess = new ArrayList<>(); + filesToProcess.add(mock); + try { + checker.process(filesToProcess); + fail("IOError is expected!"); + } + catch (CheckstyleException ex) { + assertThat("Error cause differs from SecurityException", + ex.getCause(), instanceOf(SecurityException.class)); + assertEquals("Error message is not expected", + errorMessage, ex.getCause().getMessage()); + + // destroy is called by Main + checker.destroy(); + + final Properties cache = new Properties(); + cache.load(Files.newBufferedReader(cacheFile.toPath())); + + assertEquals("Cache has unexpected size", + 1, cache.size()); + } + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CheckstyleAntTaskPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CheckstyleAntTaskPowerTest.java new file mode 100644 index 00000000000..abe1400ed2c --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CheckstyleAntTaskPowerTest.java @@ -0,0 +1,197 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +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.Definitions; +import com.puppycrawl.tools.checkstyle.ant.CheckstyleAntTask; +import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(CheckstyleAntTask.class) +public class CheckstyleAntTaskPowerTest extends AbstractPathTestSupport { + + private static final String FLAWLESS_INPUT = + "InputCheckstyleAntTaskFlawless.java"; + private static final String CONFIG_FILE = + "InputCheckstyleAntTaskTestChecks.xml"; + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/ant/checkstyleanttask/"; + } + + @Test + public final void testExecuteLogOutput() throws Exception { + final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub(); + final URL url = new File(getPath(CONFIG_FILE)).toURI().toURL(); + antTask.setProject(new Project()); + antTask.setConfig(url.toString()); + antTask.setFile(new File(getPath(FLAWLESS_INPUT))); + + mockStatic(System.class); + when(System.currentTimeMillis()).thenReturn(1L); + + antTask.execute(); + + final LocalizedMessage auditStartedMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, "DefaultLogger.auditStarted", + null, null, + getClass(), null); + final LocalizedMessage auditFinishedMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, "DefaultLogger.auditFinished", + null, null, + getClass(), null); + + final List expectedList = Arrays.asList( + new MessageLevelPair("checkstyle version ", Project.MSG_VERBOSE), + new MessageLevelPair("Adding standalone file for audit", Project.MSG_VERBOSE), + new MessageLevelPair("To locate the files took 0 ms.", Project.MSG_VERBOSE), + new MessageLevelPair("Running Checkstyle ", Project.MSG_INFO), + new MessageLevelPair("Using configuration ", Project.MSG_VERBOSE), + new MessageLevelPair(auditStartedMessage.getMessage(), Project.MSG_DEBUG), + new MessageLevelPair(auditFinishedMessage.getMessage(), Project.MSG_DEBUG), + new MessageLevelPair("To process the files took 0 ms.", Project.MSG_VERBOSE), + new MessageLevelPair("Total execution took 0 ms.", Project.MSG_VERBOSE) + ); + + final List loggedMessages = antTask.getLoggedMessages(); + + assertEquals("Amount of log messages is unexpected", + expectedList.size(), loggedMessages.size()); + for (int i = 0; i < expectedList.size(); i++) { + final MessageLevelPair expected = expectedList.get(i); + final MessageLevelPair actual = loggedMessages.get(i); + assertTrue("Log messages were expected", + actual.getMsg().startsWith(expected.getMsg())); + assertEquals("Log messages were expected", + expected.getLevel(), actual.getLevel()); + } + } + + @Test + public void testCheckerException() throws IOException { + final CheckstyleAntTask antTask = new CheckstyleAntTaskStub(); + antTask.setConfig(getPath(CONFIG_FILE)); + antTask.setProject(new Project()); + antTask.setFile(new File("")); + try { + antTask.execute(); + fail("Exception is expected"); + } + catch (BuildException ex) { + assertTrue("Error message is unexpected", + ex.getMessage().startsWith("Unable to process files:")); + } + } + + /** + * Non meaningful javadoc just to contain "noinspection" tag. + * Till https://youtrack.jetbrains.com/issue/IDEA-187210 + * @noinspection JUnitTestCaseWithNoTests + */ + private static class CheckstyleAntTaskStub extends CheckstyleAntTask { + + @Override + protected List scanFileSets() { + final File mock = PowerMockito.mock(File.class); + // Assume that I/O error is happened when we try to invoke 'lastModified()' method. + final Exception expectedError = new RuntimeException(""); + when(mock.lastModified()).thenThrow(expectedError); + final List list = new ArrayList<>(); + list.add(mock); + return list; + } + + } + + /** + * Non meaningful javadoc just to contain "noinspection" tag. + * Till https://youtrack.jetbrains.com/issue/IDEA-187210 + * @noinspection JUnitTestCaseWithNoTests + */ + private static class CheckstyleAntTaskLogStub extends CheckstyleAntTask { + + private final List loggedMessages = new ArrayList<>(); + + @Override + public void log(String msg, int msgLevel) { + loggedMessages.add(new MessageLevelPair(msg, msgLevel)); + } + + @Override + public void log(String msg, Throwable t, int msgLevel) { + loggedMessages.add(new MessageLevelPair(msg, msgLevel)); + } + + public List getLoggedMessages() { + return Collections.unmodifiableList(loggedMessages); + } + + } + + /** + * Non meaningful javadoc just to contain "noinspection" tag. + * Till https://youtrack.jetbrains.com/issue/IDEA-187210 + * @noinspection JUnitTestCaseWithNoTests + */ + private static final class MessageLevelPair { + + private final String msg; + private final int level; + + MessageLevelPair(String msg, int level) { + this.msg = msg; + this.level = level; + } + + public String getMsg() { + return msg; + } + + public int getLevel() { + return level; + } + + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ClassResolverPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ClassResolverPowerTest.java new file mode 100644 index 00000000000..d29df223919 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ClassResolverPowerTest.java @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; + +import java.util.HashSet; +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.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.puppycrawl.tools.checkstyle.checks.javadoc.ClassResolver; +import com.puppycrawl.tools.checkstyle.checks.javadoc.ClassResolverTest; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ClassResolver.class, ClassResolverTest.class }) +public class ClassResolverPowerTest { + + @Test + public void testResolveQualifiedNameFails() throws Exception { + final Set imports = new HashSet<>(); + imports.add("java.applet.someClass"); + + final ClassResolver classResolver = PowerMockito.spy(new ClassResolver(Thread + .currentThread().getContextClassLoader(), "", imports)); + + PowerMockito.doThrow(new ClassNotFoundException("expected exception")) + .when(classResolver, "safeLoad", any()); + PowerMockito.doReturn(true).when(classResolver, "isLoadable", any()); + + try { + classResolver.resolve("someClass", ""); + fail("IllegalStateException is expected"); + } + catch (IllegalStateException ex) { + // exception is expected + final String expected = "expected exception"; + assertTrue("Invalid exception cause, should be: ClassNotFoundException", + ex.getCause() instanceof ClassNotFoundException); + assertTrue("Invalid exception message, should end with: " + expected, + ex.getMessage().endsWith(expected)); + } + } + + /** + * This test exists to prevent any possible regression and let of + * https://github.com/checkstyle/checkstyle/issues/1192 to be persistent + * event is not very obvious. + * + * @throws Exception when smth is not expected + */ + @Test + public void testIsLoadableWithNoClassDefFoundError() throws Exception { + final Set imports = new HashSet<>(); + imports.add("java.applet.someClass"); + + final ClassResolver classResolver = PowerMockito.spy(new ClassResolver(Thread + .currentThread().getContextClassLoader(), "", imports)); + + PowerMockito.doThrow(new NoClassDefFoundError("expected exception")) + .when(classResolver, "safeLoad", any()); + + final boolean result = classResolver.isLoadable("someClass"); + assertFalse("result should be false", result); + } + +} 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 new file mode 100644 index 00000000000..b967b67a900 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/CommonUtilPowerTest.java @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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 new file mode 100644 index 00000000000..f4f5195f8bf --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ConfigurationLoaderPowerTest.java @@ -0,0 +1,120 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.when; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +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 org.xml.sax.Attributes; + +import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport; +import com.puppycrawl.tools.checkstyle.ConfigurationLoader; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.PropertiesExpander; +import com.puppycrawl.tools.checkstyle.PropertyResolver; +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 testIncorrectTag() throws Exception { + try { + final Class aClassParent = ConfigurationLoader.class; + final Constructor ctorParent = aClassParent.getDeclaredConstructor( + PropertyResolver.class, boolean.class, ThreadModeSettings.class); + ctorParent.setAccessible(true); + final Object objParent = ctorParent.newInstance(null, true, null); + + final Class aClass = Class.forName("com.puppycrawl.tools.checkstyle." + + "ConfigurationLoader$InternalLoader"); + final Constructor constructor = aClass.getConstructor(objParent.getClass()); + constructor.setAccessible(true); + + final Object obj = constructor.newInstance(objParent); + + final Class[] param = new Class[] {String.class, String.class, + String.class, Attributes.class, }; + final Method method = aClass.getDeclaredMethod("startElement", param); + + method.setAccessible(true); + method.invoke(obj, "", "", "hello", null); + + fail("Exception is expected"); + } + catch (InvocationTargetException ex) { + assertTrue("Invalid exception cause", + ex.getCause() instanceof IllegalStateException); + assertEquals("Invalid exception cause message", + "Unknown name:" + "hello" + ".", ex.getCause().getMessage()); + } + } + + @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.getAttributeNames()).thenReturn(new String[] {"severity"}); + when(tested.getName()).thenReturn("MemberName"); + when(tested.getAttribute("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()), true); + 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/DefaultLoggerPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/DefaultLoggerPowerTest.java new file mode 100644 index 00000000000..9b25086d812 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/DefaultLoggerPowerTest.java @@ -0,0 +1,79 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.assertTrue; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +import com.puppycrawl.tools.checkstyle.DefaultLogger; +import com.puppycrawl.tools.checkstyle.Definitions; +import com.puppycrawl.tools.checkstyle.api.AuditEvent; +import com.puppycrawl.tools.checkstyle.api.AutomaticBean; +import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; +import com.puppycrawl.tools.checkstyle.utils.CommonUtil; + +public class DefaultLoggerPowerTest { + + @Test + public void testNewCtor() throws Exception { + final OutputStream infoStream = spy(new ByteArrayOutputStream()); + final ByteArrayOutputStream errorStream = spy(new ByteArrayOutputStream()); + final DefaultLogger dl = new DefaultLogger(infoStream, + AutomaticBean.OutputStreamOptions.CLOSE, errorStream, + AutomaticBean.OutputStreamOptions.CLOSE); + dl.auditStarted(null); + dl.addException(new AuditEvent(5000, "myfile"), new IllegalStateException("upsss")); + dl.auditFinished(new AuditEvent(6000, "myfile")); + final String output = errorStream.toString(StandardCharsets.UTF_8.name()); + final LocalizedMessage addExceptionMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.ADD_EXCEPTION_MESSAGE, + new String[] {"myfile"}, null, + getClass(), null); + final LocalizedMessage startMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.AUDIT_STARTED_MESSAGE, + CommonUtil.EMPTY_STRING_ARRAY, null, + getClass(), null); + final LocalizedMessage finishMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, DefaultLogger.AUDIT_FINISHED_MESSAGE, + CommonUtil.EMPTY_STRING_ARRAY, null, + getClass(), null); + + verify(infoStream, times(1)).close(); + verify(errorStream, times(1)).close(); + final String infoOutput = infoStream.toString(); + assertTrue("Message should contain exception info, but was " + infoOutput, + infoOutput.contains(startMessage.getMessage())); + assertTrue("Message should contain exception info, but was " + infoOutput, + infoOutput.contains(finishMessage.getMessage())); + assertTrue("Message should contain exception info, but was " + output, + output.contains(addExceptionMessage.getMessage())); + assertTrue("Message should contain exception info, but was " + output, + output.contains("java.lang.IllegalStateException: upsss")); + } + +} 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 new file mode 100644 index 00000000000..08d2496764f --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/HeaderCheckPowerTest.java @@ -0,0 +1,70 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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 new file mode 100644 index 00000000000..5b92a8324df --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/ImportControlLoaderPowerTest.java @@ -0,0 +1,94 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.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 testInputStreamThatFailsOnClose() throws Exception { + final InputStream inputStream = PowerMockito.mock(InputStream.class); + Mockito.doThrow(IOException.class).when(inputStream).close(); + 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) { + final Throwable[] suppressed = ex.getSuppressed(); + assertEquals("Expected one suppressed exception", 1, suppressed.length); + assertSame("Invalid exception class", IOException.class, suppressed[0].getClass()); + } + Mockito.verify(inputStream).close(); + } + + @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/JavadocPackageCheckPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/JavadocPackageCheckPowerTest.java new file mode 100644 index 00000000000..125dc458466 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/JavadocPackageCheckPowerTest.java @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.io.File; + +import org.junit.Test; + +import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocPackageCheck; +import com.puppycrawl.tools.checkstyle.utils.CommonUtil; + +public class JavadocPackageCheckPowerTest extends AbstractModuleTestSupport { + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/checks/javadoc/javadocpackage"; + } + + /** + * Test require readable file with no parent to be used. + * Usage of Mockito.spy() is the only way to satisfy these requirements + * without the need to create new file in current working directory. + * + * @throws Exception if error occurs + */ + @Test + public void testWithFileWithoutParent() throws Exception { + final DefaultConfiguration moduleConfig = createModuleConfig(JavadocPackageCheck.class); + final File fileWithoutParent = spy(new File(getPath("noparentfile" + + File.separator + "package-info.java"))); + when(fileWithoutParent.getParent()).thenReturn(null); + when(fileWithoutParent.getParentFile()).thenReturn(null); + final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + verify(createChecker(moduleConfig), + new File[] {fileWithoutParent}, + getPath("annotation" + + File.separator + "package-info.java"), expected); + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainFrameModelPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainFrameModelPowerTest.java new file mode 100644 index 00000000000..f4f554c6fe4 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainFrameModelPowerTest.java @@ -0,0 +1,111 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; + +import org.junit.Before; +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 org.powermock.reflect.Whitebox; + +import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; +import com.puppycrawl.tools.checkstyle.api.CheckstyleException; +import com.puppycrawl.tools.checkstyle.gui.MainFrameModel; +import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(ParseMode.class) +public class MainFrameModelPowerTest extends AbstractModuleTestSupport { + + private static final String FILE_NAME_TEST_DATA = "InputMainFrameModel.java"; + private static final String FILE_NAME_NON_JAVA = "NotJavaFile.notjava"; + private static final String FILE_NAME_NON_EXISTENT = "non-existent.file"; + + private MainFrameModel model; + private File testData; + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/gui/mainframemodel"; + } + + @Before + public void prepareTestData() throws IOException { + model = new MainFrameModel(); + testData = new File(getPath(FILE_NAME_TEST_DATA)); + } + + @Test + public void testShouldAcceptFile() throws IOException { + final File directory = PowerMockito.mock(File.class); + PowerMockito.when(directory.isDirectory()).thenReturn(true); + assertTrue("MainFrame should accept directory", + MainFrameModel.shouldAcceptFile(directory)); + + final File javaFile = new File(getPath(FILE_NAME_TEST_DATA)); + assertTrue("MainFrame should accept java file", + MainFrameModel.shouldAcceptFile(javaFile)); + + final File nonJavaFile = PowerMockito.mock(File.class); + PowerMockito.when(nonJavaFile.isDirectory()).thenReturn(false); + PowerMockito.when(nonJavaFile.getName()).thenReturn(FILE_NAME_NON_JAVA); + assertFalse("MainFrame should not accept nonJava file", + MainFrameModel.shouldAcceptFile(nonJavaFile)); + + final File nonExistentFile = new File(getPath(FILE_NAME_NON_EXISTENT)); + assertFalse("MainFrame should not accept nonexistent file", + MainFrameModel.shouldAcceptFile(nonExistentFile)); + } + + @Test + public void testOpenFileWithUnknownParseMode() throws CheckstyleException { + final ParseMode unknownParseMode = PowerMockito.mock(ParseMode.class); + Whitebox.setInternalState(unknownParseMode, "ordinal", 3); + + PowerMockito.when(unknownParseMode.toString()).thenReturn("Unknown parse mode"); + PowerMockito.mockStatic(ParseMode.class); + PowerMockito.when(ParseMode.values()).thenReturn( + new ParseMode[] { + ParseMode.PLAIN_JAVA, ParseMode.JAVA_WITH_COMMENTS, + ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS, unknownParseMode, }); + + try { + model.setParseMode(unknownParseMode); + model.openFile(testData); + + fail("Expected IllegalArgumentException is not thrown."); + } + catch (IllegalArgumentException ex) { + assertEquals("Invalid exception message", + "Unknown mode: Unknown parse mode", ex.getMessage()); + } + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainPowerTest.java new file mode 100644 index 00000000000..fb50172a40c --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/MainPowerTest.java @@ -0,0 +1,70 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.powermock.api.mockito.PowerMockito.mockStatic; + +import java.util.Locale; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.SystemErrRule; +import org.junit.contrib.java.lang.system.SystemOutRule; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.puppycrawl.tools.checkstyle.Main; +import com.puppycrawl.tools.checkstyle.utils.CommonUtil; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({Main.class, CommonUtil.class}) +public class MainPowerTest { + + private static final String SHORT_USAGE = String.format(Locale.ROOT, + "Usage: checkstyle [OPTIONS]... FILES...%n" + + "Try 'checkstyle --help' for more information.%n"); + + private static final String EOL = System.getProperty("line.separator"); + + @Rule + public final SystemErrRule systemErr = new SystemErrRule().enableLog().mute(); + @Rule + public final SystemOutRule systemOut = new SystemOutRule().enableLog().mute(); + + /** + * This test is a workaround for the Jacoco limitations. A call to {@link System#exit(int)} + * will never return, so Jacoco coverage probe will be missing. By mocking the {@code System} + * class we turn {@code System.exit()} to noop and the Jacoco coverage probe should succeed. + * + * @throws Exception if error occurs + * @see Jacoco issue 117 + */ + @Test + public void testJacocoWorkaround() throws Exception { + final String expected = "Missing required parameter: " + EOL + SHORT_USAGE; + mockStatic(System.class); + Main.main(); + assertEquals("Unexpected output log", "", systemOut.getLog()); + assertEquals("Unexpected system error log", expected, systemErr.getLog()); + } + +} 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 new file mode 100644 index 00000000000..a5291cb4939 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PackageObjectFactoryPowerTest.java @@ -0,0 +1,86 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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 org.powermock.reflect.Whitebox; + +import com.puppycrawl.tools.checkstyle.PackageObjectFactory; +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 Whitebox} 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 = Whitebox.getInternalState(objectFactory, + internalFieldName); + assertNull("Expected uninitialized field", nullMap); + + final Object instance = objectFactory.createModule(name); + assertEquals("Expected empty string", "", instance); + + final Map emptyMap = Whitebox.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 new file mode 100644 index 00000000000..45b54244dcf --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/PropertyCacheFilePowerTest.java @@ -0,0 +1,291 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.mockito.Mockito.times; +import static org.powermock.api.mockito.PowerMockito.doNothing; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.verifyStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +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.mockito.ArgumentMatchers; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.google.common.io.ByteStreams; +import com.google.common.io.Closeables; +import com.google.common.io.Flushables; +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, Closeables.class, Flushables.class}) +public class PropertyCacheFilePowerTest extends AbstractPathTestSupport { + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/propertycachefile"; + } + + @Test + public void testCloseAndFlushOutputStreamAfterCreatingHashCode() throws IOException { + mockStatic(Closeables.class); + doNothing().when(Closeables.class); + Closeables.close(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); + mockStatic(Flushables.class); + doNothing().when(Flushables.class); + Flushables.flush(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); + + final Configuration config = new DefaultConfiguration("myName"); + final PropertyCacheFile cache = new PropertyCacheFile(config, "fileDoesNotExist.txt"); + cache.load(); + + verifyStatic(Closeables.class, times(1)); + Closeables.close(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); + + verifyStatic(Flushables.class, times(1)); + Flushables.flush(any(ObjectOutputStream.class), ArgumentMatchers.eq(false)); + } + + /** + * 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 testFlushAndCloseCacheFileOutputStream() throws IOException { + mockStatic(Closeables.class); + doNothing().when(Closeables.class); + Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); + mockStatic(Flushables.class); + doNothing().when(Flushables.class); + Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); + + final Configuration config = new DefaultConfiguration("myName"); + final PropertyCacheFile cache = new PropertyCacheFile(config, + temporaryFolder.newFile().getPath()); + + cache.put("CheckedFileName.java", System.currentTimeMillis()); + cache.persist(); + + verifyStatic(Closeables.class, times(1)); + Closeables.close(any(OutputStream.class), ArgumentMatchers.eq(false)); + verifyStatic(Flushables.class, times(1)); + Flushables.flush(any(OutputStream.class), ArgumentMatchers.eq(false)); + } + + @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(); + cacheDetails.load(Files.newBufferedReader(cacheFile.toPath())); + + 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(); + cacheDetails.load(Files.newBufferedReader(cacheFile.toPath())); + + 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/RegexpOnFilenameCheckPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/RegexpOnFilenameCheckPowerTest.java new file mode 100644 index 00000000000..b8dbcfe1d02 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/RegexpOnFilenameCheckPowerTest.java @@ -0,0 +1,60 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.io.File; + +import org.junit.Test; + +import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpOnFilenameCheck; +import com.puppycrawl.tools.checkstyle.utils.CommonUtil; + +public class RegexpOnFilenameCheckPowerTest extends AbstractModuleTestSupport { + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/checks/regexp/regexponfilename"; + } + + /** + * Test require readable file with no parent to be used. + * Usage of Mockito.spy() is the only way to satisfy these requirements + * without the need to create new file in current working directory. + * + * @throws Exception if error occurs + */ + @Test + public void testWithFileWithoutParent() throws Exception { + final DefaultConfiguration moduleConfig = createModuleConfig(RegexpOnFilenameCheck.class); + final File fileWithoutParent = spy(new File(getPath("package-info.java"))); + when(fileWithoutParent.getParent()).thenReturn(null); + when(fileWithoutParent.getParentFile()).thenReturn(null); + final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + verify(createChecker(moduleConfig), + new File[] {fileWithoutParent}, + getPath("package-info.java"), expected); + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TranslationCheckPowerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TranslationCheckPowerTest.java new file mode 100644 index 00000000000..28dfee63496 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TranslationCheckPowerTest.java @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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.hamcrest.CoreMatchers.endsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Set; +import java.util.SortedSet; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.puppycrawl.tools.checkstyle.AbstractXmlTestSupport; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.Definitions; +import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; +import com.puppycrawl.tools.checkstyle.api.MessageDispatcher; +import com.puppycrawl.tools.checkstyle.checks.TranslationCheck; + +@RunWith(PowerMockRunner.class) +public class TranslationCheckPowerTest extends AbstractXmlTestSupport { + + @Captor + private ArgumentCaptor> captor; + + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/checks/translation"; + } + + @Test + @SuppressWarnings("unchecked") + public void testLogIoExceptionFileNotFound() throws Exception { + //I can't put wrong file here. Checkstyle fails before check started. + //I saw some usage of file or handling of wrong file in Checker, or somewhere + //in checks running part. So I had to do it with reflection to improve coverage. + final TranslationCheck check = new TranslationCheck(); + final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class); + final MessageDispatcher dispatcher = mock(MessageDispatcher.class); + check.configure(checkConfig); + check.setMessageDispatcher(dispatcher); + + final Method loadKeys = + check.getClass().getDeclaredMethod("getTranslationKeys", File.class); + loadKeys.setAccessible(true); + final Set keys = (Set) loadKeys.invoke(check, new File(".no.such.file")); + assertTrue("Translation keys should be empty when File is not found", keys.isEmpty()); + + Mockito.verify(dispatcher, times(1)).fireErrors(any(String.class), captor.capture()); + final String actual = captor.getValue().first().getMessage(); + final LocalizedMessage localizedMessage = new LocalizedMessage(1, + Definitions.CHECKSTYLE_BUNDLE, "general.fileNotFound", + null, null, getClass(), null); + assertEquals("Invalid message", localizedMessage.getMessage(), actual); + } + + @Test + public void testLogIoException() throws Exception { + //I can't put wrong file here. Checkstyle fails before check started. + //I saw some usage of file or handling of wrong file in Checker, or somewhere + //in checks running part. So I had to do it with reflection to improve coverage. + final TranslationCheck check = new TranslationCheck(); + final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class); + final MessageDispatcher dispatcher = mock(MessageDispatcher.class); + check.configure(checkConfig); + check.setMessageDispatcher(dispatcher); + + final Method logException = check.getClass().getDeclaredMethod("logException", + Exception.class, + File.class); + logException.setAccessible(true); + final File file = new File(""); + logException.invoke(check, new IOException("test exception"), file); + + Mockito.verify(dispatcher, times(1)).fireErrors(any(String.class), captor.capture()); + final String actual = captor.getValue().first().getMessage(); + assertThat("Invalid message: " + actual, actual, endsWith("test exception")); + } + +} 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 new file mode 100644 index 00000000000..e231b2134b5 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/internal/powermock/TreeWalkerPowerTest.java @@ -0,0 +1,101 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 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 org.powermock.reflect.Whitebox; + +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; + +@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 {}"); + Whitebox.invokeMethod(treeWalkerSpy, "processFiltered", file, new FileText(file, lines)); + verifyPrivate(treeWalkerSpy, times(1)).invoke("walk", + any(DetailAST.class), any(FileContents.class), any(classAstState)); + verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredMessages", + 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 {}"); + Whitebox.invokeMethod(treeWalkerSpy, "processFiltered", file, new FileText(file, lines)); + verifyPrivate(treeWalkerSpy, times(1)).invoke("walk", + any(DetailAST.class), any(FileContents.class), any(classAstState)); + verifyPrivate(treeWalkerSpy, times(0)).invoke("getFilteredMessages", + 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 fb2468650f2..b07c39eb96b 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/utils/CommonUtilTest.java @@ -25,30 +25,19 @@ import static org.junit.Assert.assertSame; 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.io.Closeable; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; -import java.net.URISyntaxException; -import java.net.URL; import java.util.Dictionary; import java.util.regex.Pattern; 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.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; -@RunWith(PowerMockRunner.class) public class CommonUtilTest { /** After appending to path produces equivalent, but denormalized path. */ @@ -434,27 +423,6 @@ public void testIsBlankWithWhitespacesOnly() { CommonUtil.isBlank(" ")); } - @Test - @PrepareForTest({ CommonUtil.class, CommonUtilTest.class }) - 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()); - } - } - @Test public void testIsIntValidString() { assertTrue("Should return true when string is null", CommonUtil.isInt("42")); @@ -472,11 +440,6 @@ public void testIsIntNull() { CommonUtil.isInt(null)); } - /** - * Non meaningful javadoc just to contain "noinspection" tag. - * Till https://youtrack.jetbrains.com/issue/IDEA-187210 - * @noinspection JUnitTestCaseWithNoTests - */ private static class TestCloseable implements Closeable { private boolean closed; diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderNotXml.java b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderNotXml.java new file mode 100644 index 00000000000..35f20fae4a6 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderNotXml.java @@ -0,0 +1,4 @@ +package com.puppycrawl.tools.checkstyle.packagenamesloader; + +public class InputPackageNamesLoaderNotXml { +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDots.xml b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDots.xml new file mode 100644 index 00000000000..ebfcf51f78b --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDots.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDotsEx.xml b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDotsEx.xml new file mode 100644 index 00000000000..c046d5a33c5 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/packagenamesloader/InputPackageNamesLoaderWithDotsEx.xml @@ -0,0 +1,11 @@ + + + + + + + + +