diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-25 11:03:10 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-25 11:10:23 +0000 |
| commit | b9b353b5b9485f41288df16431070aa658595956 (patch) | |
| tree | a76be84d53027af1ba184863f909294a35736c83 /src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java | |
| parent | 334f4b5a198fb025c698bc60506316cc55c5f4b1 (diff) | |
Add test for AnnotationNode.toString()
Diffstat (limited to 'src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java')
| -rw-r--r-- | src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java b/src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java new file mode 100644 index 0000000..2eb8d9c --- /dev/null +++ b/src/test/java/org/zwobble/couscous/tests/AnnotationNodeTests.java @@ -0,0 +1,80 @@ +package org.zwobble.couscous.tests; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.stream.IntStream; + +import org.junit.Test; +import org.zwobble.couscous.ast.AnnotationNode; +import org.zwobble.couscous.util.ExtraArrays; + +import com.google.common.base.Joiner; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.zwobble.couscous.util.ExtraArrays.stream; + +public class AnnotationNodeTests { + @Test + public void annotationNodeIsValueObject() throws Exception { + assertIsValueObject(AnnotationNode.class); + } + + private <T> void assertIsValueObject(Class<T> clazz) throws Exception { + GeneratedValue value = generateValue(clazz); + Field[] fields = clazz.getDeclaredFields(); + Object[] fieldStrings = IntStream.range(0, fields.length) + .mapToObj(index -> String.format("%s=%s", fields[index].getName(), value.arguments[index])) + .toArray(); + assertEquals( + String.format("%s(%s)", + clazz.getSimpleName(), + Joiner.on(", ").join(fieldStrings)), + value.instance.toString()); + } + + private GeneratedValue generateValue(Class<?> type) { + try { + Field[] fields = type.getDeclaredFields(); + Class<?>[] fieldTypes = ExtraArrays.map(fields, field -> field.getType()) + .toArray(Class<?>[]::new); + Method constructor = findStaticConstructor(type, fieldTypes); + Object[] arguments = ExtraArrays.map(fieldTypes, fieldType -> generateInstance(fieldType)) + .toArray(Object[]::new); + Object instance = constructor.invoke(null, arguments); + return new GeneratedValue(instance, arguments); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Object generateInstance(Class<?> type) { + if (type.equals(String.class)) { + return "[string]"; + } else { + return generateValue(type).instance; + } + } + + private Method findStaticConstructor(Class<?> type, Class<?>[] fieldTypes) { + return stream(type.getDeclaredMethods()) + .filter(method -> isStaticConstructor(type, fieldTypes, method)) + .findAny() + .orElseThrow(() -> new RuntimeException("Could not find static constructor for " + type)); + } + + private boolean isStaticConstructor(Class<?> type, Class<?>[] fieldTypes, Method method) { + return method.getReturnType().equals(type) && + asList(fieldTypes).equals(asList(method.getParameterTypes())); + } + + private class GeneratedValue { + private final Object instance; + private final Object[] arguments; + + public GeneratedValue(Object value, Object[] arguments) { + this.instance = value; + this.arguments = arguments; + } + } +} |
