diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-25 17:44:32 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-25 17:44:32 +0000 |
| commit | 0a4c805808f6470943773bc1fd5333662f9f5c2b (patch) | |
| tree | 2b5678e667dd810d539bee61d222ac2d18e7a432 | |
| parent | a435bc428f92f0e5c762a0a578e230cd7756ad37 (diff) | |
Remove lombok from VariableDeclaration
3 files changed, 129 insertions, 23 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/VariableDeclaration.java b/src/main/java/org/zwobble/couscous/ast/VariableDeclaration.java index 84c0d43..713f3a6 100644 --- a/src/main/java/org/zwobble/couscous/ast/VariableDeclaration.java +++ b/src/main/java/org/zwobble/couscous/ast/VariableDeclaration.java @@ -1,10 +1,72 @@ package org.zwobble.couscous.ast; -import lombok.Value; - -@Value(staticConstructor="var") public class VariableDeclaration { - String id; - String name; - TypeName type; + public static VariableDeclaration var(String id, String name, TypeName type) { + return new VariableDeclaration(id, name, type); + } + + private final String id; + private final String name; + private final TypeName type; + + private VariableDeclaration(String id, String name, TypeName type) { + this.id = id; + this.name = name; + this.type = type; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public TypeName getType() { + return type; + } + + @Override + public String toString() { + return "VariableDeclaration(id=" + id + ", name=" + name + ", type=" + + type + ")"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + VariableDeclaration other = (VariableDeclaration) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } } diff --git a/src/main/java/org/zwobble/couscous/util/ExtraArrays.java b/src/main/java/org/zwobble/couscous/util/ExtraArrays.java index c4ebc57..457b77b 100644 --- a/src/main/java/org/zwobble/couscous/util/ExtraArrays.java +++ b/src/main/java/org/zwobble/couscous/util/ExtraArrays.java @@ -1,11 +1,18 @@ package org.zwobble.couscous.util; import java.util.Arrays; +import java.util.function.BiFunction; import java.util.function.Function; +import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class ExtraArrays { + public static <T, R> Stream<R> mapWithIndex(T[] array, BiFunction<Integer, T, R> function) { + return IntStream.range(0, array.length) + .mapToObj(index -> function.apply(index, array[index])); + } + public static <T, R> Stream<R> map(T[] array, Function<T, R> function) { return stream(array).map(function); } diff --git a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java index f31ec65..287d6a8 100644 --- a/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java +++ b/src/test/java/org/zwobble/couscous/tests/ValueObjectTests.java @@ -4,12 +4,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.function.Function; import java.util.stream.IntStream; +import java.util.stream.Stream; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.zwobble.couscous.ast.AnnotationNode; +import org.zwobble.couscous.ast.VariableDeclaration; import org.zwobble.couscous.util.ExtraArrays; import com.google.common.base.Joiner; @@ -30,7 +32,8 @@ public class ValueObjectTests { @Parameters(name="{0} is value object") public static Iterable<Object[]> valueObjectTypes() { return asList(new Object[][] { - {AnnotationNode.class} + {AnnotationNode.class}, + {VariableDeclaration.class} }); } @@ -49,19 +52,48 @@ public class ValueObjectTests { } @Test - public void equalityIncludesAllFields() { - assertEquals(generateInstance(clazz), generateInstance(clazz)); - assertNotEquals( + public void equalityAndHashCodeIncludeAllFields() throws Exception { + assertEqualsWithHashCode(generateInstance(clazz), generateInstance(clazz)); + + generateInstancesWithSlightDifference(clazz) + .forEach(instance -> { + assertNotEqualsWithHashCode( + generateFirstInstance(clazz), + instance); + }); + + assertNotEqualsWithHashCode( generateFirstInstance(clazz), generateSecondInstance(clazz)); } - - @Test - public void hashCodeIncludesAllFields() { - assertEquals(generateInstance(clazz).hashCode(), generateInstance(clazz).hashCode()); - assertNotEquals( - generateFirstInstance(clazz).hashCode(), - generateSecondInstance(clazz).hashCode()); + + private static void assertEqualsWithHashCode(Object first, Object second) { + assertEquals(first, second); + assertEquals(first.hashCode(), second.hashCode()); + } + + private static void assertNotEqualsWithHashCode(Object first, Object second) { + assertNotEquals(first, second); + assertNotEquals(first.hashCode(), second.hashCode()); + } + + private static Stream<Object> generateInstancesWithSlightDifference(Class<?> clazz) { + Class<?>[] fieldTypes = fieldTypes(clazz); + Method constructor = findStaticConstructor(clazz); + + return IntStream.range(0, fieldTypes.length) + .mapToObj(index -> { + Object[] arguments = ExtraArrays.mapWithIndex( + fieldTypes, + (argumentIndex, fieldType) -> + argumentIndex == index ? generateSecondInstance(fieldType) : generateFirstInstance(fieldType)) + .toArray(Object[]::new); + try { + return constructor.invoke(null, arguments); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); } private static Object generateFirstInstance(Class<?> type) { @@ -74,7 +106,7 @@ public class ValueObjectTests { private static Object generateSecondInstance(Class<?> type) { if (type.equals(String.class)) { - return "[string ]"; + return "[string 2]"; } else { return generateValue(type, ValueObjectTests::generateSecondInstance).instance; } @@ -90,10 +122,8 @@ public class ValueObjectTests { private static GeneratedValue generateValue(Class<?> type, Function<Class<?>, Object> generate) { try { - Field[] fields = type.getDeclaredFields(); - Class<?>[] fieldTypes = ExtraArrays.map(fields, field -> field.getType()) - .toArray(Class<?>[]::new); - Method constructor = findStaticConstructor(type, fieldTypes); + Class<?>[] fieldTypes = fieldTypes(type); + Method constructor = findStaticConstructor(type); Object[] arguments = ExtraArrays.map(fieldTypes, fieldType -> generate.apply(fieldType)) .toArray(Object[]::new); Object instance = constructor.invoke(null, arguments); @@ -102,8 +132,15 @@ public class ValueObjectTests { throw new RuntimeException(e); } } + + private static Class<?>[] fieldTypes(Class<?> type) { + Field[] fields = type.getDeclaredFields(); + return ExtraArrays.map(fields, field -> field.getType()) + .toArray(Class<?>[]::new); + } - private static Method findStaticConstructor(Class<?> type, Class<?>[] fieldTypes) { + private static Method findStaticConstructor(Class<?> type) { + Class<?>[] fieldTypes = fieldTypes(type); return stream(type.getDeclaredMethods()) .filter(method -> isStaticConstructor(type, fieldTypes, method)) .findAny() |
