diff --git a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java index f496c35ec82..78c72bd0488 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java @@ -17,17 +17,18 @@ package org.springframework.core.io; import java.io.FileNotFoundException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** - * Unit tests that serve as regression tests for the bugs described in SPR-6888 - * and SPR-9413. + * Unit tests for {@link ClassPathResource}. + * + *

These also originally served as regression tests for the bugs described in + * SPR-6888 and SPR-9413. * * @author Chris Beams * @author Sam Brannen @@ -36,105 +37,110 @@ class ClassPathResourceTests { private static final String PACKAGE_PATH = "org/springframework/core/io"; private static final String NONEXISTENT_RESOURCE_NAME = "nonexistent.xml"; - private static final String FQ_RESOURCE_PATH = PACKAGE_PATH + '/' + NONEXISTENT_RESOURCE_NAME; + private static final String ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE = PACKAGE_PATH + '/' + NONEXISTENT_RESOURCE_NAME; + private static final String ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE_WITH_LEADING_SLASH = '/' + ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE; - /** - * Absolute path version of {@link #FQ_RESOURCE_PATH}. - */ - private static final String FQ_RESOURCE_PATH_WITH_LEADING_SLASH = '/' + FQ_RESOURCE_PATH; - private static final Pattern DESCRIPTION_PATTERN = Pattern.compile("^class path resource \\[(.+?)]$"); + @Nested + class GetInputStream { + @Test + void withStringConstructorRaisesExceptionForNonexistentResource() { + assertExceptionContainsAbsolutePath(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE)); + } - @Test - void stringConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH)); - } + @Test + void withClassLoaderConstructorRaisesExceptionForNonexistentResource() { + assertExceptionContainsAbsolutePath(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE, getClass().getClassLoader())); + } - @Test - void classLiteralConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass())); - } + @Test + void withClassLiteralConstructorRaisesExceptionForNonexistentRelativeResource() { + assertExceptionContainsAbsolutePath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass())); + } - @Test - void classLoaderConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader())); - } + @Test + void withClassLiteralConstructorRaisesExceptionForNonexistentAbsoluteResource() { + assertExceptionContainsAbsolutePath(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE, getClass())); + } - @Test - void getDescriptionWithStringConstructor() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH), FQ_RESOURCE_PATH); - } + private static void assertExceptionContainsAbsolutePath(ClassPathResource resource) { + assertThatExceptionOfType(FileNotFoundException.class) + .isThrownBy(resource::getInputStream) + .withMessageContaining(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE); + } - @Test - void getDescriptionWithStringConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH), - FQ_RESOURCE_PATH); } - @Test - void getDescriptionWithClassLiteralConstructor() { - assertDescriptionContainsExpectedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass()), - FQ_RESOURCE_PATH); - } + @Nested + class GetDescription { - @Test - void getDescriptionWithClassLiteralConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass()), FQ_RESOURCE_PATH); - } + @Test + void withStringConstructor() { + assertDescription(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE)); + } - @Test - void getDescriptionWithClassLoaderConstructor() { - assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader()), FQ_RESOURCE_PATH); - } + @Test + void withStringConstructorAndLeadingSlash() { + assertDescription(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE_WITH_LEADING_SLASH)); + } - @Test - void getDescriptionWithClassLoaderConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass().getClassLoader()), FQ_RESOURCE_PATH); - } + @Test + void withClassLiteralConstructor() { + assertDescription(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass())); + } + + @Test + void withClassLiteralConstructorAndLeadingSlash() { + assertDescription(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE_WITH_LEADING_SLASH, getClass())); + } + + @Test + void withClassLoaderConstructor() { + assertDescription(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE, getClass().getClassLoader())); + } + + @Test + void withClassLoaderConstructorAndLeadingSlash() { + assertDescription(new ClassPathResource(ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE_WITH_LEADING_SLASH, getClass().getClassLoader())); + } + + private static void assertDescription(ClassPathResource resource) { + assertThat(resource.getDescription()).isEqualTo("class path resource [%s]", ABSOLUTE_PATH_TO_NONEXISTENT_RESOURCE); + } - @Test - void dropLeadingSlashForClassLoaderAccess() { - assertThat(new ClassPathResource("/test.html").getPath()).isEqualTo("test.html"); - assertThat(((ClassPathResource) new ClassPathResource("").createRelative("/test.html")).getPath()).isEqualTo("test.html"); } - @Test - void convertToAbsolutePathForClassRelativeAccess() { - assertThat(new ClassPathResource("/test.html", getClass()).getPath()).isEqualTo("test.html"); - assertThat(new ClassPathResource("", getClass()).getPath()).isEqualTo(PACKAGE_PATH + "/"); - assertThat(((ClassPathResource) new ClassPathResource("", getClass()).createRelative("/test.html")).getPath()).isEqualTo("test.html"); - assertThat(((ClassPathResource) new ClassPathResource("", getClass()).createRelative("test.html")).getPath()).isEqualTo(PACKAGE_PATH + "/test.html"); + @Nested + class GetPath { + + @Test + void dropsLeadingSlashForClassLoaderAccess() { + assertThat(new ClassPathResource("/test.html").getPath()).isEqualTo("test.html"); + assertThat(((ClassPathResource) new ClassPathResource("").createRelative("/test.html")).getPath()).isEqualTo("test.html"); + } + + @Test + void convertsToAbsolutePathForClassRelativeAccess() { + assertThat(new ClassPathResource("/test.html", getClass()).getPath()).isEqualTo("test.html"); + assertThat(new ClassPathResource("", getClass()).getPath()).isEqualTo(PACKAGE_PATH + "/"); + assertThat(((ClassPathResource) new ClassPathResource("", getClass()).createRelative("/test.html")).getPath()).isEqualTo("test.html"); + assertThat(((ClassPathResource) new ClassPathResource("", getClass()).createRelative("test.html")).getPath()).isEqualTo(PACKAGE_PATH + "/test.html"); + } + } @Test - void directoryNotReadable() { + void directoryNotReadable() throws Exception { Resource fileDir = new ClassPathResource("org/springframework/core"); + assertThat(fileDir.getURL()).asString().startsWith("file:"); assertThat(fileDir.exists()).isTrue(); assertThat(fileDir.isReadable()).isFalse(); Resource jarDir = new ClassPathResource("reactor/core"); + assertThat(jarDir.getURL()).asString().startsWith("jar:"); assertThat(jarDir.exists()).isTrue(); assertThat(jarDir.isReadable()).isFalse(); } - - private void assertDescriptionContainsExpectedPath(ClassPathResource resource, String expectedPath) { - Matcher matcher = DESCRIPTION_PATTERN.matcher(resource.getDescription()); - assertThat(matcher.matches()).isTrue(); - assertThat(matcher.groupCount()).isEqualTo(1); - String match = matcher.group(1); - - assertThat(match).isEqualTo(expectedPath); - } - - private void assertExceptionContainsFullyQualifiedPath(ClassPathResource resource) { - assertThatExceptionOfType(FileNotFoundException.class).isThrownBy( - resource::getInputStream) - .withMessageContaining(FQ_RESOURCE_PATH); - } - }