More unit tests for jdk17

This commit is contained in:
2023-09-18 18:32:52 -05:00
parent 587f8bbaf6
commit 3cd7639da1
3 changed files with 212 additions and 122 deletions

View File

@ -13,7 +13,7 @@ import java.lang.annotation.Target;
* @author Isaac Parenteau
*
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MapValue {

View File

@ -4,17 +4,7 @@ import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@ -24,8 +14,6 @@ import java.util.stream.IntStream;
import net.locusworks.common.annotations.MapValue;
import net.locusworks.common.interfaces.ThrowingConsumer;
import java.util.Set;
/***
* Utils class with generic methods
* @author Isaac Parenteau
@ -110,49 +98,33 @@ public class Utils {
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> buildMap(Class<?> mapClass, Class<K> mapKey, Class<V> mapValue, Object... data) {
Objects.requireNonNull(mapKey, "Null key value");
Objects.requireNonNull(mapValue, "Null map value");
Map<K, V> results;
try {
results = (Map<K, V>) mapClass.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create instance of " + mapClass.getSimpleName());
throw new IllegalArgumentException("Unable to create instance of " + mapClass.getSimpleName() + " e: " + ex.getMessage());
}
if (data.length % 2 != 0) {
throw new IllegalArgumentException("Odd number of arguments provided");
}
Object key = null;
int step = -1;
for(int i = 0; i < data.length; i+=2) {
Object key = data[i];
Object value = data[i + 1];
for (Object value : data) {
switch(++step % 2) {
case 0:
if (mapKey == null) {
throw new IllegalArgumentException("Null key value");
}
if (value instanceof Class) {
try {
value = ((Class<?>)value).getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create new instance of " + value);
}
if (!mapKey.isInstance(key)) {
throw new IllegalArgumentException("Key is not the correct instance. Expecting " + mapKey.getName() + " Received " + key.getClass().getName());
}
if (!mapKey.isInstance(value)) {
throw new IllegalArgumentException("Key is not the correct instance. Expecting " + mapKey.getName() + " Received " + value.getClass().getName());
}
key = value;
continue;
case 1:
if (!mapValue.isInstance(value)) {
throw new IllegalArgumentException("Value is not the correct instance. Expecting " + mapValue.getName() + " Received " + value.getClass().getName());
}
results.put((K) key, (V) value);
break;
default:
throw new IllegalAccessError("Calculation for step was not a multiple of two. This shouldn't have happened");
}
}
return results;
}
@ -161,28 +133,24 @@ public class Utils {
* Builds a set of objects
* @param setClass Class type of the set to create
* @param setValue Class type of the objects being placed in the set
* @param <V> Class type of the return object (should be the same as setValue)
* @param <E> Class type of the return object (should be the same as setValue)
* @param data Data to place inside the set
* @return Set filled with the data
* @deprecated since JDk11 can use Set.of
*/
@SuppressWarnings("unchecked")
public static <V> Set<V> buildSet(Class<?> setClass, Class<V> setValue, Object... data) {
Set<V> results;
try {
results = (Set<V>) setClass.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new IllegalArgumentException("Unable to create instance of " + setClass.getSimpleName());
public static <E> Set<E> buildSet(Class<?> setClass, Class<E> setValue, E... data) {
return buildSet(data);
}
for (Object value : data) {
if (!setValue.isInstance(value)) {
throw new IllegalArgumentException("Value is not the correct instance. Expecting " + setValue.getName() + " Received " + value.getClass().getName());
}
results.add((V) value);
}
return results;
/**
* Builds a set of objects
* @param data the data to set
* @return the set
* @param <E> the type
*/
@SafeVarargs public static <E> Set<E> buildSet(E... data) {
return Set.of(data);
}
/**
@ -197,23 +165,12 @@ public class Utils {
}
/**
* Clone list.
* Clone list and makes it unmodifiable.
*
* @param <E> the type parameter
* @param list the list
*
* @return the list
* @throws IllegalAccessException throw when an object in the list cannot be accessed through reflection
* @throws InstantiationException thrown when an object in the list cannot be instantiated through reflection
* @return unmodifiable list
*/
@SuppressWarnings("unchecked")
public static <E> List<E> cloneList(List<E> list)
throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
List<E> clone = new ArrayList<>();
for (E item : list) {
clone.add((E) cloneObject(item));
}
return clone;
public static <E> List<E> cloneList(List<E> list) {
return Collections.unmodifiableList(list);
}
/**
@ -223,7 +180,8 @@ public class Utils {
* @throws IllegalAccessException thrown when the filed cannot be access
* @throws InstantiationException Thrown when the object cannot be instantiated
*/
public static Object cloneObject(Object obj)
@SuppressWarnings("unchecked")
public static <O> O cloneObject(O obj)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Object clone = obj.getClass().getDeclaredConstructor().newInstance();
for (Field field : obj.getClass().getDeclaredFields()) {
@ -232,9 +190,10 @@ public class Utils {
if (field.get(obj) == null || Modifier.isFinal(field.getModifiers())){
continue;
}
if (field.getType().isPrimitive() || field.getType().equals(String.class)
|| field.getType().getSuperclass().equals(Number.class)
|| field.getType().equals(Boolean.class)){
Class<?> type = field.getType();
if (type.isPrimitive() || getWrapperTypes().contains(type)) {
field.set(clone, field.get(obj));
} else {
Object childObj = field.get(obj);
@ -246,7 +205,7 @@ public class Utils {
}
} catch (NullPointerException ignored) { }
}
return clone;
return (O) clone;
}
/***
@ -260,18 +219,17 @@ public class Utils {
Class<?> clazz = obj.getClass();
Map<String, Object> map = new LinkedHashMap<>();
boolean hasAnnotations = clazz.isAnnotationPresent(MapValue.class);
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
boolean hasAnnotations = field.isAnnotationPresent(MapValue.class);
String key = field.getName();
Object value = field.get(obj);
if (value == null) continue;
if (hasAnnotations) {
if (!field.isAnnotationPresent(MapValue.class)) {
continue;
}
MapValue annotation = field.getDeclaredAnnotation(MapValue.class);
if (annotation.ignore()) {
continue;
@ -303,6 +261,12 @@ public class Utils {
return convert;
}
/**
* Converts an object toa string map;
* @param obj the object to convert
* @return the map
* @throws Exception thrown if something happens
*/
public static Map<String, String> convertToStringMap(Object obj) throws Exception {
return convertToStringMap(convertToMap(obj));
}
@ -459,6 +423,27 @@ public class Utils {
return tmpList;
}
/**
* Use reflection to get the field values
* @param clazz the class to find the field
* @param fieldName the field name
* @return field
*/
private static Field getField(Class<?> clazz, String fieldName) {
Field field = null;
while(clazz != null) {
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
break;
} catch(Exception ex) {
clazz = clazz.getSuperclass();
}
}
return field;
}
/**
* A replacement for String.format. Allows for to many parameters or too few
* Replaces {} in the string in order.
@ -503,27 +488,6 @@ public class Utils {
return obj == null ? "Unknown" : (verbose ? obj.getClass().getName() : obj.getClass().getSimpleName());
}
/**
* Use reflection to get the field values
* @param clazz the class to find the field
* @param fieldName the field name
* @return field
*/
private static Field getField(Class<?> clazz, String fieldName) {
Field field = null;
while(clazz != null) {
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
break;
} catch(Exception ex) {
clazz = clazz.getSuperclass();
}
}
return field;
}
/**
* Get a value from a map
*
@ -1076,16 +1040,16 @@ public class Utils {
}
private static Set<Class<?>> getWrapperTypes() {
Set<Class<?>> ret = new HashSet<>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(String.class);
return ret;
return Set.of(
Boolean.class,
Character.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
String.class
);
}
}

View File

@ -1,15 +1,14 @@
package net.locusworks.test;
import net.locusworks.common.annotations.MapValue;
import net.locusworks.common.utils.Utils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.ParameterizedTest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
@ -110,9 +109,136 @@ public class UtilsTest {
assertEquals("World", mymap.get("Hello"));
}
@Test
public void testCloneList() {
String[] values = new String[]{
"Hello",
"world"
};
List<String> cloned = Utils.cloneList(new ArrayList<>(Arrays.stream(values).toList()));
assertEquals(2, cloned.size());
assertThrows(UnsupportedOperationException.class, () -> cloned.add("asdf"));
}
@Test
public void testCloneObject()
throws InvocationTargetException, InstantiationException, IllegalAccessException,
NoSuchMethodException {
TestClass clazz = new TestClass();
clazz.field1 = "hi";
clazz.field2 = "low";
clazz.field3 = "world";
TestClass clazz3 = new TestClass();
clazz3.field1 = "hi";
clazz3.field2 = "smash";
clazz3.field3 = "world";
clazz.testClass = clazz3;
TestClass clazz2 = Utils.cloneObject(clazz);
assertNotNull(clazz2);
assertEquals(clazz.field1, clazz2.field1);
assertEquals(clazz.field2, clazz2.field2);
assertEquals(clazz.field3, clazz2.field3);
assertEquals(clazz.field5, clazz2.field5);
assertEquals(clazz.number, clazz2.number);
assertEquals(clazz.aBoolean, clazz2.aBoolean);
assertNotNull(clazz2.field4);
assertNull(clazz2.nullField);
}
@Test
public void testCovertToMap() throws Exception {
TestClass clazz = new TestClass();
clazz.field1 = "hi";
clazz.field2 = "low";
clazz.field3 = "world";
TestClass clazz3 = new TestClass();
clazz.field1 = "hi";
clazz.field2 = "low";
clazz.field3 = "world";
clazz.testClass = clazz3;
Map<String, Object> converted = Utils.convertToMap(clazz);
assertEquals(7, converted.size());
assertEquals("hi", converted.get("other_field"));
}
@Test
public void testConvertToStringMap() throws Exception {
TestClass clazz = new TestClass();
clazz.field1 = "hi";
clazz.field2 = "low";
clazz.field3 = "world";
Map<String, String> converted = Utils.convertToStringMap(clazz);
assertEquals(6, converted.size());
assertEquals("hi", converted.get("other_field"));
converted = Utils.convertToStringMap(converted);
assertEquals(6, converted.size());
assertEquals("hi", converted.get("other_field"));
}
@Test
public void testBuildStringMap() {
Map<String, String> myMap = Utils.buildStringHashMap("hello", "world");
assertNotNull(myMap);
assertEquals(1, myMap.size());
}
@Test
public void testBuildMapExceptions() {
Throwable ex = assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(String.class, String.class, String.class, "" ));
assertNotNull(ex);
ex = assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, "Hello"));
assertEquals("Odd number of arguments provided", ex.getMessage());
assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, new Object(), "Hello"));
assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, String.class, String.class, "Hello", new Object()));
assertThrows(IllegalArgumentException.class, () -> Utils.buildMap(TreeMap.class, Object.class, String.class, "Hello", new Object()));
}
@Test
public void testBuildSet() {
Set<String> myset = Utils.buildSet("Hello", "World");
assertNotNull(myset);
assertEquals(2, myset.size());
}
@Test
public void testIsJunitRunning() {
assertTrue(Utils.isJUnitRunning());
}
public static class TestClass {
@MapValue("other_field")
private String field1;
@MapValue(ignore = true)
private String field2;
private String field3;
private final String field4 = "final";
@MapValue
private int field5 = 5;
private Boolean aBoolean = Boolean.valueOf("true");
private Double number = 1.0d;
private String nullField = null;
private TestClass testClass;
}
}