Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move string-based argument conversion tests to platform-test #4305

Merged
merged 1 commit into from
Feb 12, 2025

Conversation

scordio
Copy link
Contributor

@scordio scordio commented Feb 9, 2025

Overview

Prior to this commit, platform-tests had no dedicated tests for ConversionSupport. Instead, DefaultArgumentConverterTests from jupiter-tests provided the corresponding coverage.

Now, string-based tests are moved to ConversionSupportTests, while DefaultArgumentConverterTests verify that the delegation to ConversionSupport happens correctly.

See #4219 (comment).

For an easier review, here's the diff between DefaultArgumentConverterTests from main and ConversionSupportTests from this PR:

Diff

--- jupiter-tests/src/test/java/org/junit/jupiter/params/converter/DefaultArgumentConverterTests.java	2025-02-09 16:22:11
+++ platform-tests/src/test/java/org/junit/platform/commons/support/conversion/ConversionSupportTests.java	2025-02-09 17:34:21
@@ -8,15 +8,12 @@
  * https://www.eclipse.org/legal/epl-v20.html
  */
 
-package org.junit.jupiter.params.converter;
+package org.junit.platform.commons.support.conversion;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 import java.io.File;
-import java.lang.Thread.State;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -46,18 +43,18 @@
 import java.util.concurrent.TimeUnit;
 
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ParameterContext;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 import org.junit.platform.commons.support.ReflectionSupport;
 import org.junit.platform.commons.test.TestClassLoader;
+import org.junit.platform.commons.util.ClassLoaderUtils;
 
 /**
- * Unit tests for {@link DefaultArgumentConverter}.
+ * Unit tests for {@link ConversionSupport}.
  *
- * @since 5.0
+ * @since 5.12
  */
-class DefaultArgumentConverterTests {
+class ConversionSupportTests {
 
 	@Test
 	void isAwareOfNull() {
@@ -67,32 +64,6 @@
 	}
 
 	@Test
-	void isAwareOfWrapperTypesForPrimitiveTypes() {
-		assertConverts(true, boolean.class, true);
-		assertConverts(false, boolean.class, false);
-		assertConverts((byte) 1, byte.class, (byte) 1);
-		assertConverts('o', char.class, 'o');
-		assertConverts((short) 1, short.class, (short) 1);
-		assertConverts(1, int.class, 1);
-		assertConverts(1L, long.class, 1L);
-		assertConverts(1.0f, float.class, 1.0f);
-		assertConverts(1.0d, double.class, 1.0d);
-	}
-
-	@Test
-	void isAwareOfWideningConversions() {
-		assertConverts((byte) 1, short.class, (byte) 1);
-		assertConverts((short) 1, int.class, (short) 1);
-		assertConverts((char) 1, int.class, (char) 1);
-		assertConverts((byte) 1, long.class, (byte) 1);
-		assertConverts(1, long.class, 1);
-		assertConverts((char) 1, float.class, (char) 1);
-		assertConverts(1, float.class, 1);
-		assertConverts(1L, double.class, 1L);
-		assertConverts(1.0f, double.class, 1.0f);
-	}
-
-	@Test
 	void convertsStringsToPrimitiveTypes() {
 		assertConverts("true", boolean.class, true);
 		assertConverts("false", boolean.class, false);
@@ -134,7 +105,7 @@
 	@ValueSource(classes = { char.class, boolean.class, short.class, byte.class, int.class, long.class, float.class,
 			double.class, void.class })
 	void throwsExceptionForNullToPrimitiveTypeConversion(Class<?> type) {
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert(null, type)) //
 				.withMessage("Cannot convert null to primitive value of type " + type.getCanonicalName());
 	}
@@ -143,67 +114,47 @@
 	@ValueSource(classes = { Boolean.class, Character.class, Short.class, Byte.class, Integer.class, Long.class,
 			Float.class, Double.class })
 	void throwsExceptionWhenConvertingTheWordNullToPrimitiveWrapperType(Class<?> type) {
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("null", type)) //
 				.withMessage("Failed to convert String \"null\" to type " + type.getCanonicalName());
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("NULL", type)) //
 				.withMessage("Failed to convert String \"NULL\" to type " + type.getCanonicalName());
 	}
 
 	@Test
 	void throwsExceptionOnInvalidStringForPrimitiveTypes() {
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("ab", char.class)) //
 				.withMessage("Failed to convert String \"ab\" to type char") //
 				.havingCause() //
-				.havingCause() //
 				.withMessage("String must have length of 1: ab");
 
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("tru", boolean.class)) //
 				.withMessage("Failed to convert String \"tru\" to type boolean") //
 				.havingCause() //
-				.havingCause() //
 				.withMessage("String must be 'true' or 'false' (ignoring case): tru");
 
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("null", boolean.class)) //
 				.withMessage("Failed to convert String \"null\" to type boolean") //
 				.havingCause() //
-				.havingCause() //
 				.withMessage("String must be 'true' or 'false' (ignoring case): null");
 
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("NULL", boolean.class)) //
 				.withMessage("Failed to convert String \"NULL\" to type boolean") //
 				.havingCause() //
