From 3d9f6da25e1ff18ed71a916f75125db7f90f2625 Mon Sep 17 00:00:00 2001
From: Ashley Scopes <73482956+ascopes@users.noreply.github.com>
Date: Sat, 21 Jan 2023 20:35:46 +0000
Subject: [PATCH] Implement ability to change default versioning strategy in
JUnit support.
If the user wishes to iterate across sources/targets instead of
releases for the JUnit annotations, there is now an attribute that
can be overridden to support that.
---
.../jct/junit/AbstractCompilersProvider.java | 36 ++--
.../ascopes/jct/junit/JavacCompilerTest.java | 11 +
.../jct/junit/JavacCompilersProvider.java | 7 +-
.../ascopes/jct/junit/VersionStrategy.java | 95 +++++++++
.../junit/AbstractCompilersProviderTest.java | 191 +++++++++---------
.../junit/JavacCompilersProviderTest.java | 8 +-
.../tests/unit/junit/VersionStrategyTest.java | 111 ++++++++++
7 files changed, 347 insertions(+), 112 deletions(-)
create mode 100644 java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/VersionStrategy.java
create mode 100644 java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/VersionStrategyTest.java
diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/AbstractCompilersProvider.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/AbstractCompilersProvider.java
index 6717d551b..f3dcdf9a1 100644
--- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/AbstractCompilersProvider.java
+++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/AbstractCompilersProvider.java
@@ -51,6 +51,7 @@
* int minVersion() default Integer.MIN_VALUE;
* int maxVersion() default Integer.MAX_VALUE;
* Class<? extends JctSimpleCompilerConfigurer>[] configurers() default {};
+ * VersionStrategy versionStrategy() default VersionStrategy.RELEASE;
* }
*
*
@@ -62,18 +63,18 @@
* implements AnnotationConsumer<MyCompilerTest> {
*
* {@literal @Override}
- * protected JctCompiler<?, ?> compilerForVersion(int release) {
- * return new MyCompilerImpl().release(release);
+ * protected JctCompiler<?, ?> initializeNewCompiler() {
+ * return new MyCompilerImpl();
* }
*
* {@literal @Override}
* protected int minSupportedVersion(boolean modules) {
- * return 11;
+ * return 11; // Support Java 11 as the minimum.
* }
*
* {@literal @Override}
* protected int maxSupportedVersion(boolean modules) {
- * return 19;
+ * return 19; // Support Java 19 as the maximum.
* }
*
* {@literal @Override}
@@ -82,7 +83,8 @@
* annotation.minVersion(),
* annotation.maxVersion(),
* true,
- * annotation.configurers()
+ * annotation.configurers(),
+ * annotation.versionStrategy(),
* );
* }
* }
@@ -121,6 +123,7 @@ public abstract class AbstractCompilersProvider implements ArgumentsProvider {
private int minVersion;
private int maxVersion;
private Class extends JctCompilerConfigurer>>[] configurerClasses;
+ private VersionStrategy versionStrategy;
/**
* Initialise this provider.
@@ -129,13 +132,18 @@ protected AbstractCompilersProvider() {
minVersion = 0;
maxVersion = Integer.MAX_VALUE;
configurerClasses = emptyArray();
+ versionStrategy = VersionStrategy.RELEASE;
}
@Override
public Stream extends Arguments> provideArguments(ExtensionContext context) {
return IntStream
.rangeClosed(minVersion, maxVersion)
- .mapToObj(this::compilerForVersion)
+ .mapToObj(version -> {
+ var compiler = initializeNewCompiler();
+ versionStrategy.configureCompiler(compiler, version);
+ return compiler;
+ })
.peek(this::applyConfigurers)
.map(Arguments::of);
}
@@ -147,12 +155,14 @@ public Stream extends Arguments> provideArguments(ExtensionContext context) {
* @param max the inclusive maximum compiler version to use.
* @param modules whether the compiler version must support modules.
* @param configurerClasses the configurer classes to apply to each compiler.
+ * @param versionStrategy the version strategy to use.
*/
protected final void configure(
int min,
int max,
boolean modules,
- Class extends JctCompilerConfigurer>>[] configurerClasses
+ Class extends JctCompilerConfigurer>>[] configurerClasses,
+ VersionStrategy versionStrategy
) {
min = Math.max(min, minSupportedVersion(modules));
max = Math.min(max, maxSupportedVersion(modules));
@@ -171,15 +181,15 @@ protected final void configure(
maxVersion = max;
this.configurerClasses = requireNonNullValues(configurerClasses, "configurerClasses");
+ this.versionStrategy = requireNonNull(versionStrategy, "versionStrategy");
}
/**
- * Initialise a new compiler on the given release.
+ * Initialise a new compiler.
*
- * @param release the release version to use.
- * @return the compiler.
+ * @return the compiler object.
*/
- protected abstract JctCompiler, ?> compilerForVersion(int release);
+ protected abstract JctCompiler, ?> initializeNewCompiler();
/**
* Get the minimum supported compiler version.
@@ -201,7 +211,7 @@ private void applyConfigurers(JctCompiler, ?> compiler) {
var classes = requireNonNull(configurerClasses);
for (var configurerClass : classes) {
- var configurer = initialiseConfigurer(configurerClass);
+ var configurer = initializeConfigurer(configurerClass);
try {
configurer.configure(compiler);
@@ -218,7 +228,7 @@ private void applyConfigurers(JctCompiler, ?> compiler) {
}
}
- private JctCompilerConfigurer> initialiseConfigurer(
+ private JctCompilerConfigurer> initializeConfigurer(
Class extends JctCompilerConfigurer>> configurerClass
) {
Constructor extends JctCompilerConfigurer>> constructor;
diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilerTest.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilerTest.java
index 628208e77..8533fecf0 100644
--- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilerTest.java
+++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilerTest.java
@@ -79,4 +79,15 @@
*/
boolean modules() default false;
+ /**
+ * The version strategy to use.
+ *
+ *
This determines whether the version number being iterated across specifies the
+ * release, source, target, or source and target versions.
+ *
+ *
The default is to specify the release.
+ *
+ * @return the version strategy to use.
+ */
+ VersionStrategy versionStrategy() default VersionStrategy.RELEASE;
}
diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilersProvider.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilersProvider.java
index c9778da71..5f5f4733d 100644
--- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilersProvider.java
+++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/JavacCompilersProvider.java
@@ -41,8 +41,8 @@ public JavacCompilersProvider() {
}
@Override
- protected JctCompiler, ?> compilerForVersion(int release) {
- return new JavacJctCompilerImpl("javac release " + release).release(release);
+ protected JctCompiler, ?> initializeNewCompiler() {
+ return new JavacJctCompilerImpl();
}
@Override
@@ -62,7 +62,8 @@ public void accept(JavacCompilerTest javacCompilers) {
javacCompilers.minVersion(),
javacCompilers.maxVersion(),
javacCompilers.modules(),
- javacCompilers.configurers()
+ javacCompilers.configurers(),
+ javacCompilers.versionStrategy()
);
}
}
diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/VersionStrategy.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/VersionStrategy.java
new file mode 100644
index 000000000..848dead3d
--- /dev/null
+++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/junit/VersionStrategy.java
@@ -0,0 +1,95 @@
+/*
+ * 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.junit;
+
+import io.github.ascopes.jct.compilers.JctCompiler;
+import java.util.function.BiConsumer;
+import javax.annotation.concurrent.Immutable;
+import javax.annotation.concurrent.ThreadSafe;
+import org.apiguardian.api.API;
+import org.apiguardian.api.API.Status;
+
+/**
+ * Strategy for setting a version on a JUnit compiler annotation.
+ *
+ * @author Ashley Scopes
+ * @since 0.0.1 (0.0.1-M7)
+ */
+@API(since = "0.0.1", status = Status.STABLE)
+@Immutable
+@ThreadSafe
+public enum VersionStrategy {
+
+ /**
+ * Set the {@link JctCompiler#release release}.
+ */
+ RELEASE(
+ JctCompiler::release,
+ (compiler, version) -> compiler
+ .name(compiler.getName() + " (release = Java " + version + ")")
+ ),
+
+ /**
+ * Set the {@link JctCompiler#source} source}.
+ */
+ SOURCE(
+ JctCompiler::source,
+ (compiler, version) -> compiler
+ .name(compiler.getName() + " (source = Java " + version + ")")
+ ),
+
+ /**
+ * Set the {@link JctCompiler#target} target}.
+ */
+ TARGET(
+ JctCompiler::target,
+ (compiler, version) -> compiler
+ .name(compiler.getName() + " (target = Java " + version + ")")
+ ),
+
+ /**
+ * Set the {@link JctCompiler#source source} and {@link JctCompiler#target target}.
+ */
+ SOURCE_AND_TARGET(
+ (compiler, version) -> compiler
+ .source(version)
+ .target(version),
+ (compiler, version) -> compiler
+ .name(compiler.getName() + " (source and target = Java " + version + ")")
+ );
+
+ private final BiConsumer, Integer> versionSetter;
+ private final BiConsumer, Integer> descriptionFormatter;
+
+ VersionStrategy(
+ BiConsumer, Integer> versionSetter,
+ BiConsumer, Integer> descriptionFormatter
+ ) {
+ this.versionSetter = versionSetter;
+ this.descriptionFormatter = descriptionFormatter;
+ }
+
+ /**
+ * Set the given version on the compiler, according to the strategy in use.
+ *
+ * @param compiler the compiler to configure.
+ * @param version the version to set.
+ */
+ public void configureCompiler(JctCompiler, ?> compiler, int version) {
+ versionSetter.accept(compiler, version);
+ descriptionFormatter.accept(compiler, version);
+ }
+}
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/AbstractCompilersProviderTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/AbstractCompilersProviderTest.java
index a7c632933..d45fb3805 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/AbstractCompilersProviderTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/AbstractCompilersProviderTest.java
@@ -18,19 +18,20 @@
import static io.github.ascopes.jct.tests.helpers.GenericMock.mockRaw;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
-import static org.assertj.core.api.InstanceOfAssertFactories.STRING;
import static org.assertj.core.api.InstanceOfAssertFactories.THROWABLE;
import static org.assertj.core.api.InstanceOfAssertFactories.array;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.withSettings;
import io.github.ascopes.jct.compilers.JctCompiler;
import io.github.ascopes.jct.compilers.JctCompilerConfigurer;
import io.github.ascopes.jct.ex.JctJunitConfigurerException;
import io.github.ascopes.jct.junit.AbstractCompilersProvider;
+import io.github.ascopes.jct.junit.VersionStrategy;
import java.lang.reflect.InvocationTargetException;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
@@ -49,64 +50,6 @@
@DisplayName("AbstractCompilersProvider tests")
class AbstractCompilersProviderTest {
- @DisplayName("Configuring the provider with a version too low will use the minimum version")
- @Test
- void configuringTheProviderWithTooLowVersionWillUseTheMinimumVersion() {
- // Given
- var provider = new CompilersProviderImpl(8, 17);
-
- // When
- provider.configureInternals(5, 17);
- var compilers = provider.provideArguments(mock(ExtensionContext.class))
- .map(args -> (JctCompiler, ?>) args.get()[0])
- .collect(Collectors.toList());
-
- // Then
- assertThat(compilers)
- .as("compilers that were initialised (%s)", compilers)
- .hasSize(17 - 8 + 1);
-
- assertSoftly(softly -> {
- for (var i = 0; i < compilers.size(); ++i) {
- softly.assertThat(compilers)
- .as("compilers[%d]", i)
- .element(i)
- .as("compilers[%d].getRelease()", i)
- .extracting(JctCompiler::getRelease, STRING)
- .isEqualTo("%d", 8 + i);
- }
- });
- }
-
- @DisplayName("Configuring the provider with a version too high will use the maximum version")
- @Test
- void configuringTheProviderWithTooHighVersionWillUseTheMaximumVersion() {
- // Given
- var provider = new CompilersProviderImpl(8, 17);
-
- // When
- provider.configureInternals(8, 30);
- var compilers = provider.provideArguments(mock(ExtensionContext.class))
- .map(args -> (JctCompiler, ?>) args.get()[0])
- .collect(Collectors.toList());
-
- // Then
- assertThat(compilers)
- .as("compilers that were initialised (%s)", compilers)
- .hasSize(17 - 8 + 1);
-
- assertSoftly(softly -> {
- for (var i = 0; i < compilers.size(); ++i) {
- softly.assertThat(compilers)
- .as("compilers[%d]", i)
- .element(i)
- .as("compilers[%d].getRelease()", i)
- .extracting(JctCompiler::getRelease, STRING)
- .isEqualTo("%d", 8 + i);
- }
- });
- }
-
@DisplayName("Configuring the provider with a version below Java 8 will raise an exception")
@CsvSource({
"7, 12",
@@ -118,7 +61,7 @@ void configuringTheProviderWithPreJava8WillRaiseException(int min, int max) {
var provider = new CompilersProviderImpl(3, 17);
// Then
- assertThatThrownBy(() -> provider.configureInternals(min, max))
+ assertThatThrownBy(() -> provider.configureInternals(min, max, VersionStrategy.RELEASE))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Cannot use a Java version less than Java 8");
}
@@ -132,38 +75,91 @@ void configuringTheProviderWithMinAboveMaxWillRaiseException() {
var provider = new CompilersProviderImpl(5, 17);
// Then
- assertThatThrownBy(() -> provider.configureInternals(11, 10))
+ assertThatThrownBy(() -> provider.configureInternals(11, 10, VersionStrategy.RELEASE))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Cannot set min version to a version higher than the max version");
}
- @DisplayName("Configuring the provider with a valid version range will use that range")
+ @DisplayName("Configuring the provider with a null version strategy will raise an exception")
+ @SuppressWarnings("DataFlowIssue")
@Test
- void configuringTheProviderWithValidVersionRangeWillUseThatRange() {
+ void configuringTheProviderWithNullVersionStrategyWillRaiseException() {
// Given
var provider = new CompilersProviderImpl(8, 17);
+ // Then
+ assertThatThrownBy(() -> provider.configureInternals(10, 15, null))
+ .isInstanceOf(NullPointerException.class)
+ .hasMessage("versionStrategy");
+ }
+
+ @DisplayName("Configuring the provider with a version strategy uses that strategy")
+ @Test
+ void configuringTheProviderWithVersionStrategyUsesThatStrategy() {
+ // Given
+ var provider = new CompilersProviderImpl(8, 17);
+ var versionStrategy = mock(VersionStrategy.class);
+
// When
- provider.configureInternals(10, 15);
+ provider.configureInternals(10, 15, versionStrategy);
var compilers = provider.provideArguments(mock(ExtensionContext.class))
.map(args -> (JctCompiler, ?>) args.get()[0])
.collect(Collectors.toList());
// Then
- assertThat(compilers)
- .as("compilers that were initialised (%s)", compilers)
- .hasSize(6);
+ for (var i = 0; i < compilers.size(); ++i) {
+ var compiler = compilers.get(i);
+ var version = 10 + i;
+ verify(versionStrategy).configureCompiler(compiler, version);
+ }
- assertSoftly(softly -> {
- for (var i = 0; i < compilers.size(); ++i) {
- softly.assertThat(compilers)
- .as("compilers[%d]", i)
- .element(i)
- .as("compilers[%d].getRelease()", i)
- .extracting(JctCompiler::getRelease, STRING)
- .isEqualTo("%d", 10 + i);
- }
- });
+ verifyNoMoreInteractions(versionStrategy);
+ }
+
+ @DisplayName("Configuring the provider respects the minimum version bound")
+ @Test
+ void configuringTheProviderRespectsTheMinimumVersionBound() {
+ // Given
+ var provider = new CompilersProviderImpl(15, 17);
+ var versionStrategy = mock(VersionStrategy.class);
+
+ // When
+ provider.configureInternals(10, 17, versionStrategy);
+ var compilers = provider.provideArguments(mock(ExtensionContext.class))
+ .map(args -> (JctCompiler, ?>) args.get()[0])
+ .collect(Collectors.toList());
+
+ // Then
+ assertThat(compilers).hasSize(3);
+
+ for (var i = 0; i < compilers.size(); ++i) {
+ var compiler = compilers.get(i);
+ var version = 15 + i;
+ verify(versionStrategy).configureCompiler(compiler, version);
+ }
+ }
+
+ @DisplayName("Configuring the provider respects the maximum version bound")
+ @Test
+ void configuringTheProviderRespectsTheMaximumVersionBound() {
+ // Given
+ var provider = new CompilersProviderImpl(15, 17);
+ var versionStrategy = mock(VersionStrategy.class);
+
+ // When
+ provider.configureInternals(15, 20, versionStrategy);
+ var compilers = provider.provideArguments(mock(ExtensionContext.class))
+ .map(args -> (JctCompiler, ?>) args.get()[0])
+ .collect(Collectors.toList());
+
+ // Then
+ assertThat(compilers).hasSize(3);
+
+ for (var i = 0; i < compilers.size(); ++i) {
+ var compiler = compilers.get(i);
+ var version = 15 + i;
+ verify(versionStrategy).configureCompiler(compiler, version);
+ }
}
@DisplayName("Configuring the provider with configurers will initialise those configurers")
@@ -179,7 +175,8 @@ void configuringTheProviderWithConfigurersWillUseConfigurers() {
// When
provider.configureInternals(
- 10, 15, FooConfigurer.class, BarConfigurer.class, BazConfigurer.class
+ 10, 15, VersionStrategy.RELEASE,
+ FooConfigurer.class, BarConfigurer.class, BazConfigurer.class
);
var compilers = provider.provideArguments(mock(ExtensionContext.class))
.map(args -> (JctCompiler, ?>) args.get()[0])
@@ -234,7 +231,9 @@ void configurersThrowingTestAbortedExceptionInConstructorsWillPropagate() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, AbortedConstructorConfigurer.class);
+ provider.configureInternals(
+ 10, 15, VersionStrategy.RELEASE, AbortedConstructorConfigurer.class
+ );
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -255,7 +254,10 @@ void configurersThrowingTestAbortedExceptionWhenConfiguringWillPropagate() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, AbortedConfigureConfigurer.class);
+ provider.configureInternals(
+ 10, 15, VersionStrategy.RELEASE,
+ AbortedConfigureConfigurer.class
+ );
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -271,7 +273,9 @@ void configurersThrowingExceptionsInConstructorsWillPropagate() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, ThrowingConstructorConfigurer.class);
+ provider.configureInternals(
+ 10, 15, VersionStrategy.RELEASE, ThrowingConstructorConfigurer.class
+ );
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -292,7 +296,7 @@ void abstractConfigurersWillProduceExceptions() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, AbstractConfigurer.class);
+ provider.configureInternals(10, 15, VersionStrategy.RELEASE, AbstractConfigurer.class);
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -311,7 +315,9 @@ void configurersThrowingExceptionsWhenConfiguringWillPropagate() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, ThrowingConfigureConfigurer.class);
+ provider.configureInternals(
+ 10, 15, VersionStrategy.RELEASE, ThrowingConfigureConfigurer.class
+ );
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -332,7 +338,9 @@ void configurersWithNonDefaultConstructorsWillProduceExceptions() {
var provider = new CompilersProviderImpl(8, 17);
// When
- provider.configureInternals(10, 15, NonDefaultConstructorConfigurer.class);
+ provider.configureInternals(
+ 10, 15, VersionStrategy.RELEASE, NonDefaultConstructorConfigurer.class
+ );
// Then
assertThatThrownBy(() -> provider.provideArguments(mock(ExtensionContext.class)).toArray())
@@ -362,20 +370,17 @@ public CompilersProviderImpl(int minSupportedVersion, int maxSupportedVersion) {
final void configureInternals(
int min,
int max,
+ VersionStrategy versionStrategy,
Class extends JctCompilerConfigurer>>... configurerClasses
) {
- configure(min, max, false, configurerClasses);
+ configure(min, max, false, configurerClasses, versionStrategy);
}
@Override
- protected JctCompiler, ?> compilerForVersion(int release) {
- var mock = mockRaw(JctCompiler.class)
+ protected JctCompiler, ?> initializeNewCompiler() {
+ return mockRaw(JctCompiler.class)
.>upcastedTo()
- .build();
-
- when(mock.getRelease()).thenReturn(Integer.toString(release));
-
- return mock;
+ .build(withSettings().name("mock compiler"));
}
@Override
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/JavacCompilersProviderTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/JavacCompilersProviderTest.java
index ffe4dd78c..16707264c 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/JavacCompilersProviderTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/JavacCompilersProviderTest.java
@@ -28,6 +28,7 @@
import io.github.ascopes.jct.compilers.javac.JavacJctCompilerImpl;
import io.github.ascopes.jct.junit.JavacCompilerTest;
import io.github.ascopes.jct.junit.JavacCompilersProvider;
+import io.github.ascopes.jct.junit.VersionStrategy;
import java.lang.reflect.AnnotatedElement;
import java.util.stream.Collectors;
import org.junit.jupiter.api.DisplayName;
@@ -69,7 +70,7 @@ void providerUsesTheUserProvidedVersionRangesWhenValid(boolean modules) {
var compiler = compilers.get(i);
softly.assertThat(compiler.getName())
.as("compilers[%d].getName()", i)
- .isEqualTo("javac release %d", 10 + i);
+ .isEqualTo("JDK Compiler (release = Java %d)", 10 + i);
softly.assertThat(compiler.getRelease())
.as("compilers[%d].getRelease()", i)
.isEqualTo("%d", 10 + i);
@@ -106,7 +107,7 @@ void providerUsesTheMinCompilerVersionAllowedIfExceeded(boolean modules) {
var compiler = compilers.get(i);
softly.assertThat(compiler.getName())
.as("compilers[%d].getName()", i)
- .isEqualTo("javac release %d", 8 + i);
+ .isEqualTo("JDK Compiler (release = Java %d)", 8 + i);
softly.assertThat(compiler.getRelease())
.as("compilers[%d].getRelease()", i)
.isEqualTo("%d", 8 + i);
@@ -143,7 +144,7 @@ void providerUsesTheMaxCompilerVersionAllowedIfExceeded(boolean modules) {
var compiler = compilers.get(i);
softly.assertThat(compiler.getName())
.as("compilers[%d].getName()", i)
- .isEqualTo("javac release %d", 10 + i);
+ .isEqualTo("JDK Compiler (release = Java %d)", 10 + i);
softly.assertThat(compiler.getRelease())
.as("compilers[%d].getRelease()", i)
.isEqualTo("%d", 10 + i);
@@ -164,6 +165,7 @@ final JavacCompilerTest someAnnotation(
when(annotation.maxVersion()).thenReturn(max);
when(annotation.modules()).thenReturn(modules);
when(annotation.configurers()).thenReturn(configurers);
+ when(annotation.versionStrategy()).thenReturn(VersionStrategy.RELEASE);
when(annotation.annotationType()).thenAnswer(ctx -> JavacCompilerTest.class);
return annotation;
}
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/VersionStrategyTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/VersionStrategyTest.java
new file mode 100644
index 000000000..e4fa31df4
--- /dev/null
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/junit/VersionStrategyTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.tests.unit.junit;
+
+import static io.github.ascopes.jct.tests.helpers.Fixtures.someText;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import io.github.ascopes.jct.compilers.JctCompiler;
+import io.github.ascopes.jct.junit.VersionStrategy;
+import io.github.ascopes.jct.tests.helpers.Fixtures;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.Mock.Strictness;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+/**
+ * {@link VersionStrategy} tests.
+ *
+ * @author Ashley Scopes
+ */
+@DisplayName("VersionStrategy tests")
+@ExtendWith(MockitoExtension.class)
+class VersionStrategyTest {
+ String baseName;
+
+ @Mock(answer = Answers.RETURNS_SELF, strictness = Strictness.LENIENT)
+ JctCompiler, ?> compiler;
+
+ @BeforeEach
+ void setUp() {
+ baseName = someText();
+ when(compiler.getName()).thenReturn(baseName);
+ }
+
+ @DisplayName("RELEASE sets the release")
+ @ValueSource(ints = {10, 15, 20})
+ @ParameterizedTest(name = "for version {0}")
+ void releaseSetsTheRelease(int version) {
+ // When
+ VersionStrategy.RELEASE.configureCompiler(compiler, version);
+
+ // Then
+ verify(compiler).release(version);
+ verify(compiler).getName();
+ verify(compiler).name(baseName + " (release = Java " + version + ")");
+ verifyNoMoreInteractions(compiler);
+ }
+
+ @DisplayName("SOURCE sets the source")
+ @ValueSource(ints = {10, 15, 20})
+ @ParameterizedTest(name = "for version {0}")
+ void sourceSetsTheSource(int version) {
+ // When
+ VersionStrategy.SOURCE.configureCompiler(compiler, version);
+
+ // Then
+ verify(compiler).source(version);
+ verify(compiler).getName();
+ verify(compiler).name(baseName + " (source = Java " + version + ")");
+ verifyNoMoreInteractions(compiler);
+ }
+
+ @DisplayName("TARGET sets the target")
+ @ValueSource(ints = {10, 15, 20})
+ @ParameterizedTest(name = "for version {0}")
+ void targetSetsTheTarget(int version) {
+ // When
+ VersionStrategy.TARGET.configureCompiler(compiler, version);
+
+ // Then
+ verify(compiler).target(version);
+ verify(compiler).getName();
+ verify(compiler).name(baseName + " (target = Java " + version + ")");
+ verifyNoMoreInteractions(compiler);
+ }
+
+ @DisplayName("SOURCE_AND_TARGET sets the target")
+ @ValueSource(ints = {10, 15, 20})
+ @ParameterizedTest(name = "for version {0}")
+ void sourceAndTargetSetsTheSourceAndTarget(int version) {
+ // When
+ VersionStrategy.SOURCE_AND_TARGET.configureCompiler(compiler, version);
+
+ // Then
+ verify(compiler).source(version);
+ verify(compiler).target(version);
+ verify(compiler).getName();
+ verify(compiler).name(baseName + " (source and target = Java " + version + ")");
+ verifyNoMoreInteractions(compiler);
+ }
+}