18
18
19
19
import java .io .FileNotFoundException ;
20
20
import java .io .IOException ;
21
+ import java .io .UncheckedIOException ;
21
22
import java .net .URLDecoder ;
23
+ import java .nio .file .Path ;
22
24
import java .util .Arrays ;
23
25
import java .util .List ;
24
26
35
37
/**
36
38
* Tests for {@link PathMatchingResourcePatternResolver}.
37
39
*
38
- * <p>If tests fail, uncomment the diagnostics in {@link #assertFilenames}.
40
+ * <p>If tests fail, uncomment the diagnostics in {@link #assertFilenames(String, boolean, String...) }.
39
41
*
40
42
* @author Oliver Hutchison
41
43
* @author Juergen Hoeller
@@ -62,7 +64,7 @@ class PathMatchingResourcePatternResolverTests {
62
64
class InvalidPatterns {
63
65
64
66
@ Test
65
- void invalidPrefixWithPatternElementInItThrowsException () throws IOException {
67
+ void invalidPrefixWithPatternElementInItThrowsException () {
66
68
assertThatExceptionOfType (FileNotFoundException .class ).isThrownBy (() -> resolver .getResources ("xx**:**/*.xy" ));
67
69
}
68
70
@@ -73,22 +75,34 @@ void invalidPrefixWithPatternElementInItThrowsException() throws IOException {
73
75
class FileSystemResources {
74
76
75
77
@ Test
76
- void singleResourceOnFileSystem () throws IOException {
78
+ void singleResourceOnFileSystem () {
77
79
String pattern = "org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.class" ;
78
- assertFilenames (pattern , "PathMatchingResourcePatternResolverTests.class" );
80
+ assertExactFilenames (pattern , "PathMatchingResourcePatternResolverTests.class" );
79
81
}
80
82
81
83
@ Test
82
- void classpathStarWithPatternOnFileSystem () throws IOException {
84
+ void classpathStarWithPatternOnFileSystem () {
83
85
String pattern = "classpath*:org/springframework/core/io/sup*/*.class" ;
84
86
String [] expectedFilenames = StringUtils .concatenateStringArrays (CLASSES_IN_CORE_IO_SUPPORT , TEST_CLASSES_IN_CORE_IO_SUPPORT );
85
87
assertFilenames (pattern , expectedFilenames );
86
88
}
87
89
88
- @ Test
89
- void getResourcesOnFileSystemContainingHashtagsInTheirFileNames () throws IOException {
90
- String pattern = "classpath*:org/springframework/core/io/**/resource#test*.txt" ;
91
- assertFilenames (pattern , "resource#test1.txt" , "resource#test2.txt" );
90
+ @ Nested
91
+ class WithHashtagsInTheirFileNames {
92
+
93
+ @ Test
94
+ void usingClasspathStarProtocol () {
95
+ String pattern = "classpath*:org/springframework/core/io/**/resource#test*.txt" ;
96
+ assertExactFilenames (pattern , "resource#test1.txt" , "resource#test2.txt" );
97
+ }
98
+
99
+ @ Test
100
+ void usingFilePrototol () {
101
+ Path testResourcesDir = Path .of ("src/test/resources" ).toAbsolutePath ();
102
+ String pattern = "file:%s/scanned-resources/**" .formatted (testResourcesDir );
103
+ assertExactFilenames (pattern , "resource#test1.txt" , "resource#test2.txt" );
104
+ }
105
+
92
106
}
93
107
94
108
}
@@ -98,57 +112,75 @@ void getResourcesOnFileSystemContainingHashtagsInTheirFileNames() throws IOExcep
98
112
class JarResources {
99
113
100
114
@ Test
101
- void singleResourceInJar () throws IOException {
115
+ void singleResourceInJar () {
102
116
String pattern = "org/reactivestreams/Publisher.class" ;
103
- assertFilenames (pattern , "Publisher.class" );
117
+ assertExactFilenames (pattern , "Publisher.class" );
104
118
}
105
119
106
120
@ Test
107
- void singleResourceInRootOfJar () throws IOException {
121
+ void singleResourceInRootOfJar () {
108
122
String pattern = "aspectj_1_5_0.dtd" ;
109
- assertFilenames (pattern , "aspectj_1_5_0.dtd" );
123
+ assertExactFilenames (pattern , "aspectj_1_5_0.dtd" );
110
124
}
111
125
112
126
@ Test
113
- void classpathWithPatternInJar () throws IOException {
127
+ void classpathWithPatternInJar () {
114
128
String pattern = "classpath:reactor/util/annotation/*.class" ;
115
- assertFilenames (pattern , CLASSES_IN_REACTOR_UTIL_ANNOTATION );
129
+ assertExactFilenames (pattern , CLASSES_IN_REACTOR_UTIL_ANNOTATION );
116
130
}
117
131
118
132
@ Test
119
- void classpathStarWithPatternInJar () throws IOException {
133
+ void classpathStarWithPatternInJar () {
120
134
String pattern = "classpath*:reactor/util/annotation/*.class" ;
121
- assertFilenames (pattern , CLASSES_IN_REACTOR_UTIL_ANNOTATION );
135
+ assertExactFilenames (pattern , CLASSES_IN_REACTOR_UTIL_ANNOTATION );
122
136
}
123
137
124
138
// Fails in a native image -- https://github.com/oracle/graal/issues/5020
125
139
@ Test
126
140
void rootPatternRetrievalInJarFiles () throws IOException {
127
- assertThat (resolver .getResources ("classpath*:*.dtd" )).extracting (Resource ::getFilename )
141
+ assertThat (resolver .getResources ("classpath*:aspectj *.dtd" )).extracting (Resource ::getFilename )
128
142
.as ("Could not find aspectj_1_5_0.dtd in the root of the aspectjweaver jar" )
129
- .contains ("aspectj_1_5_0.dtd" );
143
+ .containsExactly ("aspectj_1_5_0.dtd" );
130
144
}
131
145
132
146
}
133
147
134
148
135
- private void assertFilenames (String pattern , String ... filenames ) throws IOException {
136
- Resource [] resources = resolver .getResources (pattern );
137
- List <String > actualNames = Arrays .stream (resources )
138
- .map (Resource ::getFilename )
139
- // Need to decode within GraalVM native image to get %23 converted to #.
140
- .map (filename -> URLDecoder .decode (filename , UTF_8 ))
141
- .sorted ()
142
- .toList ();
149
+ private void assertFilenames (String pattern , String ... filenames ) {
150
+ assertFilenames (pattern , false , filenames );
151
+ }
143
152
144
- // Uncomment the following if you encounter problems with matching against the file system.
145
- // List<String> expectedNames = Arrays.stream(filenames).sorted().toList();
146
- // System.out.println("----------------------------------------------------------------------");
147
- // System.out.println("Expected: " + expectedNames);
148
- // System.out.println("Actual: " + actualNames);
149
- // Arrays.stream(resources).forEach(System.out::println);
153
+ private void assertExactFilenames (String pattern , String ... filenames ) {
154
+ assertFilenames (pattern , true , filenames );
155
+ }
150
156
151
- assertThat (actualNames ).as ("subset of files found" ).contains (filenames );
157
+ private void assertFilenames (String pattern , boolean exactly , String ... filenames ) {
158
+ try {
159
+ Resource [] resources = resolver .getResources (pattern );
160
+ List <String > actualNames = Arrays .stream (resources )
161
+ .map (Resource ::getFilename )
162
+ // Need to decode within GraalVM native image to get %23 converted to #.
163
+ .map (filename -> URLDecoder .decode (filename , UTF_8 ))
164
+ .sorted ()
165
+ .toList ();
166
+
167
+ // Uncomment the following if you encounter problems with matching against the file system.
168
+ // List<String> expectedNames = Arrays.stream(filenames).sorted().toList();
169
+ // System.out.println("----------------------------------------------------------------------");
170
+ // System.out.println("Expected: " + expectedNames);
171
+ // System.out.println("Actual: " + actualNames);
172
+ // Arrays.stream(resources).forEach(System.out::println);
173
+
174
+ if (exactly ) {
175
+ assertThat (actualNames ).as ("subset of files found" ).containsExactlyInAnyOrder (filenames );
176
+ }
177
+ else {
178
+ assertThat (actualNames ).as ("subset of files found" ).contains (filenames );
179
+ }
180
+ }
181
+ catch (IOException ex ) {
182
+ throw new UncheckedIOException (ex );
183
+ }
152
184
}
153
185
154
186
}
0 commit comments