diff --git a/spring-ai-test/src/main/java/org/springframework/ai/utils/SpringAiTestAutoConfigurations.java b/spring-ai-test/src/main/java/org/springframework/ai/utils/SpringAiTestAutoConfigurations.java new file mode 100644 index 00000000000..628006485e6 --- /dev/null +++ b/spring-ai-test/src/main/java/org/springframework/ai/utils/SpringAiTestAutoConfigurations.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023-2024 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.ai.utils; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Stream; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.core.annotation.AnnotationUtils; + +/** + * Utility class that creates {@link AutoConfigurations} for testing purpose. + *
+ * This class processes the provided configuration classes, checks for the presence of + * {@link AutoConfiguration} annotations, and builds an {@link AutoConfigurations} + * instance that includes both the original classes and those declared in the + * {@link AutoConfiguration#after()} attribute. + *
+ * + * @author Issam El-atif + * @see AutoConfigurations + */ +public final class SpringAiTestAutoConfigurations { + + private SpringAiTestAutoConfigurations() { + } + + /** + * Creates an {@link AutoConfigurations} instance that includes the provided + * configuration classes and any autoconfiguration classes referenced in + * {@link AutoConfiguration#after()} attribute. + * @param configurations one or more configuration classes that may be annotated with + * {@link AutoConfiguration} + * @return a composed {@link AutoConfigurations} instance including all discovered + * classes + * @see AutoConfigurations#of(Class[]) + */ + public static AutoConfigurations of(Class>... configurations) { + return AutoConfigurations.of(Arrays.stream(configurations) + .map(c -> AnnotationUtils.findAnnotation(c, AutoConfiguration.class)) + .filter(Objects::nonNull) + .map(AutoConfiguration::after) + .flatMap(ac -> Stream.concat(Stream.of(ac), Stream.of(configurations))) + .toArray(Class>[]::new)); + } + +} diff --git a/spring-ai-test/src/test/java/org/springframework/ai/utils/SpringAiTestAutoConfigurationsTests.java b/spring-ai-test/src/test/java/org/springframework/ai/utils/SpringAiTestAutoConfigurationsTests.java new file mode 100644 index 00000000000..7429ba59a4a --- /dev/null +++ b/spring-ai-test/src/test/java/org/springframework/ai/utils/SpringAiTestAutoConfigurationsTests.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023-2024 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.ai.utils; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Issam El-atif + */ +class SpringAiTestAutoConfigurationsTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + void shouldLoadProvidedConfiguration() { + this.contextRunner.withConfiguration(SpringAiTestAutoConfigurations.of(SimpleConfiguration.class)) + .run(context -> assertThat(context).hasSingleBean(SimpleConfiguration.class)); + } + + @Test + void shouldIncludeConfigurationsDeclaredInAfterAttribute() { + this.contextRunner.withConfiguration(SpringAiTestAutoConfigurations.of(AfterConfiguration.class)) + .run(context -> { + assertThat(context).hasSingleBean(SimpleConfiguration.class); + assertThat(context).hasSingleBean(AfterConfiguration.class); + }); + } + + @AutoConfiguration + static class SimpleConfiguration { + + } + + @AutoConfiguration(after = { SimpleConfiguration.class }) + static class AfterConfiguration { + + } + +}