Verified Commit 741823ff authored by Daniel Mangold's avatar Daniel Mangold
Browse files

Optimized Assertions.java

parent 9d78a8c1
......@@ -3,6 +3,7 @@ package h05;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import static java.lang.reflect.Modifier.*;
......@@ -12,79 +13,60 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class Assertions {
private static final Map<Integer, Object[]> MODIFIER_METHODS;
static {
Map<Integer, Object[]> modifierMethodsTmp = null;
try {
modifierMethodsTmp = Map.of(
PUBLIC, new Object[] {Modifier.class.getDeclaredMethod("isPublic", int.class), "public"},
PRIVATE, new Object[] {Modifier.class.getDeclaredMethod("isPrivate", int.class), "private"},
PROTECTED, new Object[] {Modifier.class.getDeclaredMethod("isProtected", int.class), "protected"},
STATIC, new Object[] {Modifier.class.getDeclaredMethod("isStatic", int.class), "static"},
FINAL, new Object[] {Modifier.class.getDeclaredMethod("isFinal", int.class), "final"},
ABSTRACT, new Object[] {Modifier.class.getDeclaredMethod("isAbstract", int.class), "abstract"}
);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
MODIFIER_METHODS = modifierMethodsTmp;
}
/**
* Assert that the given member has (map value = {@code true}) or does not have
* (map value = {@code false}) the modifiers in {@code modifiers}. <br>
* Assert that the given member has the specified modifiers. <br>
* Throws a {@link AssertionError} if the assertion fails
* <br><br>
* Calls {@link Assertions#assertHasModifiers(Member, Map, String)} with {@code null} as last
* Calls {@link Assertions#assertHasModifiers(Member, List, String)} with {@code null} as last
* parameter (default error message)
* @param member the member to check the modifiers of
* @param modifiers a map of modifiers (constants in {@link Modifier}) with a
* corresponding boolean value
* @param modifiers a list of modifiers (constants of {@link Modifier})
*/
public static void assertHasModifiers(Member member, Map<Integer, Boolean> modifiers) {
public static void assertHasModifiers(Member member, List<Integer> modifiers) {
assertHasModifiers(member, modifiers, null);
}
/**
* Assert that the given member has (map value = {@code true}) or does not have
* (map value = {@code false}) the modifiers in {@code modifiers}. <br>
* Assert that the given member has the specified modifiers. <br>
* Throws a {@link AssertionError} if the assertion fails
* @param member the member to check the modifiers of
* @param modifiers a map of modifiers (constants in {@link Modifier}) with a
* corresponding boolean value
* @param msg the error message to pass to {@link AssertionError}
* @param modifiers a list of modifiers (constants of {@link Modifier})
* @param errorMsg the error message to pass to {@link AssertionError}
*/
public static void assertHasModifiers(Member member, Map<Integer, Boolean> modifiers, String msg) {
Class<Modifier> modifierClass = Modifier.class;
public static void assertHasModifiers(Member member, List<Integer> modifiers, String errorMsg) {
try {
for (Integer modifier : modifiers.keySet()) {
Method method;
String msgSuffix;
switch (modifier) {
case PUBLIC:
method = modifierClass.getDeclaredMethod("isPublic", int.class);
msgSuffix = "public";
break;
case PROTECTED:
method = modifierClass.getDeclaredMethod("isProtected", int.class);
msgSuffix = "protected";
break;
case PRIVATE:
method = modifierClass.getDeclaredMethod("isPrivate", int.class);
msgSuffix = "private";
break;
case STATIC:
method = modifierClass.getDeclaredMethod("isStatic", int.class);
msgSuffix = "static";
break;
case FINAL:
method = modifierClass.getDeclaredMethod("isFinal", int.class);
msgSuffix = "final";
break;
case ABSTRACT:
method = modifierClass.getDeclaredMethod("isAbstract", int.class);
msgSuffix = "abstract";
break;
default:
throw new IllegalArgumentException(String.valueOf(modifier));
}
for (Map.Entry<Integer, Object[]> entry : MODIFIER_METHODS.entrySet()) {
Integer modifier = entry.getKey();
Method method = (Method) entry.getValue()[0];
String msgSuffix = (String) entry.getValue()[1];
if (modifiers.get(modifier))
if (modifiers.contains(modifier))
assertTrue((Boolean) method.invoke(null, member.getModifiers()),
msg != null ? msg : member.getName() + " must be " + msgSuffix);
errorMsg != null ? errorMsg : member.getName() + " must be " + msgSuffix);
else
assertFalse((Boolean) method.invoke(null, member.getModifiers()),
msg != null ? msg : member.getName() + " must not be " + msgSuffix);
errorMsg != null ? errorMsg : member.getName() + " must not be " + msgSuffix);
}
} catch (ReflectiveOperationException e) {
e.printStackTrace();
......
......@@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.List;
import static h05.Assertions.*;
import static h05.Utils.*;
......@@ -54,10 +54,10 @@ public class ListItemTest {
key.setAccessible(true);
next.setAccessible(true);
assertHasModifiers(key, Map.of(PUBLIC, true));
assertHasModifiers(key, List.of(PUBLIC));
assertEquals("T", key.getGenericType().getTypeName(), "Type of field \"key\" is incorrect");
assertHasModifiers(next, Map.of(PUBLIC, true));
assertHasModifiers(next, List.of(PUBLIC));
assertEquals("h05.ListItem<T>", next.getGenericType().getTypeName(), "Type of field \"next\" is incorrect");
......
......@@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.List;
import static h05.Assertions.*;
import static h05.Utils.*;
......@@ -50,7 +50,7 @@ public class MyTreeNodeTest {
fail(CLASS_NAME + " is missing a required constructor", e);
}
assertHasModifiers(constructor, Map.of(PUBLIC, true), "Constructor of " + CLASS_NAME + " must be public");
assertHasModifiers(constructor, List.of(PUBLIC), "Constructor of " + CLASS_NAME + " must be public");
// fields
try {
......@@ -60,10 +60,10 @@ public class MyTreeNodeTest {
fail(CLASS_NAME + " is missing one or more required fields", e);
}
assertHasModifiers(nodeID, Map.of(PUBLIC, true, STATIC, false, FINAL, true));
assertHasModifiers(nodeID, List.of(PUBLIC, FINAL));
assertEquals(long.class, nodeID.getType(), "nodeID must be of type long");
assertHasModifiers(successors, Map.of(PUBLIC, true, STATIC, false, FINAL, false));
assertHasModifiers(successors, List.of(PUBLIC));
assertEquals("h05.ListItem<h05.MyTreeNode>", successors.getGenericType().getTypeName(),
"successors must be of type ListItem<MyTreeNode>");
......
......@@ -16,7 +16,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.Stack;
import static h05.Assertions.*;
......@@ -63,7 +63,7 @@ public class MyTreeTest {
fail(CLASS_NAME + " is missing a required constructor", e);
}
assertHasModifiers(constructor, Map.of(PUBLIC, true), "Constructor of " + CLASS_NAME + " must be public");
assertHasModifiers(constructor, List.of(PUBLIC), "Constructor of " + CLASS_NAME + " must be public");
// fields
try {
......@@ -76,10 +76,10 @@ public class MyTreeTest {
root.setAccessible(true);
nextNodeID.setAccessible(true);
assertHasModifiers(root, Map.of(PRIVATE, true, STATIC, false, FINAL, false));
assertHasModifiers(root, List.of(PRIVATE));
assertEquals(MyTreeNodeTest.myTreeNodeClass, root.getType(), "root must be of type MyTreeNode");
assertHasModifiers(nextNodeID, Map.of(PRIVATE, true, STATIC, true, FINAL, false));
assertHasModifiers(nextNodeID, List.of(PRIVATE, STATIC));
assertEquals(long.class, nextNodeID.getType(), "nextNodeID must be of type long");
// methods
......@@ -92,7 +92,7 @@ public class MyTreeTest {
fail(CLASS_NAME + " is missing one or more required methods", e);
}
assertHasModifiers(buildRecursively, Map.of(PRIVATE, true, STATIC, false));
assertHasModifiers(buildRecursively, List.of(PRIVATE));
assertEquals(MyTreeNodeTest.myTreeNodeClass, buildRecursively.getReturnType(),
"buildRecursively does not have return type MyTreeNode");
assertTrue(() -> {
......@@ -107,7 +107,7 @@ public class MyTreeTest {
return hasBadStringOperationException && hasIOException;
}, "buildRecursively does not throw all required potential exceptions");
assertHasModifiers(buildIteratively, Map.of(PRIVATE, true, STATIC, false));
assertHasModifiers(buildIteratively, List.of(PRIVATE));
assertEquals(MyTreeNodeTest.myTreeNodeClass, buildIteratively.getReturnType(),
"buildIteratively does not have return type MyTreeNode");
assertTrue(() -> {
......@@ -122,7 +122,7 @@ public class MyTreeTest {
return hasBadStringOperationException && hasIOException;
}, "buildIteratively does not throw all required potential exceptions");
assertHasModifiers(isIsomorphic, Map.of(PUBLIC, true, STATIC, false));
assertHasModifiers(isIsomorphic, List.of(PUBLIC));
assertEquals(boolean.class, isIsomorphic.getReturnType(), "isIsomorphic does not have return type boolean");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment