diff --git a/pom.xml b/pom.xml
index 241dc2b09..25f6ee503 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.cedarsoftware
java-util
jar
- 2.4.1
+ 2.5.0-SNAPSHOT
Java Utilities
https://github.com/jdereg/java-util
diff --git a/src/test/java/com/cedarsoftware/util/convert/CharacterConversionsTests.java b/src/test/java/com/cedarsoftware/util/convert/CharacterConversionsTests.java
new file mode 100644
index 000000000..792f2fa03
--- /dev/null
+++ b/src/test/java/com/cedarsoftware/util/convert/CharacterConversionsTests.java
@@ -0,0 +1,45 @@
+package com.cedarsoftware.util.convert;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CharacterConversionsTests {
+
+ private Converter converter;
+
+ @BeforeEach
+ void beforeEach() {
+ this.converter = new Converter(new DefaultConverterOptions());
+ }
+
+ @ParameterizedTest
+ @NullSource
+ void toByteObject_whenCharacterIsNull_returnsNull(Character ch) {
+ assertThat(this.converter.convert(ch, Byte.class))
+ .isNull();
+ }
+
+ @ParameterizedTest
+ @NullSource
+ void toByte_whenCharacterIsNull_returnsCommonValuesZero(Character ch) {
+ assertThat(this.converter.convert(ch, byte.class))
+ .isSameAs(CommonValues.BYTE_ZERO);
+ }
+
+ @ParameterizedTest
+ @NullSource
+ void toIntObject_whenCharacterIsNull_returnsNull(Character ch) {
+ assertThat(this.converter.convert(ch, Integer.class))
+ .isNull();
+ }
+
+ @ParameterizedTest
+ @NullSource
+ void toInteger_whenCharacterIsNull_returnsCommonValuesZero(Character ch) {
+ assertThat(this.converter.convert(ch, int.class))
+ .isSameAs(CommonValues.INTEGER_ZERO);
+ }
+}
diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
index be8d66dec..deee2ed39 100644
--- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
+++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
@@ -20,6 +20,7 @@
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
@@ -31,37 +32,39 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
+import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import static com.cedarsoftware.util.MapUtilities.mapOf;
import static com.cedarsoftware.util.convert.Converter.getShortName;
import static com.cedarsoftware.util.convert.Converter.pair;
-import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author John DeRegnaucourt (jdereg@gmail.com) & Ken Partlow
- *
- * Copyright (c) Cedar Software LLC
- *
- * 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.
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * 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.
*/
-class ConverterEverythingTest
-{
+class ConverterEverythingTest {
private static final TimeZone TZ_TOKYO = TimeZone.getTimeZone("Asia/Tokyo");
private Converter converter;
private ConverterOptions options = new ConverterOptions() {
@@ -78,49 +81,49 @@ public TimeZone getTimeZone() {
// Byte/byte
TEST_FACTORY.put(pair(Void.class, byte.class), new Object[][] {
- { null, (byte)0 }
+ { null, (byte) 0 }
});
TEST_FACTORY.put(pair(Void.class, Byte.class), new Object[][] {
{ null, null }
});
TEST_FACTORY.put(pair(Byte.class, Byte.class), new Object[][] {
- { (byte)-1, (byte)-1 },
- { (byte)0, (byte)0 },
- { (byte)1, (byte)1 },
+ { (byte) -1, (byte) -1 },
+ { (byte) 0, (byte) 0 },
+ { (byte) 1, (byte) 1 },
{ Byte.MIN_VALUE, Byte.MIN_VALUE },
{ Byte.MAX_VALUE, Byte.MAX_VALUE }
});
TEST_FACTORY.put(pair(Short.class, Byte.class), new Object[][] {
- { (short)-1, (byte)-1 },
- { (short)0, (byte) 0 },
- { (short)1, (byte)1 },
- { (short)-128, Byte.MIN_VALUE },
- { (short)127, Byte.MAX_VALUE },
- { (short)-129, (byte) 127 }, // verify wrap around
- { (short)128, (byte)-128 } // verify wrap around
+ { (short) -1, (byte) -1 },
+ { (short) 0, (byte) 0 },
+ { (short) 1, (byte) 1 },
+ { (short) -128, Byte.MIN_VALUE },
+ { (short) 127, Byte.MAX_VALUE },
+ { (short) -129, (byte) 127 }, // verify wrap around
+ { (short) 128, (byte) -128 } // verify wrap around
});
TEST_FACTORY.put(pair(Integer.class, Byte.class), new Object[][] {
- { -1, (byte)-1 },
+ { -1, (byte) -1 },
{ 0, (byte) 0 },
{ 1, (byte) 1 },
{ -128, Byte.MIN_VALUE },
{ 127, Byte.MAX_VALUE },
{ -129, (byte) 127 }, // verify wrap around
- { 128, (byte)-128 } // verify wrap around
+ { 128, (byte) -128 } // verify wrap around
});
TEST_FACTORY.put(pair(Long.class, Byte.class), new Object[][] {
- { -1L, (byte)-1 },
+ { -1L, (byte) -1 },
{ 0L, (byte) 0 },
{ 1L, (byte) 1 },
{ -128L, Byte.MIN_VALUE },
{ 127L, Byte.MAX_VALUE },
{ -129L, (byte) 127 }, // verify wrap around
- { 128L, (byte)-128 } // verify wrap around
+ { 128L, (byte) -128 } // verify wrap around
});
TEST_FACTORY.put(pair(Float.class, Byte.class), new Object[][] {
- { -1f, (byte)-1 },
- { -1.99f, (byte)-1 },
- { -1.1f, (byte)-1 },
+ { -1f, (byte) -1 },
+ { -1.99f, (byte) -1 },
+ { -1.1f, (byte) -1 },
{ 0f, (byte) 0 },
{ 1f, (byte) 1 },
{ 1.1f, (byte) 1 },
@@ -132,15 +135,15 @@ public TimeZone getTimeZone() {
});
TEST_FACTORY.put(pair(Double.class, Byte.class), new Object[][] {
{ -1d, (byte) -1 },
- { -1.99d, (byte)-1 },
- { -1.1d, (byte)-1 },
+ { -1.99d, (byte) -1 },
+ { -1.1d, (byte) -1 },
{ 0d, (byte) 0 },
{ 1d, (byte) 1 },
{ 1.1d, (byte) 1 },
{ 1.999d, (byte) 1 },
{ -128d, Byte.MIN_VALUE },
{ 127d, Byte.MAX_VALUE },
- {-129d, (byte) 127 }, // verify wrap around
+ { -129d, (byte) 127 }, // verify wrap around
{ 128d, (byte) -128 } // verify wrap around
});
TEST_FACTORY.put(pair(Boolean.class, Byte.class), new Object[][] {
@@ -150,8 +153,8 @@ public TimeZone getTimeZone() {
TEST_FACTORY.put(pair(Character.class, Byte.class), new Object[][] {
{ '1', (byte) 49 },
{ '0', (byte) 48 },
- { (char)1, (byte) 1 },
- { (char)0, (byte) 0 },
+ { (char) 1, (byte) 1 },
+ { (char) 0, (byte) 0 },
});
TEST_FACTORY.put(pair(AtomicBoolean.class, Byte.class), new Object[][] {
{ new AtomicBoolean(true), (byte) 1 },
@@ -163,8 +166,8 @@ public TimeZone getTimeZone() {
{ new AtomicInteger(1), (byte) 1 },
{ new AtomicInteger(-128), Byte.MIN_VALUE },
{ new AtomicInteger(127), Byte.MAX_VALUE },
- { new AtomicInteger(-129), (byte)127 },
- { new AtomicInteger(128), (byte)-128 },
+ { new AtomicInteger(-129), (byte) 127 },
+ { new AtomicInteger(128), (byte) -128 },
});
TEST_FACTORY.put(pair(AtomicLong.class, Byte.class), new Object[][] {
{ new AtomicLong(-1), (byte) -1 },
@@ -172,8 +175,8 @@ public TimeZone getTimeZone() {
{ new AtomicLong(1), (byte) 1 },
{ new AtomicLong(-128), Byte.MIN_VALUE },
{ new AtomicLong(127), Byte.MAX_VALUE },
- { new AtomicLong(-129), (byte)127 },
- { new AtomicLong(128), (byte)-128 },
+ { new AtomicLong(-129), (byte) 127 },
+ { new AtomicLong(128), (byte) -128 },
});
TEST_FACTORY.put(pair(BigInteger.class, Byte.class), new Object[][] {
{ new BigInteger("-1"), (byte) -1 },
@@ -181,8 +184,8 @@ public TimeZone getTimeZone() {
{ new BigInteger("1"), (byte) 1 },
{ new BigInteger("-128"), Byte.MIN_VALUE },
{ new BigInteger("127"), Byte.MAX_VALUE },
- { new BigInteger("-129"), (byte)127 },
- { new BigInteger("128"), (byte)-128 },
+ { new BigInteger("-129"), (byte) 127 },
+ { new BigInteger("128"), (byte) -128 },
});
TEST_FACTORY.put(pair(BigDecimal.class, Byte.class), new Object[][] {
{ new BigDecimal("-1"), (byte) -1 },
@@ -194,8 +197,8 @@ public TimeZone getTimeZone() {
{ new BigDecimal("1.9"), (byte) 1 },
{ new BigDecimal("-128"), Byte.MIN_VALUE },
{ new BigDecimal("127"), Byte.MAX_VALUE },
- { new BigDecimal("-129"), (byte)127 },
- { new BigDecimal("128"), (byte)-128 },
+ { new BigDecimal("-129"), (byte) 127 },
+ { new BigDecimal("128"), (byte) -128 },
});
TEST_FACTORY.put(pair(Number.class, Byte.class), new Object[][] {
{ -2L, (byte) -2 },
@@ -205,21 +208,21 @@ public TimeZone getTimeZone() {
{ mapOf("_v", -1), (byte) -1 },
{ mapOf("value", "-1"), (byte) -1 },
{ mapOf("value", -1L), (byte) -1 },
-
+
{ mapOf("_v", "0"), (byte) 0 },
{ mapOf("_v", 0), (byte) 0 },
{ mapOf("_v", "1"), (byte) 1 },
{ mapOf("_v", 1), (byte) 1 },
- { mapOf("_v","-128"), Byte.MIN_VALUE },
- { mapOf("_v",-128), Byte.MIN_VALUE },
+ { mapOf("_v", "-128"), Byte.MIN_VALUE },
+ { mapOf("_v", -128), Byte.MIN_VALUE },
{ mapOf("_v", "127"), Byte.MAX_VALUE },
{ mapOf("_v", 127), Byte.MAX_VALUE },
{ mapOf("_v", "-129"), new IllegalArgumentException("'-129' not parseable as a byte value or outside -128 to 127") },
- { mapOf("_v", -129), (byte)127 },
+ { mapOf("_v", -129), (byte) 127 },
{ mapOf("_v", "128"), new IllegalArgumentException("'128' not parseable as a byte value or outside -128 to 127") },
{ mapOf("_v", 128), (byte) -128 },
@@ -233,14 +236,14 @@ public TimeZone getTimeZone() {
{ "1", (byte) 1 },
{ "1.1", (byte) 1 },
{ "1.9", (byte) 1 },
- { "-128", (byte)-128 },
- { "127", (byte)127 },
- { "", (byte)0 },
- { "crapola", new IllegalArgumentException("Value 'crapola' not parseable as a byte value or outside -128 to 127")},
- { "54 crapola", new IllegalArgumentException("Value '54 crapola' not parseable as a byte value or outside -128 to 127")},
- { "54crapola", new IllegalArgumentException("Value '54crapola' not parseable as a byte value or outside -128 to 127")},
- { "crapola 54", new IllegalArgumentException("Value 'crapola 54' not parseable as a byte value or outside -128 to 127")},
- { "crapola54", new IllegalArgumentException("Value 'crapola54' not parseable as a byte value or outside -128 to 127")},
+ { "-128", (byte) -128 },
+ { "127", (byte) 127 },
+ { "", (byte) 0 },
+ { "crapola", new IllegalArgumentException("Value 'crapola' not parseable as a byte value or outside -128 to 127") },
+ { "54 crapola", new IllegalArgumentException("Value '54 crapola' not parseable as a byte value or outside -128 to 127") },
+ { "54crapola", new IllegalArgumentException("Value '54crapola' not parseable as a byte value or outside -128 to 127") },
+ { "crapola 54", new IllegalArgumentException("Value 'crapola 54' not parseable as a byte value or outside -128 to 127") },
+ { "crapola54", new IllegalArgumentException("Value 'crapola54' not parseable as a byte value or outside -128 to 127") },
{ "-129", new IllegalArgumentException("'-129' not parseable as a byte value or outside -128 to 127") },
{ "128", new IllegalArgumentException("'128' not parseable as a byte value or outside -128 to 127") },
});
@@ -271,19 +274,19 @@ public TimeZone getTimeZone() {
{ mapOf("_v", "1-1"), MonthDay.of(1, 1) },
{ mapOf("value", "1-1"), MonthDay.of(1, 1) },
{ mapOf("_v", "01-01"), MonthDay.of(1, 1) },
- { mapOf("_v","--01-01"), MonthDay.of(1, 1) },
- { mapOf("_v","--1-1"), new IllegalArgumentException("Unable to extract Month-Day from string: --1-1") },
- { mapOf("_v","12-31"), MonthDay.of(12, 31) },
- { mapOf("_v","--12-31"), MonthDay.of(12, 31) },
- { mapOf("_v","-12-31"), new IllegalArgumentException("Unable to extract Month-Day from string: -12-31") },
- { mapOf("_v","6-30"), MonthDay.of(6, 30) },
- { mapOf("_v","06-30"), MonthDay.of(6, 30) },
- { mapOf("_v","--06-30"), MonthDay.of(6, 30) },
- { mapOf("_v","--6-30"), new IllegalArgumentException("Unable to extract Month-Day from string: --6-30") },
- { mapOf("month","6", "day", 30), MonthDay.of(6, 30) },
- { mapOf("month",6L, "day", "30"), MonthDay.of(6, 30)},
- { mapOf("month", mapOf("_v", 6L), "day", "30"), MonthDay.of(6, 30)}, // recursive on "month"
- { mapOf("month", 6L, "day", mapOf("_v", "30")), MonthDay.of(6, 30)}, // recursive on "day"
+ { mapOf("_v", "--01-01"), MonthDay.of(1, 1) },
+ { mapOf("_v", "--1-1"), new IllegalArgumentException("Unable to extract Month-Day from string: --1-1") },
+ { mapOf("_v", "12-31"), MonthDay.of(12, 31) },
+ { mapOf("_v", "--12-31"), MonthDay.of(12, 31) },
+ { mapOf("_v", "-12-31"), new IllegalArgumentException("Unable to extract Month-Day from string: -12-31") },
+ { mapOf("_v", "6-30"), MonthDay.of(6, 30) },
+ { mapOf("_v", "06-30"), MonthDay.of(6, 30) },
+ { mapOf("_v", "--06-30"), MonthDay.of(6, 30) },
+ { mapOf("_v", "--6-30"), new IllegalArgumentException("Unable to extract Month-Day from string: --6-30") },
+ { mapOf("month", "6", "day", 30), MonthDay.of(6, 30) },
+ { mapOf("month", 6L, "day", "30"), MonthDay.of(6, 30) },
+ { mapOf("month", mapOf("_v", 6L), "day", "30"), MonthDay.of(6, 30) }, // recursive on "month"
+ { mapOf("month", 6L, "day", mapOf("_v", "30")), MonthDay.of(6, 30) }, // recursive on "day"
});
// YearMonth
@@ -318,8 +321,8 @@ public TimeZone getTimeZone() {
{ null, null },
});
TEST_FACTORY.put(pair(Period.class, Period.class), new Object[][] {
- { Period.of(0, 0, 0), Period.of(0,0, 0) },
- { Period.of(1, 1, 1), Period.of(1,1, 1) },
+ { Period.of(0, 0, 0), Period.of(0, 0, 0) },
+ { Period.of(1, 1, 1), Period.of(1, 1, 1) },
});
TEST_FACTORY.put(pair(String.class, Period.class), new Object[][] {
{ "P0D", Period.of(0, 0, 0) },
@@ -336,9 +339,9 @@ public TimeZone getTimeZone() {
{ mapOf("_v", "P0D"), Period.of(0, 0, 0) },
{ mapOf("value", "P1Y1M1D"), Period.of(1, 1, 1) },
{ mapOf("years", "2", "months", 2, "days", 2.0d), Period.of(2, 2, 2) },
- { mapOf("years", mapOf("_v", (byte)2), "months", mapOf("_v", 2.0f), "days", mapOf("_v", new AtomicInteger(2))), Period.of(2, 2, 2) }, // recursion
+ { mapOf("years", mapOf("_v", (byte) 2), "months", mapOf("_v", 2.0f), "days", mapOf("_v", new AtomicInteger(2))), Period.of(2, 2, 2) }, // recursion
});
-
+
// Year
TEST_FACTORY.put(pair(Void.class, Year.class), new Object[][] {
{ null, null },
@@ -358,11 +361,11 @@ public TimeZone getTimeZone() {
{ mapOf("_v", "1984"), Year.of(1984) },
{ mapOf("value", 1984L), Year.of(1984) },
{ mapOf("year", 1492), Year.of(1492) },
- { mapOf("year", mapOf("_v", (short)2024)), Year.of(2024) }, // recursion
+ { mapOf("year", mapOf("_v", (short) 2024)), Year.of(2024) }, // recursion
});
TEST_FACTORY.put(pair(Number.class, Year.class), new Object[][] {
- { (byte)101, new IllegalArgumentException("Unsupported conversion, source type [Byte (101)] target type 'Year'") },
- { (short)2024, Year.of(2024) },
+ { (byte) 101, new IllegalArgumentException("Unsupported conversion, source type [Byte (101)] target type 'Year'") },
+ { (short) 2024, Year.of(2024) },
});
// ZoneId
@@ -410,22 +413,22 @@ public TimeZone getTimeZone() {
{ mapOf("hours", -10L, "minutes", "0"), ZoneOffset.of("-10:00") },
{ mapOf("hrs", -10L, "mins", "0"), new IllegalArgumentException("Map to ZoneOffset the map must include one of the following: [hours, minutes, seconds], [_v], or [value]") },
{ mapOf("hours", -10L, "minutes", "0", "seconds", 0), ZoneOffset.of("-10:00") },
- { mapOf("hours", "-10", "minutes", (byte)-15, "seconds", "-1"), ZoneOffset.of("-10:15:01") },
- { mapOf("hours", "10", "minutes", (byte)15, "seconds", true), ZoneOffset.of("+10:15:01") },
- { mapOf("hours", mapOf("_v","10"), "minutes", mapOf("_v", (byte)15), "seconds", mapOf("_v", true)), ZoneOffset.of("+10:15:01") }, // full recursion
+ { mapOf("hours", "-10", "minutes", (byte) -15, "seconds", "-1"), ZoneOffset.of("-10:15:01") },
+ { mapOf("hours", "10", "minutes", (byte) 15, "seconds", true), ZoneOffset.of("+10:15:01") },
+ { mapOf("hours", mapOf("_v", "10"), "minutes", mapOf("_v", (byte) 15), "seconds", mapOf("_v", true)), ZoneOffset.of("+10:15:01") }, // full recursion
});
-
+
// String
TEST_FACTORY.put(pair(Void.class, String.class), new Object[][] {
{ null, null }
});
TEST_FACTORY.put(pair(Byte.class, String.class), new Object[][] {
- { (byte)0, "0" },
+ { (byte) 0, "0" },
{ Byte.MIN_VALUE, "-128" },
{ Byte.MAX_VALUE, "127" },
});
TEST_FACTORY.put(pair(Short.class, String.class), new Object[][] {
- { (short)0, "0" },
+ { (short) 0, "0" },
{ Short.MIN_VALUE, "-32768" },
{ Short.MAX_VALUE, "32767" },
});
@@ -463,24 +466,24 @@ public TimeZone getTimeZone() {
});
TEST_FACTORY.put(pair(Boolean.class, String.class), new Object[][] {
{ false, "false" },
- { true, "true"}
+ { true, "true" }
});
TEST_FACTORY.put(pair(Character.class, String.class), new Object[][] {
- { '1', "1"},
- { (char) 32, " "},
+ { '1', "1" },
+ { (char) 32, " " },
});
TEST_FACTORY.put(pair(BigInteger.class, String.class), new Object[][] {
- { new BigInteger("-1"), "-1"},
- { new BigInteger("0"), "0"},
- { new BigInteger("1"), "1"},
+ { new BigInteger("-1"), "-1" },
+ { new BigInteger("0"), "0" },
+ { new BigInteger("1"), "1" },
});
TEST_FACTORY.put(pair(BigDecimal.class, String.class), new Object[][] {
- { new BigDecimal("-1"), "-1"},
- { new BigDecimal("-1.0"), "-1"},
- { new BigDecimal("0"), "0"},
- { new BigDecimal("0.0"), "0"},
- { new BigDecimal("1.0"), "1"},
- { new BigDecimal("3.141519265358979323846264338"), "3.141519265358979323846264338"},
+ { new BigDecimal("-1"), "-1" },
+ { new BigDecimal("-1.0"), "-1" },
+ { new BigDecimal("0"), "0" },
+ { new BigDecimal("0.0"), "0" },
+ { new BigDecimal("1.0"), "1" },
+ { new BigDecimal("3.141519265358979323846264338"), "3.141519265358979323846264338" },
});
TEST_FACTORY.put(pair(AtomicBoolean.class, String.class), new Object[][] {
{ new AtomicBoolean(false), "false" },
@@ -501,20 +504,20 @@ public TimeZone getTimeZone() {
{ new AtomicLong(Long.MAX_VALUE), "9223372036854775807" },
});
TEST_FACTORY.put(pair(byte[].class, String.class), new Object[][] {
- { new byte[] {(byte)0xf0, (byte)0x9f, (byte)0x8d, (byte)0xba}, "\uD83C\uDF7A" }, // beer mug, byte[] treated as UTF-8.
- { new byte[] {(byte)65, (byte)66, (byte)67, (byte)68}, "ABCD" }
+ { new byte[] { (byte) 0xf0, (byte) 0x9f, (byte) 0x8d, (byte) 0xba }, "\uD83C\uDF7A" }, // beer mug, byte[] treated as UTF-8.
+ { new byte[] { (byte) 65, (byte) 66, (byte) 67, (byte) 68 }, "ABCD" }
});
TEST_FACTORY.put(pair(char[].class, String.class), new Object[][] {
- { new char[] { 'A', 'B', 'C', 'D'}, "ABCD" }
+ { new char[] { 'A', 'B', 'C', 'D' }, "ABCD" }
});
TEST_FACTORY.put(pair(Character[].class, String.class), new Object[][] {
- { new Character[] { 'A', 'B', 'C', 'D'}, "ABCD" }
+ { new Character[] { 'A', 'B', 'C', 'D' }, "ABCD" }
});
TEST_FACTORY.put(pair(ByteBuffer.class, String.class), new Object[][] {
- { ByteBuffer.wrap(new byte[] { (byte)0x30, (byte)0x31, (byte)0x32, (byte)0x33}), "0123"}
+ { ByteBuffer.wrap(new byte[] { (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33 }), "0123" }
});
TEST_FACTORY.put(pair(CharBuffer.class, String.class), new Object[][] {
- { CharBuffer.wrap(new char[] { 'A', 'B', 'C', 'D'}), "ABCD" },
+ { CharBuffer.wrap(new char[] { 'A', 'B', 'C', 'D' }), "ABCD" },
});
TEST_FACTORY.put(pair(Class.class, String.class), new Object[][] {
{ Date.class, "java.util.Date" }
@@ -549,10 +552,10 @@ public TimeZone getTimeZone() {
{ ZonedDateTime.parse("2024-02-14T19:20:00+05:00"), "2024-02-14T19:20:00+05:00" }
});
TEST_FACTORY.put(pair(UUID.class, String.class), new Object[][] {
- { new UUID(0L, 0L) , "00000000-0000-0000-0000-000000000000" },
- { new UUID(1L, 1L) , "00000000-0000-0001-0000-000000000001" },
- { new UUID(Long.MAX_VALUE, Long.MAX_VALUE) , "7fffffff-ffff-ffff-7fff-ffffffffffff" },
- { new UUID(Long.MIN_VALUE, Long.MIN_VALUE) , "80000000-0000-0000-8000-000000000000" },
+ { new UUID(0L, 0L), "00000000-0000-0000-0000-000000000000" },
+ { new UUID(1L, 1L), "00000000-0000-0001-0000-000000000001" },
+ { new UUID(Long.MAX_VALUE, Long.MAX_VALUE), "7fffffff-ffff-ffff-7fff-ffffffffffff" },
+ { new UUID(Long.MIN_VALUE, Long.MIN_VALUE), "80000000-0000-0000-8000-000000000000" },
});
TEST_FACTORY.put(pair(Calendar.class, String.class), new Object[][] {
{ (Supplier) () -> {
@@ -564,15 +567,15 @@ public TimeZone getTimeZone() {
}, "2024-02-05T22:31:00" }
});
TEST_FACTORY.put(pair(Number.class, String.class), new Object[][] {
- { (byte)1 , "1" },
- { (short)2 , "2" },
- { 3 , "3" },
- { 4L , "4" },
- { 5f , "5.0" },
- { 6d , "6.0" },
+ { (byte) 1, "1" },
+ { (short) 2, "2" },
+ { 3, "3" },
+ { 4L, "4" },
+ { 5f, "5.0" },
+ { 6d, "6.0" },
});
TEST_FACTORY.put(pair(Map.class, String.class), new Object[][] {
-
+
});
TEST_FACTORY.put(pair(Enum.class, String.class), new Object[][] {
@@ -611,10 +614,12 @@ public TimeZone getTimeZone() {
});
TEST_FACTORY.put(pair(Year.class, String.class), new Object[][] {
-
+
});
}
+ public static Map> shortNamesToClass = new ConcurrentHashMap<>();
+
private static String toGmtString(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
simpleDateFormat.setTimeZone(TZ_TOKYO);
@@ -627,22 +632,20 @@ public void before() {
converter = new Converter(options);
}
+
@Test
- void testEverything() {
- boolean failed = false;
+ void testForMissingTests() {
Map, Set>> map = converter.allSupportedConversions();
int neededTests = 0;
- int count = 0;
- boolean filterTests = false;
- int singleIndex = -1; // Set to -1 to run all tests for a given pairing, or to 0-index to only run a specific test.
- Class> singleSource = Calendar.class;
- Class> singleTarget = String.class;
for (Map.Entry, Set>> entry : map.entrySet()) {
Class> sourceClass = entry.getKey();
Set> targetClasses = entry.getValue();
-
+
+
+
for (Class> targetClass : targetClasses) {
+
Object[][] testData = TEST_FACTORY.get(pair(sourceClass, targetClass));
if (testData == null) { // data set needs added
@@ -650,37 +653,6 @@ void testEverything() {
// an "everything" test entry is added.
System.err.println("No test data for: " + getShortName(sourceClass) + " ==> " + getShortName(targetClass));
neededTests++;
- continue;
- }
-
- for (int i=0; i < testData.length; i++) {
- if (filterTests) {
- if (!sourceClass.equals(singleSource) || !targetClass.equals(singleTarget)) {
- // Allow skipping all but one (1) test, or all but one category of tests.
- if (singleIndex < 0 || singleIndex != i) {
- continue;
- }
- }
- }
-
- Object[] testPair = testData[i];
- try {
- verifyTestPair(sourceClass, targetClass, testPair);
- count++;
- } catch (Throwable e) {
- System.err.println();
- System.err.println("{ " + getShortName(sourceClass) + ".class ==> " + getShortName(targetClass) + ".class }");
- System.err.print("testPair[" + i + "] = ");
- if (testPair.length == 2) {
- String pair0 = testPair[0] == null ? "null" : testPair[0].toString();
- String pair1 = testPair[1] == null ? "null" : testPair[1].toString();
- System.err.println("{ " + pair0 + ", " + pair1 + " }");
- }
- System.err.println();
- e.printStackTrace();
- System.err.println();
- failed = true;
- }
}
}
}
@@ -688,51 +660,93 @@ void testEverything() {
if (neededTests > 0) {
System.err.println(neededTests + " tests need to be added.");
System.err.flush();
- }
- if (failed) {
- throw new RuntimeException("One or more tests failed.");
- }
- if (neededTests > 0 || failed) {
- System.out.println("Tests passed: " + count);
- System.out.flush();
+ // fail(neededTests + " tests need to be added.");
}
}
- private void verifyTestPair(Class> sourceClass, Class> targetClass, Object[] testPair) {
- if (testPair.length != 2) {
- throw new IllegalArgumentException("Test cases must have two values : { source instance, target instance }");
+ private static Object possiblyConvertSupplier(Object possibleSupplier) {
+ if (possibleSupplier instanceof Supplier) {
+ return ((Supplier>) possibleSupplier).get();
}
- // If lambda Supplier function given, execute it and substitute the value into the source location
- if (testPair[0] instanceof Supplier) {
- testPair[0] = ((Supplier>) testPair[0]).get();
- }
+ return possibleSupplier;
+ }
- // If lambda Supplier function given, execute it and substitute the value into the target location
- if (testPair[1] instanceof Supplier) {
- testPair[1] = ((Supplier>) testPair[1]).get();
- }
+ private static Stream generateTestEverythingParams() {
+
+ ArrayList list = new ArrayList<>(400);
+
+ for (Map.Entry, Class>>, Object[][]> entry : TEST_FACTORY.entrySet()) {
+ Class> sourceClass = entry.getKey().getKey();
+ Class> targetClass = entry.getKey().getValue();
+ Object[][] testData = entry.getValue();
+
+ for (int i = 0; i < testData.length; i++) {
+ Object[] testPair = testData[i];
+
+ // don't worry about putting back into the pair for tests when suppliers. We can get each time for now.
+ // protecting Test integrity.
+ Object source = possiblyConvertSupplier(testPair[0]);
+ Object target = possiblyConvertSupplier(testPair[1]);
+
+ String shortNameSource = addShortName(sourceClass);
+ String shortNameTarget = addShortName(targetClass);
+
+ list.add(Arguments.of(shortNameSource, shortNameTarget, source, target));
+ }
- // Ensure test data author matched the source instance to the source class
- if (testPair[0] != null) {
- assertThat(testPair[0]).isInstanceOf(sourceClass);
}
- // If an exception is expected to be returned, then assert that it is thrown, the type of exception, and a portion of the message.
- if (testPair[1] instanceof Throwable) {
- Throwable t = (Throwable) testPair[1];
+ return Stream.of(list.toArray(new Arguments[] {}));
+ }
+
+ @ParameterizedTest(name = "<{0}, {1}> ==> {2}")
+ @MethodSource("generateTestEverythingParams")
+ void testSourceMatchesExpectedType(String shortNameSource, String shortNameTarget, Object source, Object actual) {
+ Class> sourceClass = getFromShortName(shortNameSource);
+ assertTrue(source == null || sourceClass.isAssignableFrom(source.getClass()));
+ }
+
+ @ParameterizedTest(name = "<{0}, {1}> ==> {2}")
+ @MethodSource("generateTestEverythingParams")
+ void testConvert(String shortNameSource, String shortNameTarget, Object source, Object target) {
+ Class> targetClass = getFromShortName(shortNameTarget);
+ //TODO: does the exception actually get thrown on the convert or should we just check if they are equal?
+ if (target instanceof Throwable) {
+ Throwable t = (Throwable) target;
assertThatExceptionOfType(t.getClass())
- .isThrownBy(() -> converter.convert(testPair[0], targetClass, options))
- .withMessageContaining(((Throwable) testPair[1]).getMessage());
+ .isThrownBy(() -> converter.convert(source, targetClass, options))
+ .withMessageContaining(((Throwable) target).getMessage());
} else {
// Assert values are equals
- Object target = converter.convert(testPair[0], targetClass, options);
- assertEquals(testPair[1], target);
+ Object actual = converter.convert(source, targetClass, options);
+ assertEquals(target, actual);
+ }
+ }
- // Verify same instance when source and target are the same class
- if (sourceClass.equals(targetClass)) {
- assertSame(testPair[0], target);
- }
+ @ParameterizedTest(name = "<{0}, {1}> ==> {2}")
+ @MethodSource("generateTestEverythingParams")
+ void testIdentity(String shortNameSource, String shortNameTarget, Object source, Object actual) {
+ Class> sourceClass = getFromShortName(shortNameSource);
+ Class> targetClass = getFromShortName(shortNameTarget);
+ // do not test identity on Throwables.
+ // if source and target classes match then we expect the objects to be the same object.
+ assertTrue(actual instanceof Throwable ||
+ !sourceClass.equals(targetClass) ||
+ (source == converter.convert(source, targetClass, options)));
+ }
+
+ public static String addShortName(Class> c) {
+ String name = c.getSimpleName();
+ if (java.sql.Date.class.isAssignableFrom(c)) {
+ name = "java.sql.Date";
}
+ shortNamesToClass.put(name, c);
+ return name;
+ }
+
+ public static Class> getFromShortName(String name) {
+ return shortNamesToClass.get(name);
}
+
}