Skip to content

Commit f5b43ce

Browse files
authored
Make targetType parameter easier to use with class literals (#5106)
Resolves #5105.
1 parent 984c0c4 commit f5b43ce

File tree

6 files changed

+52
-2
lines changed

6 files changed

+52
-2
lines changed

documentation/src/docs/asciidoc/release-notes/release-notes-6.0.1.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ repository on GitHub.
6060
a custom comment character using the new `commentCharacter` attribute.
6161
* Improve error message when using `@ParameterizedClass` with field injection and not
6262
providing enough arguments.
63+
* Allow calling `TypedArgumentConverter` constructor for `@Nullable T` target types
64+
without having to cast class literals to `Class<@Nullable T>`.
6365

6466

6567
[[release-notes-6.0.1-junit-vintage]]

junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/TypedArgumentConverter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static org.apiguardian.api.API.Status.STABLE;
1414

1515
import org.apiguardian.api.API;
16+
import org.jspecify.annotations.NonNull;
1617
import org.jspecify.annotations.Nullable;
1718
import org.junit.jupiter.api.extension.ParameterContext;
1819
import org.junit.jupiter.params.support.FieldContext;
@@ -43,7 +44,8 @@ public abstract class TypedArgumentConverter<S, T extends @Nullable Object> impl
4344
* @param targetType the type of the target object to create from the source;
4445
* never {@code null}
4546
*/
46-
protected TypedArgumentConverter(Class<S> sourceType, Class<T> targetType) {
47+
protected TypedArgumentConverter(Class<S> sourceType,
48+
@SuppressWarnings("NullableProblems") Class<@NonNull T> targetType) {
4749
this.sourceType = Preconditions.notNull(sourceType, "sourceType must not be null");
4850
this.targetType = Preconditions.notNull(targetType, "targetType must not be null");
4951
}

jupiter-tests/src/test/java/org/junit/jupiter/params/ParameterizedClassIntegrationTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import java.util.stream.Stream;
5858

5959
import org.assertj.core.api.Condition;
60+
import org.jspecify.annotations.NullMarked;
6061
import org.jspecify.annotations.Nullable;
6162
import org.junit.jupiter.api.AfterAll;
6263
import org.junit.jupiter.api.AfterEach;
@@ -972,7 +973,8 @@ void test2() {
972973
}
973974
}
974975

975-
private static class CustomIntegerToStringConverter extends TypedArgumentConverter<Integer, String> {
976+
@NullMarked
977+
private static class CustomIntegerToStringConverter extends TypedArgumentConverter<Integer, @Nullable String> {
976978

977979
CustomIntegerToStringConverter() {
978980
super(Integer.class, String.class);

jupiter-tests/src/test/java/org/junit/jupiter/params/ParameterizedTestIntegrationTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import java.util.function.Supplier;
6464
import java.util.stream.Stream;
6565

66+
import org.jspecify.annotations.NullMarked;
6667
import org.jspecify.annotations.Nullable;
6768
import org.junit.jupiter.api.AfterAll;
6869
import org.junit.jupiter.api.AfterEach;
@@ -2629,6 +2630,7 @@ void testWithIso639(@ConvertWith(Iso639Converter.class) Locale locale) {
26292630
assertEquals("", locale.getCountry());
26302631
}
26312632

2633+
@NullMarked
26322634
static class Iso639Converter extends TypedArgumentConverter<String, Locale> {
26332635

26342636
Iso639Converter() {

jupiter-tests/src/test/java/org/junit/jupiter/params/converter/TypedArgumentConverterTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.lang.reflect.Method;
2525
import java.lang.reflect.Parameter;
2626

27+
import org.jspecify.annotations.NullMarked;
2728
import org.jspecify.annotations.Nullable;
2829
import org.junit.jupiter.api.Nested;
2930
import org.junit.jupiter.api.Test;
@@ -203,6 +204,7 @@ void stringToPrimitiveLong(@StringLength long length) {
203204
private @interface StringLength {
204205
}
205206

207+
@NullMarked
206208
private static class StringLengthArgumentConverter extends TypedArgumentConverter<String, Integer> {
207209

208210
StringLengthArgumentConverter() {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2015-2025 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
package org.junit.jupiter.params.converter
11+
12+
import org.junit.jupiter.api.Assertions.assertEquals
13+
import org.junit.jupiter.api.Test
14+
import org.junit.jupiter.api.assertNull
15+
import org.junit.jupiter.api.extension.ParameterContext
16+
import org.mockito.Mockito.mock
17+
import org.mockito.Mockito.`when`
18+
19+
class TypedArgumentConverterKotlinTests {
20+
@Test
21+
fun converts() {
22+
val parameterContext = mock(ParameterContext::class.java)
23+
val parameter = this.javaClass.getDeclaredMethod("foo", String::class.java).parameters[0]
24+
`when`(parameterContext.parameter).thenReturn(parameter)
25+
26+
assertNull(NullableTypeConverter().convert(null, parameterContext))
27+
assertEquals("null", NonNullableTypeConverter().convert(null, parameterContext))
28+
}
29+
30+
@Suppress("unused")
31+
private fun foo(param: String) = Unit
32+
33+
class NullableTypeConverter : TypedArgumentConverter<String, String?>(String::class.java, String::class.java) {
34+
override fun convert(source: String?) = source
35+
}
36+
37+
class NonNullableTypeConverter : TypedArgumentConverter<String, String>(String::class.java, String::class.java) {
38+
override fun convert(source: String?) = source.toString()
39+
}
40+
}

0 commit comments

Comments
 (0)