diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverter.java deleted file mode 100644 index 79f0028e58a6..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverter.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import static org.junit.platform.commons.util.ReflectionUtils.HierarchyTraversalMode.BOTTOM_UP; -import static org.junit.platform.commons.util.ReflectionUtils.findConstructors; -import static org.junit.platform.commons.util.ReflectionUtils.findMethods; -import static org.junit.platform.commons.util.ReflectionUtils.invokeMethod; -import static org.junit.platform.commons.util.ReflectionUtils.isNotPrivate; -import static org.junit.platform.commons.util.ReflectionUtils.isNotStatic; -import static org.junit.platform.commons.util.ReflectionUtils.newInstance; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.Method; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; - -import org.junit.platform.commons.util.Preconditions; - -/** - * {@code FallbackStringToObjectConverter} is a {@link StringToObjectConverter} - * that provides a fallback conversion strategy for converting from a - * {@link String} to a given target type by invoking a static factory method - * or factory constructor defined in the target type. - * - *

Search Algorithm

- * - *
    - *
  1. Search for a single, non-private static factory method in the target - * type that converts from a String to the target type. Use the factory method - * if present.
  2. - *
  3. Search for a single, non-private constructor in the target type that - * accepts a String. Use the constructor if present.
  4. - *
- * - *

If multiple suitable factory methods are discovered they will be ignored. - * If neither a single factory method nor a single constructor is found, this - * converter acts as a no-op. - * - * @since 5.1 - * @see DefaultArgumentConverter - */ -class FallbackStringToObjectConverter implements StringToObjectConverter { - - /** - * Implementation of the NULL Object Pattern. - */ - private static final Function NULL_EXECUTABLE = source -> source; - - /** - * Cache for factory methods and factory constructors. - * - *

Searches that do not find a factory method or constructor are tracked - * by the presence of a {@link #NULL_EXECUTABLE} object stored in the map. - * This prevents the framework from repeatedly searching for things which - * are already known not to exist. - */ - private static final ConcurrentHashMap, Function> factoryExecutableCache // - = new ConcurrentHashMap<>(64); - - @Override - public boolean canConvert(Class targetType) { - return findFactoryExecutable(targetType) != NULL_EXECUTABLE; - } - - @Override - public Object convert(String source, Class targetType) throws Exception { - Function executable = findFactoryExecutable(targetType); - Preconditions.condition(executable != NULL_EXECUTABLE, - "Illegal state: convert() must not be called if canConvert() returned false"); - - return executable.apply(source); - } - - private static Function findFactoryExecutable(Class targetType) { - return factoryExecutableCache.computeIfAbsent(targetType, type -> { - Method factoryMethod = findFactoryMethod(type); - if (factoryMethod != null) { - return source -> invokeMethod(factoryMethod, null, source); - } - Constructor constructor = findFactoryConstructor(type); - if (constructor != null) { - return source -> newInstance(constructor, source); - } - return NULL_EXECUTABLE; - }); - } - - private static Method findFactoryMethod(Class targetType) { - List factoryMethods = findMethods(targetType, new IsFactoryMethod(targetType), BOTTOM_UP); - if (factoryMethods.size() == 1) { - return factoryMethods.get(0); - } - return null; - } - - private static Constructor findFactoryConstructor(Class targetType) { - List> constructors = findConstructors(targetType, new IsFactoryConstructor(targetType)); - if (constructors.size() == 1) { - return constructors.get(0); - } - return null; - } - - /** - * {@link Predicate} that determines if the {@link Method} supplied to - * {@link #test(Method)} is a non-private static factory method for the - * supplied {@link #targetType}. - */ - static class IsFactoryMethod implements Predicate { - - private final Class targetType; - - IsFactoryMethod(Class targetType) { - this.targetType = targetType; - } - - @Override - public boolean test(Method method) { - // Please do not collapse the following into a single statement. - if (!method.getReturnType().equals(this.targetType)) { - return false; - } - if (isNotStatic(method)) { - return false; - } - return isNotPrivateAndAcceptsSingleStringArgument(method); - } - - } - - /** - * {@link Predicate} that determines if the {@link Constructor} supplied to - * {@link #test(Constructor)} is a non-private factory constructor for the - * supplied {@link #targetType}. - */ - static class IsFactoryConstructor implements Predicate> { - - private final Class targetType; - - IsFactoryConstructor(Class targetType) { - this.targetType = targetType; - } - - @Override - public boolean test(Constructor constructor) { - // Please do not collapse the following into a single statement. - if (!constructor.getDeclaringClass().equals(this.targetType)) { - return false; - } - return isNotPrivateAndAcceptsSingleStringArgument(constructor); - } - - } - - private static boolean isNotPrivateAndAcceptsSingleStringArgument(Executable executable) { - return isNotPrivate(executable) // - && (executable.getParameterCount() == 1) // - && (executable.getParameterTypes()[0] == String.class); - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToBooleanConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToBooleanConverter.java deleted file mode 100644 index 9d911825809b..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToBooleanConverter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import org.junit.platform.commons.util.Preconditions; - -class StringToBooleanConverter implements StringToObjectConverter { - - @Override - public boolean canConvert(Class targetType) { - return targetType == Boolean.class; - } - - @Override - public Object convert(String source, Class targetType) { - boolean isTrue = "true".equalsIgnoreCase(source); - Preconditions.condition(isTrue || "false".equalsIgnoreCase(source), - () -> "String must be 'true' or 'false' (ignoring case): " + source); - return isTrue; - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCharacterConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCharacterConverter.java deleted file mode 100644 index b3849051e45d..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCharacterConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import org.junit.platform.commons.util.Preconditions; - -class StringToCharacterConverter implements StringToObjectConverter { - - @Override - public boolean canConvert(Class targetType) { - return targetType == Character.class; - } - - @Override - public Object convert(String source, Class targetType) { - Preconditions.condition(source.length() == 1, () -> "String must have length of 1: " + source); - return source.charAt(0); - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToClassConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToClassConverter.java deleted file mode 100644 index debefc342ed0..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToClassConverter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import org.junit.platform.commons.util.ReflectionUtils; - -class StringToClassConverter implements StringToObjectConverter { - - @Override - public boolean canConvert(Class targetType) { - return targetType == Class.class; - } - - @Override - public Object convert(String source, Class targetType) throws Exception { - throw new UnsupportedOperationException("Invoke convert(String, Class, ClassLoader) instead"); - } - - @Override - public Object convert(String className, Class targetType, ClassLoader classLoader) throws Exception { - // @formatter:off - return ReflectionUtils.tryToLoadClass(className, classLoader) - .getOrThrow(cause -> new ArgumentConversionException( - "Failed to convert String \"" + className + "\" to type java.lang.Class", cause)); - // @formatter:on - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCommonJavaTypesConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCommonJavaTypesConverter.java deleted file mode 100644 index b9ac124aded8..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToCommonJavaTypesConverter.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import static java.util.Collections.unmodifiableMap; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Currency; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; -import java.util.function.Function; - -class StringToCommonJavaTypesConverter implements StringToObjectConverter { - - private static final Map, Function> CONVERTERS; - - static { - Map, Function> converters = new HashMap<>(); - - // java.io and java.nio - converters.put(File.class, File::new); - converters.put(Charset.class, Charset::forName); - converters.put(Path.class, Paths::get); - // java.net - converters.put(URI.class, URI::create); - converters.put(URL.class, StringToCommonJavaTypesConverter::toURL); - // java.util - converters.put(Currency.class, Currency::getInstance); - converters.put(Locale.class, Locale::new); - converters.put(UUID.class, UUID::fromString); - - CONVERTERS = unmodifiableMap(converters); - } - - @Override - public boolean canConvert(Class targetType) { - return CONVERTERS.containsKey(targetType); - } - - @Override - public Object convert(String source, Class targetType) throws Exception { - return CONVERTERS.get(targetType).apply(source); - } - - private static URL toURL(String url) { - try { - return URI.create(url).toURL(); - } - catch (MalformedURLException ex) { - throw new ArgumentConversionException("Failed to convert String \"" + url + "\" to type java.net.URL", ex); - } - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToEnumConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToEnumConverter.java deleted file mode 100644 index f20d1487d5ee..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToEnumConverter.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -class StringToEnumConverter implements StringToObjectConverter { - - @Override - public boolean canConvert(Class targetType) { - return targetType.isEnum(); - } - - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Object convert(String source, Class targetType) throws Exception { - return Enum.valueOf(targetType, source); - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToJavaTimeConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToJavaTimeConverter.java deleted file mode 100644 index b1851ecc323d..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToJavaTimeConverter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import static java.util.Collections.unmodifiableMap; - -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.MonthDay; -import java.time.OffsetDateTime; -import java.time.OffsetTime; -import java.time.Period; -import java.time.Year; -import java.time.YearMonth; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -class StringToJavaTimeConverter implements StringToObjectConverter { - - private static final Map, Function> CONVERTERS; - static { - Map, Function> converters = new HashMap<>(); - converters.put(Duration.class, Duration::parse); - converters.put(Instant.class, Instant::parse); - converters.put(LocalDate.class, LocalDate::parse); - converters.put(LocalDateTime.class, LocalDateTime::parse); - converters.put(LocalTime.class, LocalTime::parse); - converters.put(MonthDay.class, MonthDay::parse); - converters.put(OffsetDateTime.class, OffsetDateTime::parse); - converters.put(OffsetTime.class, OffsetTime::parse); - converters.put(Period.class, Period::parse); - converters.put(Year.class, Year::parse); - converters.put(YearMonth.class, YearMonth::parse); - converters.put(ZonedDateTime.class, ZonedDateTime::parse); - converters.put(ZoneId.class, ZoneId::of); - converters.put(ZoneOffset.class, ZoneOffset::of); - CONVERTERS = unmodifiableMap(converters); - } - - @Override - public boolean canConvert(Class targetType) { - return CONVERTERS.containsKey(targetType); - } - - @Override - public Object convert(String source, Class targetType) throws Exception { - return CONVERTERS.get(targetType).apply(source); - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToNumberConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToNumberConverter.java deleted file mode 100644 index ca278019a488..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToNumberConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -import static java.util.Collections.unmodifiableMap; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Function; - -class StringToNumberConverter implements StringToObjectConverter { - - private static final Map, Function> CONVERTERS; - static { - Map, Function> converters = new HashMap<>(); - converters.put(Byte.class, Byte::decode); - converters.put(Short.class, Short::decode); - converters.put(Integer.class, Integer::decode); - converters.put(Long.class, Long::decode); - converters.put(Float.class, Float::valueOf); - converters.put(Double.class, Double::valueOf); - // Technically, BigInteger and BigDecimal constructors are covered by - // FallbackStringToObjectConverter, but we have explicit conversion - // configured for them anyway. - converters.put(BigInteger.class, BigInteger::new); - converters.put(BigDecimal.class, BigDecimal::new); - CONVERTERS = unmodifiableMap(converters); - } - - @Override - public boolean canConvert(Class targetType) { - return CONVERTERS.containsKey(targetType); - } - - @Override - public Object convert(String source, Class targetType) { - return CONVERTERS.get(targetType).apply(source.replace("_", "")); - } - -} diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToObjectConverter.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToObjectConverter.java deleted file mode 100644 index 2a60202dba81..000000000000 --- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/converter/StringToObjectConverter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015-2023 the original author or authors. - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v2.0 which - * accompanies this distribution and is available at - * - * https://www.eclipse.org/legal/epl-v20.html - */ - -package org.junit.jupiter.params.converter; - -/** - * Internal API for converting arguments of type {@link String} to a specified - * target type. - */ -interface StringToObjectConverter { - - /** - * Determine if this converter can convert from a {@link String} to the - * supplied target type (which is guaranteed to be a wrapper type for - * primitives — for example, {@link Integer} instead of {@code int}). - */ - boolean canConvert(Class targetType); - - /** - * Convert the supplied {@link String} to the supplied target type (which is - * guaranteed to be a wrapper type for primitives — for example, - * {@link Integer} instead of {@code int}). - */ - Object convert(String source, Class targetType) throws Exception; - - /** - * Convert the supplied {@link String} to the supplied target type (which is - * guaranteed to be a wrapper type for primitives — for example, - * {@link Integer} instead of {@code int}). - * - *

The default implementation simply delegates to {@link #convert(String, Class)}. - * Can be overridden by concrete implementations of this interface that need - * access to the supplied {@link ClassLoader}. - */ - default Object convert(String source, Class targetType, ClassLoader classLoader) throws Exception { - return convert(source, targetType); - } - -} diff --git a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverterTests.java b/platform-tests/src/test/java/org/junit/platform/commons/support/conversion/FallbackStringToObjectConverterTests.java similarity index 95% rename from junit-jupiter-params/src/test/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverterTests.java rename to platform-tests/src/test/java/org/junit/platform/commons/support/conversion/FallbackStringToObjectConverterTests.java index 1d2cd21a6fdf..efc98701df7d 100644 --- a/junit-jupiter-params/src/test/java/org/junit/jupiter/params/converter/FallbackStringToObjectConverterTests.java +++ b/platform-tests/src/test/java/org/junit/platform/commons/support/conversion/FallbackStringToObjectConverterTests.java @@ -8,7 +8,7 @@ * 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.junit.platform.commons.util.ReflectionUtils.findMethod; @@ -19,15 +19,15 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.converter.FallbackStringToObjectConverter.IsFactoryConstructor; -import org.junit.jupiter.params.converter.FallbackStringToObjectConverter.IsFactoryMethod; +import org.junit.platform.commons.support.conversion.FallbackStringToObjectConverter.IsFactoryConstructor; +import org.junit.platform.commons.support.conversion.FallbackStringToObjectConverter.IsFactoryMethod; import org.junit.platform.commons.util.ReflectionUtils; /** * Unit tests for {@link FallbackStringToObjectConverter}, {@link IsFactoryMethod}, * and {@link IsFactoryConstructor}. * - * @since 5.1 + * @since 1.11 (originally since JUnit Jupiter 5.1) */ class FallbackStringToObjectConverterTests {