-				.havingCause() //
 				.withMessage("String must be 'true' or 'false' (ignoring case): NULL");
 	}
 
 	@Test
 	void throwsExceptionWhenImplicitConversionIsUnsupported() {
-		assertThatExceptionOfType(ArgumentConversionException.class) //
+		assertThatExceptionOfType(ConversionException.class) //
 				.isThrownBy(() -> convert("foo", Enigma.class)) //
 				.withMessage("No built-in converter for source type java.lang.String and target type %s",
 					Enigma.class.getName());
-
-		assertThatExceptionOfType(ArgumentConversionException.class) //
-				.isThrownBy(() -> convert(new Enigma(), int[].class)) //
-				.withMessage("No built-in converter for source type %s and target type int[]", Enigma.class.getName());
-
-		assertThatExceptionOfType(ArgumentConversionException.class) //
-				.isThrownBy(() -> convert(new long[] {}, int[].class)) //
-				.withMessage("No built-in converter for source type long[] and target type int[]");
-
-		assertThatExceptionOfType(ArgumentConversionException.class) //
-				.isThrownBy(() -> convert(new String[] {}, boolean.class)) //
-				.withMessage("No built-in converter for source type java.lang.String[] and target type boolean");
-
-		assertThatExceptionOfType(ArgumentConversionException.class) //
-				.isThrownBy(() -> convert(Class.class, int[].class)) //
-				.withMessage("No built-in converter for source type java.lang.Class and target type int[]");
 	}
 
 	/**
@@ -262,7 +213,7 @@
 	void convertsStringToClass() {
 		assertConverts("java.lang.Integer", Class.class, Integer.class);
 		assertConverts("java.lang.Void", Class.class, Void.class);
-		assertConverts("java.lang.Thread$State", Class.class, State.class);
+		assertConverts("java.lang.Thread$State", Class.class, Thread.State.class);
 		assertConverts("byte", Class.class, byte.class);
 		assertConverts("void", Class.class, void.class);
 		assertConverts("char[]", Class.class, char[].class);
@@ -281,7 +232,7 @@
 			var declaringExecutable = ReflectionSupport.findMethod(customType, "foo").get();
 			assertThat(declaringExecutable.getDeclaringClass().getClassLoader()).isSameAs(testClassLoader);
 
-			var clazz = (Class<?>) convert(customTypeName, Class.class, parameterContext(declaringExecutable));
+			var clazz = (Class<?>) convert(customTypeName, Class.class, classLoader(declaringExecutable));
 			assertThat(clazz).isNotEqualTo(Enigma.class);
 			assertThat(clazz).isEqualTo(customType);
 			assertThat(clazz.getClassLoader()).isSameAs(testClassLoader);
@@ -358,7 +309,7 @@
 
 	// -------------------------------------------------------------------------
 
-	private void assertConverts(Object input, Class<?> targetClass, Object expectedOutput) {
+	private void assertConverts(String input, Class<?> targetClass, Object expectedOutput) {
 		var result = convert(input, targetClass);
 
 		assertThat(result) //
@@ -366,23 +317,21 @@
 				.isEqualTo(expectedOutput);
 	}
 
-	private Object convert(Object input, Class<?> targetClass) {
-		return convert(input, targetClass, parameterContext());
+	private Object convert(String input, Class<?> targetClass) {
+		return convert(input, targetClass, classLoader());
 	}
 
-	private Object convert(Object input, Class<?> targetClass, ParameterContext parameterContext) {
-		return DefaultArgumentConverter.INSTANCE.convert(input, targetClass, parameterContext);
+	private Object convert(String input, Class<?> targetClass, ClassLoader classLoader) {
+		return ConversionSupport.convert(input, targetClass, classLoader);
 	}
 
-	private static ParameterContext parameterContext() {
-		Method declaringExecutable = ReflectionSupport.findMethod(DefaultArgumentConverterTests.class, "foo").get();
-		return parameterContext(declaringExecutable);
+	private static ClassLoader classLoader() {
+		Method declaringExecutable = ReflectionSupport.findMethod(ConversionSupportTests.class, "foo").get();
+		return classLoader(declaringExecutable);
 	}
 
-	private static ParameterContext parameterContext(Method declaringExecutable) {
-		ParameterContext parameterContext = mock();
-		when(parameterContext.getDeclaringExecutable()).thenReturn(declaringExecutable);
-		return parameterContext;
+	private static ClassLoader classLoader(Method declaringExecutable) {
+		return ClassLoaderUtils.getClassLoader(declaringExecutable.getDeclaringClass());
 	}
 
 	@SuppressWarnings("unused")


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

@scordio
Copy link
Contributor Author

scordio commented Feb 9, 2025

DefaultArgumentConverterTests still has a lot of duplicated test cases.

What if I wrap this invocation in a package-private method:

return ConversionSupport.convert((String) source, targetType, classLoader);

and I use Mockito to verify the delegation, cleaning up all the equivalent test cases from DefaultArgumentConverterTests?

@marcphilipp
Copy link
Member

and I use Mockito to verify the delegation, cleaning up all the equivalent test cases from DefaultArgumentConverterTests?

SGTM 👍

@scordio scordio force-pushed the conversion-support-testing branch 2 times, most recently from fe36544 to afe8ec1 Compare February 12, 2025 13:08
Prior to this commit, `platform-tests` had no dedicated tests for
`ConversionSupport`. Instead, `DefaultArgumentConverterTests` from
`jupiter-tests` provided the corresponding coverage.

Now, string-based tests are moved to `ConversionSupportTests`, while
`DefaultArgumentConverterTests` verify that the delegation to
`ConversionSupport` happens correctly.
@scordio scordio force-pushed the conversion-support-testing branch from afe8ec1 to 0e5b639 Compare February 12, 2025 13:22
@scordio scordio marked this pull request as ready for review February 12, 2025 13:23
@marcphilipp marcphilipp merged commit 779a46f into junit-team:main Feb 12, 2025
15 checks passed
@marcphilipp
Copy link
Member

Thanks, @scordio! 👍

@scordio scordio deleted the conversion-support-testing branch February 12, 2025 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants