Expose compiler warnings in CompilationException

This commit improves TestCompiler to expose both errors and warnings
instead of an opaque message. When compilation fails, both errors and
warnings are displayed.

This is particularly useful when combined with the `-Werror` option
that turns the presence of a warning into an error.

Closes gh-36037
This commit is contained in:
Stéphane Nicoll
2025-12-17 14:33:14 +01:00
parent 86e89d53a9
commit e9a4b93477
4 changed files with 176 additions and 45 deletions
@@ -16,21 +16,72 @@
package org.springframework.core.test.tools;
import java.util.List;
import javax.tools.Diagnostic;
import org.junit.jupiter.api.Test;
import org.springframework.core.test.tools.CompilationException.Problem;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CompilationException}.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
class CompilationExceptionTests {
@Test
void getMessageReturnsMessage() {
CompilationException exception = new CompilationException("message", SourceFiles.none(), ResourceFiles.none());
assertThat(exception).hasMessageContaining("message");
void exceptionMessageReportsSingleError() {
CompilationException exception = new CompilationException(
List.of(new Problem(Diagnostic.Kind.ERROR, "error message")),
SourceFiles.none(), ResourceFiles.none());
assertThat(exception.getMessage().lines()).containsExactly(
"Unable to compile source", "", "Errors:", "- error message");
}
@Test
void exceptionMessageReportsSingleWarning() {
CompilationException exception = new CompilationException(
List.of(new Problem(Diagnostic.Kind.MANDATORY_WARNING, "warning message")),
SourceFiles.none(), ResourceFiles.none());
assertThat(exception.getMessage().lines()).containsExactly(
"Unable to compile source", "", "Warnings:", "- warning message");
}
@Test
void exceptionMessageReportsProblems() {
CompilationException exception = new CompilationException(List.of(
new Problem(Diagnostic.Kind.MANDATORY_WARNING, "warning message"),
new Problem(Diagnostic.Kind.ERROR, "error message"),
new Problem(Diagnostic.Kind.WARNING, "warning message2"),
new Problem(Diagnostic.Kind.ERROR, "error message2")), SourceFiles.none(), ResourceFiles.none());
assertThat(exception.getMessage().lines()).containsExactly(
"Unable to compile source", "", "Errors:", "- error message", "- error message2", "" ,
"Warnings:", "- warning message","- warning message2");
}
@Test
void exceptionMessageReportsSourceCode() {
CompilationException exception = new CompilationException(
List.of(new Problem(Diagnostic.Kind.ERROR, "error message")),
SourceFiles.of(SourceFile.of("public class Hello {}")), ResourceFiles.none());
assertThat(exception.getMessage().lines()).containsExactly(
"Unable to compile source", "", "Errors:", "- error message", "",
"---- source: Hello.java", "public class Hello {}");
}
@Test
void exceptionMessageReportsResource() {
CompilationException exception = new CompilationException(
List.of(new Problem(Diagnostic.Kind.ERROR, "error message")),
SourceFiles.none(), ResourceFiles.of(ResourceFile.of("application.properties", "test=value")));
assertThat(exception.getMessage().lines()).containsExactly(
"Unable to compile source", "", "Errors:", "- error message", "",
"---- resource: application.properties", "test=value");
}
}
@@ -30,6 +30,7 @@ import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
@@ -136,7 +137,8 @@ class TestCompilerTests {
assertThatExceptionOfType(CompilationException.class).isThrownBy(
() -> TestCompiler.forSystem().withSources(
SourceFile.of(HELLO_BAD)).compile(compiled -> {
}));
})).satisfies(ex -> assertThat(ex.getProblems()).singleElement()
.satisfies(problem -> assertThat(problem.message()).contains("Supplier")));
}
@Test
@@ -177,7 +179,14 @@ class TestCompilerTests {
assertThatExceptionOfType(CompilationException.class).isThrownBy(
() -> TestCompiler.forSystem().failOnWarning().withSources(
SourceFile.of(HELLO_DEPRECATED), main).compile(compiled -> {
}));
})).satisfies(compilationException -> {
assertThat(compilationException.getProblems(Diagnostic.Kind.ERROR)).singleElement()
.satisfies(error -> assertThat(error.message())
.contains("-Werror"));
assertThat(compilationException.getProblems(Diagnostic.Kind.MANDATORY_WARNING)).singleElement()
.satisfies(warning -> assertThat(warning.message())
.contains("get()", "com.example.Hello"));
});
}
@Test