Skip to content

Commit

Permalink
Merge branch '3.4.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
wilkinsona committed Feb 26, 2025
2 parents 2dac97a + 608b6c4 commit f45a3d7
Show file tree
Hide file tree
Showing 313 changed files with 2,920 additions and 1,275 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@

import org.springframework.boot.sampleconfig.MyComponent;
import org.springframework.boot.sampleconfig.MyNamedComponent;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.io.ClassPathResource;

Expand Down Expand Up @@ -72,26 +73,43 @@ void loadJsr330Class() {
}

@Test
@WithSampleBeansXmlResource
void loadXmlResource() {
ClassPathResource resource = new ClassPathResource("sample-beans.xml", getClass());
ClassPathResource resource = new ClassPathResource("org/springframework/boot/sample-beans.xml");
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry, resource);
assertThat(load(loader)).isOne();
assertThat(this.registry.containsBean("myXmlComponent")).isTrue();

}

@Test
@WithResource(name = "org/springframework/boot/sample-beans.groovy", content = """
import org.springframework.boot.sampleconfig.MyComponent;
beans {
myGroovyComponent(MyComponent) {}
}
""")
void loadGroovyResource() {
ClassPathResource resource = new ClassPathResource("sample-beans.groovy", getClass());
ClassPathResource resource = new ClassPathResource("org/springframework/boot/sample-beans.groovy");
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry, resource);
assertThat(load(loader)).isOne();
assertThat(this.registry.containsBean("myGroovyComponent")).isTrue();

}

@Test
@WithResource(name = "org/springframework/boot/sample-namespace.groovy", content = """
import org.springframework.boot.sampleconfig.MyComponent;
beans {
xmlns([ctx:'http://www.springframework.org/schema/context'])
ctx.'component-scan'('base-package':'nonexistent')
myGroovyComponent(MyComponent) {}
}
""")
void loadGroovyResourceWithNamespace() {
ClassPathResource resource = new ClassPathResource("sample-namespace.groovy", getClass());
ClassPathResource resource = new ClassPathResource("org/springframework/boot/sample-namespace.groovy");
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry, resource);
assertThat(load(loader)).isOne();
assertThat(this.registry.containsBean("myGroovyComponent")).isTrue();
Expand All @@ -114,14 +132,22 @@ void loadClassName() {
}

@Test
void loadResourceName() {
@WithSampleBeansXmlResource
void loadXmlName() {
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry,
"classpath:org/springframework/boot/sample-beans.xml");
assertThat(load(loader)).isOne();
assertThat(this.registry.containsBean("myXmlComponent")).isTrue();
}

@Test
@WithResource(name = "org/springframework/boot/sample-beans.groovy", content = """
import org.springframework.boot.sampleconfig.MyComponent;
beans {
myGroovyComponent(MyComponent) {}
}
""")
void loadGroovyName() {
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry,
"classpath:org/springframework/boot/sample-beans.groovy");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ void configClassContext(CapturedOutput output) throws Exception {
}

@Test
@WithSampleBeansXmlResource
void xmlContext(CapturedOutput output) throws Exception {
SpringApplication.main(getArgs("org/springframework/boot/sample-beans.xml"));
assertThat(output).contains(SPRING_STARTUP);
}

@Test
@WithSampleBeansXmlResource
void mixedContext(CapturedOutput output) throws Exception {
SpringApplication.main(getArgs(getClass().getName(), "org/springframework/boot/sample-beans.xml"));
assertThat(output).contains(SPRING_STARTUP);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@

import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
Expand All @@ -47,9 +48,10 @@ void shouldRegisterRuntimeHints() {
}

@Test
@WithResource(name = "banner.txt", content = "\uD83D\uDE0D Spring Boot! \uD83D\uDE0D")
void shouldUseUtf8() {
ResourceLoader resourceLoader = new GenericApplicationContext();
Resource resource = resourceLoader.getResource("classpath:/banner-utf8.txt");
Resource resource = resourceLoader.getResource("classpath:banner.txt");
SpringApplicationBannerPrinter printer = new SpringApplicationBannerPrinter(resourceLoader,
new ResourceBanner(resource));
Log log = mock(Log.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.boot.convert.ApplicationConversionService;
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.boot.testsupport.system.CapturedOutput;
import org.springframework.boot.testsupport.system.OutputCaptureExtension;
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
Expand Down Expand Up @@ -226,19 +227,24 @@ void sourcesMustBeAccessible() {
}

@Test
@WithResource(name = "banner.txt", content = "Running a Test!")
void customBanner(CapturedOutput output) {
SpringApplication application = spy(new SpringApplication(ExampleConfig.class));
application.setWebApplicationType(WebApplicationType.NONE);
this.context = application.run("--spring.banner.location=classpath:test-banner.txt");
this.context = application.run();
assertThat(output).startsWith("Running a Test!");

}

@Test
@WithResource(name = "banner.txt", content = """
Running a Test!
${test.property}""")
void customBannerWithProperties(CapturedOutput output) {
SpringApplication application = spy(new SpringApplication(ExampleConfig.class));
application.setWebApplicationType(WebApplicationType.NONE);
this.context = application.run("--spring.banner.location=classpath:test-banner-with-placeholder.txt",
"--test.property=123456");
this.context = application.run("--test.property=123456");
assertThat(output).containsPattern("Running a Test!\\s+123456");
}

Expand Down Expand Up @@ -288,6 +294,7 @@ void enableBannerInLogViaProperty(CapturedOutput output) {
}

@Test
@WithResource(name = "bindtoapplication.properties", content = "spring.main.banner-mode=off")
void triggersConfigFileApplicationListenerBeforeBinding() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand Down Expand Up @@ -539,6 +546,7 @@ void commandLinePropertySourceEnhancesEnvironment() {
}

@Test
@WithResource(name = "application.properties", content = "foo=bucket")
void propertiesFileEnhancesEnvironment() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand Down Expand Up @@ -571,6 +579,8 @@ void additionalProfilesOrderedBeforeActiveProfiles() {
}

@Test
@WithResource(name = "application.properties", content = "my.property=fromapplicationproperties")
@WithResource(name = "application-other.properties", content = "my.property=fromotherpropertiesfile")
void addProfilesOrderWithProperties() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand All @@ -583,6 +593,7 @@ void addProfilesOrderWithProperties() {
}

@Test
@WithResource(name = "application.properties", content = "foo=bucket")
void emptyCommandLinePropertySourceNotAdded() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand Down Expand Up @@ -813,11 +824,13 @@ void loadSources() {
}

@Test
@WithSampleBeansXmlResource
@WithResource(name = "application.properties", content = "sample.app.test.prop=*")
void wildcardSources() {
TestSpringApplication application = new TestSpringApplication();
application.getSources().add("classpath*:org/springframework/boot/sample-${sample.app.test.prop}.xml");
application.setWebApplicationType(WebApplicationType.NONE);
this.context = application.run();
this.context = application.run("--spring.config.location=classpath:/");
}

@Test
Expand Down Expand Up @@ -1138,6 +1151,8 @@ void reactiveApplicationConfiguredViaAPropertyHasTheCorrectTypeOfContextAndEnvir
}

@Test
@WithResource(name = "application-withwebapplicationtype.yml",
content = "spring.main.web-application-type: reactive")
void environmentIsConvertedIfTypeDoesNotMatch() {
ConfigurableApplicationContext context = new SpringApplication(ExampleReactiveWebConfig.class)
.run("--spring.profiles.active=withwebapplicationtype");
Expand Down Expand Up @@ -1194,6 +1209,7 @@ void circularReferencesCanBeEnabled() {
}

@Test
@WithResource(name = "custom-config/application.yml", content = "hello: world")
void relaxedBindingShouldWorkBeforeEnvironmentIsPrepared() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand Down Expand Up @@ -1328,6 +1344,8 @@ void bindsEnvironmentPrefixToSpringApplication() {
}

@Test
@WithResource(name = "spring-application-config-property-source.properties",
content = "test.name=spring-application-config-property-source")
void movesConfigClassPropertySourcesToEnd() {
SpringApplication application = new SpringApplication(PropertySourceConfig.class);
application.setWebApplicationType(WebApplicationType.NONE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.boot.testsupport.classpath.resources.WithResource;

/**
* Makes an {@code org/springframework/boot/sample-beans.xml} resource available from the
* thread context classloader.
*
* @author Andy Wilkinson
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@WithResource(name = "org/springframework/boot/sample-beans.xml",
content = """
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myXmlComponent" class="org.springframework.boot.sampleconfig.MyComponent"/>
</beans>
""")
@interface WithSampleBeansXmlResource {

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,6 +29,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationShutdownHookInstance;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
Expand Down Expand Up @@ -72,14 +73,21 @@ private void close(ApplicationContext context) {
}

@Test
@WithResource(name = "application.properties", content = """
b=file
c=file
""")
@WithResource(name = "application-foo.properties", content = "b=profile-specific-file")
void profileAndProperties() {
SpringApplicationBuilder application = new SpringApplicationBuilder().sources(ExampleConfig.class)
.contextFactory(ApplicationContextFactory.ofContextClass(StaticApplicationContext.class))
.profiles("foo")
.properties("foo=bar");
.properties("a=default");
this.context = application.run();
assertThat(this.context).isInstanceOf(StaticApplicationContext.class);
assertThat(this.context.getEnvironment().getProperty("foo")).isEqualTo("bucket");
assertThat(this.context.getEnvironment().getProperty("a")).isEqualTo("default");
assertThat(this.context.getEnvironment().getProperty("b")).isEqualTo("profile-specific-file");
assertThat(this.context.getEnvironment().getProperty("c")).isEqualTo("file");
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("foo"))).isTrue();
}

Expand Down Expand Up @@ -194,6 +202,7 @@ void parentFirstCreation() {
}

@Test
@WithResource(name = "application-node.properties", content = "bar=spam")
void parentFirstCreationWithProfileAndDefaultArgs() {
SpringApplicationBuilder application = new SpringApplicationBuilder(ExampleConfig.class).profiles("node")
.properties("transport=redis")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,8 @@

import org.junit.jupiter.api.Test;

import org.springframework.boot.testsupport.classpath.resources.WithResource;

import static org.assertj.core.api.Assertions.assertThat;

/**
Expand All @@ -32,7 +34,18 @@
*/
class ImportCandidatesTests {

private static final String IMPORTS_FILE = "META-INF/spring/org.springframework.boot.context.annotation.ImportCandidatesTests$TestAnnotation.imports";

@Test
@WithResource(name = IMPORTS_FILE, content = """
# A comment spanning a complete line
class1
class2 # with comment at the end
# Comment with some whitespace in front
class3
""")
void loadReadsFromClasspathFile() {
ImportCandidates candidates = ImportCandidates.load(TestAnnotation.class, null);
assertThat(candidates).containsExactly("class1", "class2", "class3");
Expand Down
Loading

0 comments on commit f45a3d7

Please sign in to comment.