Skip to content

Commit dc7c7ac

Browse files
committed
Register runtime hint for @WebAppConfiguration's resource path
This commit introduces automatic registration of a runtime hint for classpath resources configured via the `value` attribute in @WebAppConfiguration. Closes gh-29026
1 parent f6db2cc commit dc7c7ac

File tree

5 files changed

+51
-11
lines changed

5 files changed

+51
-11
lines changed

spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.test.context.MergedContextConfiguration;
4343
import org.springframework.test.context.SmartContextLoader;
4444
import org.springframework.test.context.TestContextBootstrapper;
45+
import org.springframework.test.context.web.WebMergedContextConfiguration;
4546
import org.springframework.util.Assert;
4647
import org.springframework.util.LinkedMultiValueMap;
4748
import org.springframework.util.MultiValueMap;
@@ -60,6 +61,8 @@
6061
*/
6162
public class TestContextAotGenerator {
6263

64+
private static final String SLASH = "/";
65+
6366
private static final Log logger = LogFactory.getLog(TestContextAotGenerator.class);
6467

6568
private final ApplicationContextAotGenerator aotGenerator = new ApplicationContextAotGenerator();
@@ -251,15 +254,30 @@ private void registerHintsForMergedConfig(MergedContextConfiguration mergedConfi
251254

252255
// @TestPropertySource(locations = ... )
253256
registerHintsForClasspathResources(mergedConfig.getPropertySourceLocations());
257+
258+
if (mergedConfig instanceof WebMergedContextConfiguration webMergedConfig) {
259+
String resourceBasePath = webMergedConfig.getResourceBasePath();
260+
if (resourceBasePath.startsWith(CLASSPATH_URL_PREFIX)) {
261+
String pattern = resourceBasePath.substring(CLASSPATH_URL_PREFIX.length());
262+
if (!pattern.startsWith(SLASH)) {
263+
pattern = SLASH + pattern;
264+
}
265+
if (!pattern.endsWith(SLASH)) {
266+
pattern += SLASH;
267+
}
268+
pattern += "*";
269+
this.runtimeHints.resources().registerPattern(pattern);
270+
}
271+
}
254272
}
255273

256274
private void registerHintsForClasspathResources(String... locations) {
257275
Arrays.stream(locations)
258276
.filter(location -> location.startsWith(CLASSPATH_URL_PREFIX))
259277
.map(location -> {
260278
location = location.substring(CLASSPATH_URL_PREFIX.length());
261-
if (!location.startsWith("/")) {
262-
location = "/" + location;
279+
if (!location.startsWith(SLASH)) {
280+
location = SLASH + location;
263281
}
264282
return location;
265283
})

spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,13 @@ private static void assertRuntimeHints(RuntimeHints runtimeHints) {
172172
assertThat(resource().forResource("/org/springframework/test/context/aot/samples/xml/test-config.xml"))
173173
.accepts(runtimeHints);
174174

175-
// @TestPropertySource(locations = ... )
175+
// @TestPropertySource(locations = ...)
176176
assertThat(resource().forResource("/org/springframework/test/context/aot/samples/basic/BasicSpringVintageTests.properties"))
177177
.accepts(runtimeHints);
178+
179+
// @WebAppConfiguration(value = ...)
180+
assertThat(resource().forResource("/META-INF/web-resources/resources/Spring.js")).accepts(runtimeHints);
181+
assertThat(resource().forResource("/META-INF/web-resources/WEB-INF/views/home.jsp")).accepts(runtimeHints);
178182
}
179183

180184
private static void assertReflectionRegistered(RuntimeHints runtimeHints, String type, MemberCategory memberCategory) {
@@ -328,9 +332,9 @@ record Mapping(MergedContextConfiguration mergedConfig, ClassName className) {
328332
"org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext005_ApplicationContextInitializer.java",
329333
"org/springframework/test/context/aot/samples/web/WebSpringJupiterTests__TestContext005_BeanFactoryRegistrations.java",
330334
"org/springframework/test/context/aot/samples/web/WebTestConfiguration__TestContext005_BeanDefinitions.java",
331-
"org/springframework/web/reactive/config/DelegatingWebFluxConfiguration__TestContext005_Autowiring.java",
332-
"org/springframework/web/reactive/config/DelegatingWebFluxConfiguration__TestContext005_BeanDefinitions.java",
333-
"org/springframework/web/reactive/config/WebFluxConfigurationSupport__TestContext005_BeanDefinitions.java",
335+
"org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext005_Autowiring.java",
336+
"org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration__TestContext005_BeanDefinitions.java",
337+
"org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport__TestContext005_BeanDefinitions.java",
334338
// XmlSpringJupiterTests
335339
"org/springframework/context/event/DefaultEventListenerFactory__TestContext006_BeanDefinitions.java",
336340
"org/springframework/context/event/EventListenerMethodProcessor__TestContext006_BeanDefinitions.java",

spring-test/src/test/java/org/springframework/test/context/aot/samples/web/WebSpringJupiterTests.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.web.context.WebApplicationContext;
2525

2626
import static org.assertj.core.api.Assertions.assertThat;
27+
import static org.hamcrest.Matchers.containsString;
2728
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
2829
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
2930
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -33,7 +34,7 @@
3334
* @author Sam Brannen
3435
* @since 6.0
3536
*/
36-
@SpringJUnitWebConfig(WebTestConfiguration.class)
37+
@SpringJUnitWebConfig(classes = WebTestConfiguration.class, resourcePath = "classpath:META-INF/web-resources")
3738
@TestPropertySource(properties = "test.engine = jupiter")
3839
public class WebSpringJupiterTests {
3940

@@ -49,7 +50,7 @@ void setUpMockMvc() {
4950
}
5051

5152
@org.junit.jupiter.api.Test
52-
void test(@Value("${test.engine}") String testEngine) throws Exception {
53+
void controller(@Value("${test.engine}") String testEngine) throws Exception {
5354
assertThat(testEngine)
5455
.as("@Value").isEqualTo("jupiter");
5556
assertThat(wac.getEnvironment().getProperty("test.engine"))
@@ -59,4 +60,13 @@ void test(@Value("${test.engine}") String testEngine) throws Exception {
5960
.andExpectAll(status().isOk(), content().string("Hello, AOT!"));
6061
}
6162

63+
@org.junit.jupiter.api.Test
64+
void resources() throws Exception {
65+
this.mockMvc.perform(get("/resources/Spring.js"))
66+
.andExpectAll(
67+
content().contentType("application/javascript"),
68+
content().string(containsString("Spring={};"))
69+
);
70+
}
71+
6272
}

spring-test/src/test/java/org/springframework/test/context/aot/samples/web/WebTestConfiguration.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,26 @@
1818

1919
import org.springframework.context.annotation.Bean;
2020
import org.springframework.context.annotation.Configuration;
21-
import org.springframework.web.reactive.config.EnableWebFlux;
21+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
22+
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
23+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
2224

2325
/**
2426
* @author Sam Brannen
2527
* @since 6.0
2628
*/
2729
@Configuration(proxyBeanMethods = false)
28-
@EnableWebFlux
29-
class WebTestConfiguration {
30+
@EnableWebMvc
31+
class WebTestConfiguration implements WebMvcConfigurer {
3032

3133
@Bean
3234
MessageController messageController() {
3335
return new MessageController();
3436
}
3537

38+
@Override
39+
public void addResourceHandlers(ResourceHandlerRegistry registry) {
40+
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
41+
}
42+
3643
}

src/checkstyle/checkstyle-suppressions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<suppress files="src[\\/]main[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/]servlet[\\/]result[\\/].+Matchers" checks="IllegalImport" id="bannedHamcrestImports"/>
8989
<!-- spring-test - test -->
9090
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/].+TestNGTests" checks="IllegalImport" id="bannedTestNGImports"/>
91+
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]aot[\\/]samples[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
9192
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
9293
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
9394
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/](client|reactive|servlet)[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>

0 commit comments

Comments
 (0)