|
48 | 48 | import org.junit.jupiter.api.Test;
|
49 | 49 |
|
50 | 50 | import org.springframework.core.MethodParameter;
|
| 51 | +import org.springframework.core.ResolvableType; |
51 | 52 | import org.springframework.core.convert.ConversionFailedException;
|
52 | 53 | import org.springframework.core.convert.ConverterNotFoundException;
|
53 | 54 | import org.springframework.core.convert.TypeDescriptor;
|
|
56 | 57 |
|
57 | 58 | import static org.assertj.core.api.Assertions.assertThat;
|
58 | 59 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
| 60 | +import static org.assertj.core.api.Assertions.byLessThan; |
59 | 61 | import static org.assertj.core.api.Assertions.entry;
|
60 | 62 |
|
61 | 63 | /**
|
@@ -978,13 +980,88 @@ void convertNullOptionalToNull() {
|
978 | 980 | assertThat(conversionService.convert(null, rawOptionalType, TypeDescriptor.valueOf(Object.class))).isNull();
|
979 | 981 | }
|
980 | 982 |
|
| 983 | + @Test // gh-34544 |
| 984 | + void convertEmptyOptionalToNull() { |
| 985 | + Optional<Object> empty = Optional.empty(); |
| 986 | + |
| 987 | + assertThat(conversionService.convert(empty, Object.class)).isNull(); |
| 988 | + assertThat(conversionService.convert(empty, String.class)).isNull(); |
| 989 | + |
| 990 | + assertThat(conversionService.convert(empty, rawOptionalType, TypeDescriptor.valueOf(Object.class))).isNull(); |
| 991 | + assertThat(conversionService.convert(empty, rawOptionalType, TypeDescriptor.valueOf(String.class))).isNull(); |
| 992 | + assertThat(conversionService.convert(empty, rawOptionalType, TypeDescriptor.valueOf(Integer[].class))).isNull(); |
| 993 | + assertThat(conversionService.convert(empty, rawOptionalType, TypeDescriptor.valueOf(List.class))).isNull(); |
| 994 | + } |
| 995 | + |
981 | 996 | @Test
|
982 | 997 | void convertEmptyOptionalToOptional() {
|
983 | 998 | assertThat((Object) conversionService.convert(Optional.empty(), Optional.class)).isSameAs(Optional.empty());
|
984 | 999 | assertThat(conversionService.convert(Optional.empty(), TypeDescriptor.valueOf(Object.class), rawOptionalType))
|
985 | 1000 | .isSameAs(Optional.empty());
|
986 | 1001 | }
|
987 | 1002 |
|
| 1003 | + @Test // gh-34544 |
| 1004 | + @SuppressWarnings("unchecked") |
| 1005 | + void convertOptionalToOptionalWithoutConversionOfContainedObject() { |
| 1006 | + assertThat(conversionService.convert(Optional.of(42), Optional.class)).contains(42); |
| 1007 | + |
| 1008 | + assertThat(conversionService.convert(Optional.of("enigma"), Optional.class)).contains("enigma"); |
| 1009 | + assertThat((Optional<String>) conversionService.convert(Optional.of("enigma"), rawOptionalType, rawOptionalType)) |
| 1010 | + .contains("enigma"); |
| 1011 | + } |
| 1012 | + |
| 1013 | + @Test // gh-34544 |
| 1014 | + @SuppressWarnings("unchecked") |
| 1015 | + void convertOptionalToOptionalWithConversionOfContainedObject() { |
| 1016 | + TypeDescriptor integerOptionalType = |
| 1017 | + new TypeDescriptor(ResolvableType.forClassWithGenerics(Optional.class, Integer.class), null, null); |
| 1018 | + TypeDescriptor stringOptionalType = |
| 1019 | + new TypeDescriptor(ResolvableType.forClassWithGenerics(Optional.class, String.class), null, null); |
| 1020 | + |
| 1021 | + assertThat((Optional<String>) conversionService.convert(Optional.of(42), integerOptionalType, stringOptionalType)) |
| 1022 | + .contains("42"); |
| 1023 | + } |
| 1024 | + |
| 1025 | + @Test // gh-34544 |
| 1026 | + @SuppressWarnings("unchecked") |
| 1027 | + void convertOptionalToObjectWithoutConversionOfContainedObject() { |
| 1028 | + assertThat(conversionService.convert(Optional.of("enigma"), String.class)).isEqualTo("enigma"); |
| 1029 | + assertThat(conversionService.convert(Optional.of(42), Integer.class)).isEqualTo(42); |
| 1030 | + assertThat(conversionService.convert(Optional.of(new int[] {1, 2, 3}), int[].class)).containsExactly(1, 2, 3); |
| 1031 | + assertThat(conversionService.convert(Optional.of(new Integer[] {1, 2, 3}), Integer[].class)).containsExactly(1, 2, 3); |
| 1032 | + assertThat(conversionService.convert(Optional.of(List.of(1, 2, 3)), List.class)).containsExactly(1, 2, 3); |
| 1033 | + } |
| 1034 | + |
| 1035 | + @Test // gh-34544 |
| 1036 | + @SuppressWarnings("unchecked") |
| 1037 | + void convertOptionalToObjectWithConversionOfContainedObject() { |
| 1038 | + assertThat(conversionService.convert(Optional.of(42), String.class)).isEqualTo("42"); |
| 1039 | + assertThat(conversionService.convert(Optional.of(3.14F), Double.class)).isCloseTo(3.14, byLessThan(0.001)); |
| 1040 | + assertThat(conversionService.convert(Optional.of(new int[] {1, 2, 3}), Integer[].class)).containsExactly(1, 2, 3); |
| 1041 | + assertThat(conversionService.convert(Optional.of(List.of(1, 2, 3)), Set.class)).containsExactly(1, 2, 3); |
| 1042 | + } |
| 1043 | + |
| 1044 | + @Test // gh-34544 |
| 1045 | + @SuppressWarnings("unchecked") |
| 1046 | + void convertNestedOptionalsToObject() { |
| 1047 | + assertThat(conversionService.convert(Optional.of(Optional.of("unwrap me twice")), String.class)) |
| 1048 | + .isEqualTo("unwrap me twice"); |
| 1049 | + } |
| 1050 | + |
| 1051 | + @Test // gh-34544 |
| 1052 | + @SuppressWarnings("unchecked") |
| 1053 | + void convertOptionalToObjectViaTypeDescriptorForMethodParameter() { |
| 1054 | + Method method = ClassUtils.getMethod(getClass(), "handleList", List.class); |
| 1055 | + MethodParameter parameter = new MethodParameter(method, 0); |
| 1056 | + TypeDescriptor descriptor = new TypeDescriptor(parameter); |
| 1057 | + |
| 1058 | + Optional<List<Integer>> source = Optional.of(List.of(1, 2, 3)); |
| 1059 | + assertThat((List<Integer>) conversionService.convert(source, rawOptionalType, descriptor)).containsExactly(1, 2, 3); |
| 1060 | + } |
| 1061 | + |
| 1062 | + public void handleList(List<Integer> value) { |
| 1063 | + } |
| 1064 | + |
988 | 1065 | public void handleOptionalList(Optional<List<Integer>> value) {
|
989 | 1066 | }
|
990 | 1067 | }
|
|
0 commit comments