diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java index 809555031..55684eeb0 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java @@ -31,7 +31,6 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.processing.Processor; -import javax.tools.JavaCompiler; import org.apiguardian.api.API; import org.apiguardian.api.API.Status; @@ -58,8 +57,6 @@ public abstract class AbstractJctCompiler> implements JctCompiler { - private final JavaCompiler jsr199Compiler; - private final JctFlagBuilder flagBuilder; private final List annotationProcessors; private final List annotationProcessorOptions; private final List compilerOptions; @@ -87,19 +84,10 @@ public abstract class AbstractJctCompiler> /** * Initialize this compiler. * - * @param name the friendly name of the compiler to default to. - * @param jsr199Compiler the JSR-199 compiler implementation to use. - * @param flagBuilder the flag builder to use. + * @param defaultName the printable default name to use for the compiler. */ - protected AbstractJctCompiler( - String name, - JavaCompiler jsr199Compiler, - JctFlagBuilder flagBuilder - ) { - this.name = requireNonNull(name, "name"); - this.jsr199Compiler = requireNonNull(jsr199Compiler, "jsr199Compiler"); - this.flagBuilder = requireNonNull(flagBuilder, "flagBuilder"); - + protected AbstractJctCompiler(String defaultName) { + name = requireNonNull(defaultName, "name"); annotationProcessors = new ArrayList<>(); annotationProcessorOptions = new ArrayList<>(); compilerOptions = new ArrayList<>(); @@ -126,12 +114,18 @@ protected AbstractJctCompiler( @Override public JctCompilationImpl compile(Workspace workspace) { - return JctJsr199Interop.compile(workspace, myself(), jsr199Compiler, flagBuilder, null); + var flagBuilder = getJctFlagBuilderFactory().createFlagBuilder(); + var compiler = getJsr199CompilerFactory().createCompiler(); + + return JctJsr199Interop.compile(workspace, myself(), compiler, flagBuilder, null); } @Override public JctCompilationImpl compile(Workspace workspace, Collection classNames) { - return JctJsr199Interop.compile(workspace, myself(), jsr199Compiler, flagBuilder, classNames); + var flagBuilder = getJctFlagBuilderFactory().createFlagBuilder(); + var compiler = getJsr199CompilerFactory().createCompiler(); + + return JctJsr199Interop.compile(workspace, myself(), compiler, flagBuilder, classNames); } @Override @@ -152,24 +146,6 @@ public A name(String name) { return myself(); } - /** - * Get the flag builder to use. - * - * @return the flag builder. - */ - public JctFlagBuilder getFlagBuilder() { - return flagBuilder; - } - - /** - * Get the JSR-199 compiler to use. - * - * @return the JSR-199 compiler. - */ - public JavaCompiler getJsr199Compiler() { - return jsr199Compiler; - } - @Override public boolean isVerbose() { return verbose; @@ -451,6 +427,28 @@ public final String toString() { return name; } + /** + * Get the flag builder factory to use for building flags. + * + * @return the factory. + */ + public abstract JctFlagBuilderFactory getJctFlagBuilderFactory(); + + /** + * Get the JSR-199 compiler factory to use for initialising an internal compiler. + * + * @return the factory. + */ + public abstract Jsr199CompilerFactory getJsr199CompilerFactory(); + + /** + * {@inheritDoc} + * + * @return the default release version to use when no version is specified by the user. + */ + @Override + public abstract String getDefaultRelease(); + /** * Get this implementation of {@link AbstractJctCompiler}, cast to the type parameter {@link A}. * diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilderFactory.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilderFactory.java new file mode 100644 index 000000000..c9fdefd7e --- /dev/null +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilderFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 - 2023, 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 + * + * http://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 io.github.ascopes.jct.compilers; + +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; + +/** + * Factory that creates a flag builder. + * + * @author Ashley Scopes + * @since 0.0.1 (0.0.1-M7) + */ +@API(since = "0.0.1", status = Status.STABLE) +@FunctionalInterface +public interface JctFlagBuilderFactory { + + /** + * Create a new flag builder. + * + * @return the flag builder. + */ + JctFlagBuilder createFlagBuilder(); +} diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/Jsr199CompilerFactory.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/Jsr199CompilerFactory.java new file mode 100644 index 000000000..1897b10ea --- /dev/null +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/Jsr199CompilerFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 - 2023, 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 + * + * http://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 io.github.ascopes.jct.compilers; + +import javax.tools.JavaCompiler; +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; + +/** + * Factory that creates an instance of a JSR-199 compiler. + * + * @author Ashley Scopes + * @since 0.0.1 (0.0.1-M7) + */ +@API(since = "0.0.1", status = Status.STABLE) +@FunctionalInterface +public interface Jsr199CompilerFactory { + + /** + * Create a new instance of a JSR-199 {@link JavaCompiler}. + * + * @return the JSR-199 Java compiler. + */ + JavaCompiler createCompiler(); +} diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JctCompilationImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JctCompilationImpl.java index 8e65b613f..4763c9306 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JctCompilationImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JctCompilationImpl.java @@ -52,9 +52,14 @@ public final class JctCompilationImpl implements JctCompilation { private final List> diagnostics; private final JctFileManager fileManager; + @SuppressWarnings("ConstantConditions") private JctCompilationImpl(Builder builder) { - success = requireNonNull(builder.success, "success"); - failOnWarnings = requireNonNull(builder.failOnWarnings, "failOnWarnings"); + success = requireNonNull( + builder.success, "success" + ); + failOnWarnings = requireNonNull( + builder.failOnWarnings, "failOnWarnings" + ); outputLines = unmodifiableList( requireNonNullValues(builder.outputLines, "outputLines") ); @@ -64,7 +69,9 @@ private JctCompilationImpl(Builder builder) { diagnostics = unmodifiableList( requireNonNullValues(builder.diagnostics, "diagnostics") ); - fileManager = requireNonNull(builder.fileManager, "fileManager"); + fileManager = requireNonNull( + builder.fileManager, "fileManager" + ); } @Override diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctCompilerImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctCompilerImpl.java index da6100748..96eb53825 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctCompilerImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctCompilerImpl.java @@ -15,10 +15,13 @@ */ package io.github.ascopes.jct.compilers.javac; +import static java.util.Objects.requireNonNull; + import io.github.ascopes.jct.compilers.AbstractJctCompiler; +import io.github.ascopes.jct.compilers.JctFlagBuilderFactory; +import io.github.ascopes.jct.compilers.Jsr199CompilerFactory; import javax.annotation.concurrent.NotThreadSafe; import javax.lang.model.SourceVersion; -import javax.tools.JavaCompiler; import javax.tools.ToolProvider; import org.apiguardian.api.API; import org.apiguardian.api.API.Status; @@ -39,40 +42,24 @@ public final class JavacJctCompilerImpl extends AbstractJctCompiler requireNonNull(ToolProvider.getSystemJavaCompiler()); } /** diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java index 57d56eb4c..ef97b2c29 100644 --- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java +++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -33,6 +34,8 @@ import io.github.ascopes.jct.compilers.JctCompiler; import io.github.ascopes.jct.compilers.JctCompilerConfigurer; import io.github.ascopes.jct.compilers.JctFlagBuilder; +import io.github.ascopes.jct.compilers.JctFlagBuilderFactory; +import io.github.ascopes.jct.compilers.Jsr199CompilerFactory; import io.github.ascopes.jct.compilers.impl.JctCompilationImpl; import io.github.ascopes.jct.compilers.impl.JctJsr199Interop; import io.github.ascopes.jct.filemanagers.AnnotationProcessorDiscovery; @@ -93,7 +96,7 @@ class AbstractJctCompilerTest { void setUp() { name = someText(); defaultRelease = Integer.toString(someInt(11, 21)); - compiler = new CompilerImpl(name, jsr199Compiler, flagBuilder, defaultRelease); + compiler = spy(new CompilerImpl(name, defaultRelease)); } @DisplayName("AbstractJctCompiler constructor tests") @@ -106,29 +109,11 @@ class ConstructorTest { @Test void constructorRaisesNullPointerExceptionIfNameIsNull() { // Then - assertThatThrownBy(() -> new CompilerImpl(null, jsr199Compiler, flagBuilder, defaultRelease)) + assertThatThrownBy(() -> new CompilerImpl(null, defaultRelease)) .isInstanceOf(NullPointerException.class) .hasMessage("name"); } - @DisplayName("constructor raises a NullPointerException if jsr199Compiler is null") - @Test - void constructorRaisesNullPointerExceptionIfJsr199CompilerIsNull() { - // Then - assertThatThrownBy(() -> new CompilerImpl(name, null, flagBuilder, defaultRelease)) - .isInstanceOf(NullPointerException.class) - .hasMessage("jsr199Compiler"); - } - - @DisplayName("constructor raises a NullPointerException if flagBuilder is null") - @Test - void constructorRaisesNullPointerExceptionIfFlagBuilderIsNull() { - // Then - assertThatThrownBy(() -> new CompilerImpl(name, jsr199Compiler, null, defaultRelease)) - .isInstanceOf(NullPointerException.class) - .hasMessage("flagBuilder"); - } - @DisplayName("constructor initialises name correctly") @Test void constructorInitialisesNameCorrectly() { @@ -137,22 +122,6 @@ void constructorInitialisesNameCorrectly() { .isSameAs(name); } - @DisplayName("constructor initialises jsr199Compiler correctly") - @Test - void constructorInitialisesJsr199CompilerCorrectly() { - // Then - assertThatCompilerField("jsr199Compiler") - .isSameAs(jsr199Compiler); - } - - @DisplayName("constructor initialises flag builder correctly") - @Test - void constructorInitialisesFlagBuilderCorrectly() { - // Then - assertThatCompilerField("flagBuilder") - .isSameAs(flagBuilder); - } - @DisplayName("constructor initialises annotationProcessors to empty list") @Test void constructorInitialisesAnnotationProcessorsToEmptyList() { @@ -333,10 +302,10 @@ void constructorInitialisesAnnotationProcessorDiscoveryToDefaultValue() { @DisplayName(".compile(Workspace) builds the expected compilation object") @Test void compileWorkspaceBuildsTheExpectedCompilationObject() { - try (var factoryCls = mockStatic(JctJsr199Interop.class)) { + try (var interopCls = mockStatic(JctJsr199Interop.class)) { // Given var expectedCompilation = mock(JctCompilationImpl.class); - factoryCls.when(() -> JctJsr199Interop.compile(any(), any(), any(), any(), any())) + interopCls.when(() -> JctJsr199Interop.compile(any(), any(), any(), any(), any())) .thenReturn(expectedCompilation); var expectedWorkspace = mock(Workspace.class); @@ -344,8 +313,10 @@ void compileWorkspaceBuildsTheExpectedCompilationObject() { var actualCompilation = compiler.compile(expectedWorkspace); // Then - factoryCls.verify(() -> JctJsr199Interop + interopCls.verify(() -> JctJsr199Interop .compile(expectedWorkspace, compiler, jsr199Compiler, flagBuilder, null)); + verify(compiler).getJsr199CompilerFactory(); + verify(compiler).getJctFlagBuilderFactory(); assertThat(actualCompilation).isSameAs(expectedCompilation); } @@ -485,7 +456,7 @@ void nameReturnsTheCompiler() { } @DisplayName(".name(null) throws a NullPointerException") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void passingNullToNameThrowsNullPointerException() { // Then @@ -495,20 +466,6 @@ void passingNullToNameThrowsNullPointerException() { } } - @DisplayName(".getFlagBuilder() returns the flag builder") - @Test - void getFlagBuilderReturnsFlagBuilder() { - // Then - assertThat(compiler.getFlagBuilder()).isSameAs(flagBuilder); - } - - @DisplayName(".getJsr199Compiler() returns the compiler") - @Test - void getJsr199CompilerReturnsTheCompiler() { - // Then - assertThat(compiler.getJsr199Compiler()).isSameAs(jsr199Compiler); - } - @DisplayName(".isVerbose() returns the expected values") @ValueSource(booleans = {true, false}) @ParameterizedTest(name = "for verbose = {0}") @@ -1286,7 +1243,7 @@ void localeSetsExpectedValue(Locale expected) { } @DisplayName(".locale(...) throws a NullPointerException if the locale is null") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void localeThrowsNullPointerExceptionIfNull() { // Then @@ -1333,7 +1290,7 @@ void logCharsetSetsExpectedValue(Charset expected) { } @DisplayName(".logCharset(...) throws a NullPointerException if the logCharset is null") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void logCharsetThrowsNullPointerExceptionIfNull() { // Then @@ -1381,7 +1338,7 @@ void fileManagerLoggingModeSetsExpectedValue(LoggingMode expected) { @DisplayName(".fileManagerLoggingMode(...) throws a NullPointerException if " + "fileManagerLoggingMode is null") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void fileManagerLoggingModeThrowsNullPointerExceptionIfNull() { // Then @@ -1429,7 +1386,7 @@ void diagnosticLoggingModeSetsExpectedValue(LoggingMode expected) { @DisplayName(".diagnosticLoggingMode(...) throws a NullPointerException " + "if diagnosticLoggingMode is null") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void diagnosticLoggingModeThrowsNullPointerExceptionIfNull() { // Then @@ -1477,7 +1434,7 @@ void annotationProcessorDiscoverySetsExpectedValue(AnnotationProcessorDiscovery @DisplayName(".annotationProcessorDiscovery(...) throws a NullPointerException " + "if annotationProcessorDiscovery is null") - @SuppressWarnings("DataFlowIssue") + @SuppressWarnings("ConstantConditions") @Test void annotationProcessorDiscoveryThrowsNullPointerExceptionIfNull() { // Then @@ -1532,17 +1489,12 @@ static Stream charsets() { /// Helper methods and types /// //////////////////////////////// - static class CompilerImpl extends AbstractJctCompiler { + class CompilerImpl extends AbstractJctCompiler { private final String defaultRelease; - CompilerImpl( - String name, - JavaCompiler jsr199Compiler, - JctFlagBuilder flagBuilder, - String defaultRelease - ) { - super(name, jsr199Compiler, flagBuilder); + CompilerImpl(String name, String defaultRelease) { + super(name); this.defaultRelease = defaultRelease; } @@ -1550,6 +1502,16 @@ static class CompilerImpl extends AbstractJctCompiler { public String getDefaultRelease() { return defaultRelease; } + + @Override + public JctFlagBuilderFactory getJctFlagBuilderFactory() { + return () -> flagBuilder; + } + + @Override + public Jsr199CompilerFactory getJsr199CompilerFactory() { + return () -> jsr199Compiler; + } } @SafeVarargs diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctCompilerImplTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctCompilerImplTest.java index f9e619e40..0bdee0519 100644 --- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctCompilerImplTest.java +++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctCompilerImplTest.java @@ -16,10 +16,10 @@ package io.github.ascopes.jct.tests.unit.compilers.javac; import static io.github.ascopes.jct.tests.helpers.Fixtures.someInt; -import static io.github.ascopes.jct.tests.helpers.Fixtures.someText; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; @@ -39,84 +39,77 @@ * * @author Ashley Scopes */ +@SuppressWarnings("ResultOfMethodCallIgnored") @DisplayName("JavacJctCompilerImpl tests") class JavacJctCompilerImplTest { - JavaCompiler javaCompiler; JavacJctCompilerImpl compiler; @BeforeEach void setUp() { - javaCompiler = mock(JavaCompiler.class); - compiler = new JavacJctCompilerImpl(javaCompiler); + compiler = new JavacJctCompilerImpl(); } - - @DisplayName("initialising a compiler with no arguments uses the platform compiler") + + @DisplayName("Compilers have the expected JSR-199 compiler factory") @Test - void initialisingCompilerWithNoArgumentsUsesPlatformCompiler() { - try (var toolProvider = mockStatic(ToolProvider.class)) { - // Given - toolProvider.when(ToolProvider::getSystemJavaCompiler).thenReturn(javaCompiler); + void compilersHaveTheExpectedCompilerFactory() { + // Given + try (var toolProviderMock = mockStatic(ToolProvider.class)) { + var jsr199Compiler = mock(JavaCompiler.class); + toolProviderMock.when(ToolProvider::getSystemJavaCompiler).thenReturn(jsr199Compiler); // When - var compiler = new JavacJctCompilerImpl(); + var actualCompiler = compiler.getJsr199CompilerFactory().createCompiler(); // Then - assertThat(compiler.getJsr199Compiler()).isSameAs(javaCompiler); - toolProvider.verify(ToolProvider::getSystemJavaCompiler); + toolProviderMock.verify(ToolProvider::getSystemJavaCompiler); + assertThat(actualCompiler).isSameAs(jsr199Compiler); } } - @DisplayName("initialising a compiler with a string argument uses the platform compiler") + @DisplayName("Compilers have the expected flag builder factory") @Test - void initialisingCompilerWithStringUsesPlatformCompiler() { - try (var toolProvider = mockStatic(ToolProvider.class)) { - // Given - toolProvider.when(ToolProvider::getSystemJavaCompiler).thenReturn(javaCompiler); - + void compilersHaveTheExpectedFlagBuilderFactory() { + // Given + try (var flagBuilderMock = mockConstruction(JavacJctFlagBuilderImpl.class)) { // When - var compiler = new JavacJctCompilerImpl("foo"); + var flagBuilder = compiler.getJctFlagBuilderFactory().createFlagBuilder(); // Then - assertThat(compiler.getJsr199Compiler()).isSameAs(javaCompiler); - toolProvider.verify(ToolProvider::getSystemJavaCompiler); + assertThat(flagBuilderMock.constructed()).hasSize(1); + assertThat(flagBuilder).isSameAs(flagBuilderMock.constructed().get(0)); } } - @DisplayName("initialising a compiler with a string argument uses the string as the name") + @DisplayName("Compilers have the expected default release string") @Test - void initialisingCompilerWithStringUsesTheGivenStringAsTheName() { + void compilersHaveTheExpectedDefaultRelease() { // Given - var name = someText(); + try (var compilerClassMock = mockStatic(JavacJctCompilerImpl.class)) { + var latestSupportedInt = someInt(11, 21); + compilerClassMock + .when(() -> JavacJctCompilerImpl.getLatestSupportedVersionInt(anyBoolean())) + .thenReturn(latestSupportedInt); - // When - var compiler = new JavacJctCompilerImpl(name); + // When + var defaultRelease = compiler.getDefaultRelease(); - // Then - assertThat(compiler.getName()).isEqualTo(name); + // Then + compilerClassMock + .verify(() -> JavacJctCompilerImpl.getLatestSupportedVersionInt(false)); + + assertThat(defaultRelease) + .isEqualTo("%d", latestSupportedInt); + } } - @DisplayName("compilers have the expected default name") + @DisplayName("Compilers have the expected default name") @Test void compilersHaveTheExpectedDefaultName() { // Then assertThat(compiler.getName()).isEqualTo("JDK Compiler"); } - @DisplayName("compilers have the expected JSR-199 compiler implementation") - @Test - void compilersHaveTheExpectedCompilerImplementation() { - // Then - assertThat(compiler.getJsr199Compiler()).isSameAs(javaCompiler); - } - - @DisplayName("compilers have the expected flag builder") - @Test - void compilersHaveTheExpectedFlagBuilder() { - // Then - assertThat(compiler.getFlagBuilder()).isInstanceOf(JavacJctFlagBuilderImpl.class); - } - @DisplayName("Compilers have no default compiler flags set") @Test void compilersHaveNoDefaultCompilerFlagsSet() { @@ -138,28 +131,6 @@ void compilersHaveNoDefaultAnnotationProcessorsSet() { assertThat(compiler.getAnnotationProcessors()).isEmpty(); } - @DisplayName("compilers have the expected default release string") - @Test - void compilersHaveTheExpectedDefaultRelease() { - // Given - try (var compilerClassMock = mockStatic(JavacJctCompilerImpl.class)) { - var latestSupportedInt = someInt(11, 21); - compilerClassMock - .when(() -> JavacJctCompilerImpl.getLatestSupportedVersionInt(anyBoolean())) - .thenReturn(latestSupportedInt); - - // When - var defaultRelease = compiler.getDefaultRelease(); - - // Then - compilerClassMock - .verify(() -> JavacJctCompilerImpl.getLatestSupportedVersionInt(false)); - - assertThat(defaultRelease) - .isEqualTo("%d", latestSupportedInt); - } - } - @DisplayName("the earliest supported version int has the expected value") @CsvSource(useHeadersInDisplayName = true, value = { "SourceVersion.latest(), modules, expectedResult",