diff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java index ec0dffa988..b74aa700a5 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java @@ -20,9 +20,12 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -97,19 +100,106 @@ class PathMatchingResourcePatternResolverTests { assertExactSubPaths(pattern, pathPrefix, "support/resource#test1.txt", "support/resource#test2.txt"); } + @Disabled("Until gh-29333 is resolved") @Test - void usingFileProtocol() { - Path testResourcesDir = Path.of("src/test/resources").toAbsolutePath(); - String pattern = "file:%s/scanned-resources/**".formatted(testResourcesDir); - String pathPrefix = ".+scanned-resources/"; + void usingClasspathStarProtocolWithWildcardInPatternAndNotEndingInSlash() throws Exception { + String pattern = "classpath*:org/springframework/core/io/sup*"; + String pathPrefix = ".+org/springframework/core/io/"; + List actualSubPaths = getSubPathsIgnoringClassFilesEtc(pattern, pathPrefix); + + // We DO find "support" if the pattern does NOT end with a slash. + assertThat(actualSubPaths).containsExactly("support"); + } + + @Disabled("Until gh-29333 is resolved") + @Test + void usingFileProtocolWithWildcardInPatternAndNotEndingInSlash() throws Exception { + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); + String pattern = String.format("file:%s/org/springframework/core/io/sup*", testResourcesDir); + String pathPrefix = ".+org/springframework/core/io/"; + + List actualSubPaths = getSubPathsIgnoringClassFilesEtc(pattern, pathPrefix); + + // We DO find "support" if the pattern does NOT end with a slash. + assertThat(actualSubPaths).containsExactly("support"); + } + + @Test + void usingClasspathStarProtocolWithWildcardInPatternAndEndingInSlash() throws Exception { + String pattern = "classpath*:org/springframework/core/io/sup*/"; + String pathPrefix = ".+org/springframework/core/io/"; + + List actualSubPaths = getSubPathsIgnoringClassFilesEtc(pattern, pathPrefix); + + // We do NOT find "support" if the pattern ENDS with a slash. + assertThat(actualSubPaths).isEmpty(); + } + + @Test + void usingFileProtocolWithWildcardInPatternAndEndingInSlash() throws Exception { + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); + String pattern = String.format("file:%s/org/springframework/core/io/sup*/", testResourcesDir); + String pathPrefix = ".+org/springframework/core/io/"; + + List actualSubPaths = getSubPathsIgnoringClassFilesEtc(pattern, pathPrefix); + + // We do NOT find "support" if the pattern ENDS with a slash. + assertThat(actualSubPaths).isEmpty(); + } + + @Disabled("Until gh-29333 is resolved") + @Test + void usingClasspathStarProtocolWithWildcardInPatternAndEndingWithSlashStarStar() throws Exception { + String pattern = "classpath*:org/springframework/core/io/sup*/**"; + String pathPrefix = ".+org/springframework/core/io/"; + + List actualSubPaths = getSubPathsIgnoringClassFilesEtc(pattern, pathPrefix); + + // We DO find "support" if the pattern ENDS with "/**". + assertThat(actualSubPaths) + .containsExactlyInAnyOrder("support", "support/resource#test1.txt", "support/resource#test2.txt"); + } + + private List getSubPathsIgnoringClassFilesEtc(String pattern, String pathPrefix) throws IOException { + return Arrays.stream(resolver.getResources(pattern)) + .map(resource -> getPath(resource).replaceFirst(pathPrefix, "")) + .filter(name -> !name.endsWith(".class")) + .filter(name -> !name.endsWith(".kt")) + .filter(name -> !name.endsWith(".factories")) + .distinct() + .sorted() + .collect(Collectors.toList()); + } + + @Test + void usingFileProtocolWithoutWildcardInPatternAndEndingInSlashStarStar() throws Exception { + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); + String pattern = String.format("file:%s/scanned-resources/**", testResourcesDir); + String pathPrefix = ".+?resources/"; + + // We do NOT find "scanned-resources" if the pattern ENDS with "/**" AND does NOT otherwise contain a wildcard. assertExactFilenames(pattern, "resource#test1.txt", "resource#test2.txt"); - assertExactSubPaths(pattern, pathPrefix, "resource#test1.txt", "resource#test2.txt"); + assertExactSubPaths(pattern, pathPrefix, "scanned-resources/resource#test1.txt", + "scanned-resources/resource#test2.txt"); + } + + @Disabled("Until gh-29333 is resolved") + @Test + void usingFileProtocolWithWildcardInPatternAndEndingInSlashStarStar() throws Exception { + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); + String pattern = String.format("file:%s/scanned*resources/**", testResourcesDir); + String pathPrefix = ".+?resources/"; + + // We DO find "scanned-resources" if the pattern ENDS with "/**" AND DOES otherwise contain a wildcard. + assertExactFilenames(pattern, "scanned-resources", "resource#test1.txt", "resource#test2.txt"); + assertExactSubPaths(pattern, pathPrefix, "scanned-resources", "scanned-resources/resource#test1.txt", + "scanned-resources/resource#test2.txt"); } @Test void usingFileProtocolAndAssertingUrlAndUriSyntax() throws Exception { - Path testResourcesDir = Path.of("src/test/resources").toAbsolutePath(); + Path testResourcesDir = Paths.get("src/test/resources").toAbsolutePath(); String pattern = "file:%s/scanned-resources/**/resource#test1.txt".formatted(testResourcesDir); Resource[] resources = resolver.getResources(pattern); assertThat(resources).hasSize(1);