Created
October 30, 2016 23:13
-
-
Save Tzrlk/4085e88b2bae3f5b046fff37ac93b905 to your computer and use it in GitHub Desktop.
equatable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Equatable<T> { | |
Equatator<T> getEquatator(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Equatator<T> { | |
<L extends T, R extends T> boolean equatable(L left, R right); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static org.mockito.Mockito.spy; | |
public class MethodArgument<T> implements Equatable<T> { | |
public static <T> MethodArgument<T> arg(T value, Equatator<T> equatator) { | |
return new MethodArgument<>(value, value.getClass(), equatator); | |
} | |
public static <T> MethodArgument<T> arg(T value, Class type, Equatator<T> equatator) { | |
return new MethodArgument<>(value, type, equatator); | |
} | |
public static Object[] getValues(MethodArgument<?>[] args) { | |
final Object[] objects = new Object[args.length]; | |
for (int idx = 0; idx < args.length; idx++) { | |
objects[idx] = args[idx].toSpy(); | |
} | |
return objects; | |
} | |
public static Class<?>[] getTypes(MethodArgument<?>[] args) { | |
final Class<?>[] types = new Class[args.length]; | |
for (int idx = 0; idx < args.length; idx++) { | |
types[idx] = args[idx].type; | |
} | |
return types; | |
} | |
private final T value; | |
private final Class type; | |
private final Equatator<T> equatator; | |
private MethodArgument(T value, Class type, Equatator<T> equatator) { | |
this.value = value; | |
this.type = type; | |
this.equatator = equatator; | |
} | |
public T toSpy() { | |
return !type.isPrimitive() | |
? spy(value) | |
: value; | |
} | |
@Override | |
public Equatator<T> getEquatator() { | |
return equatator; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import static bravura.utils.abtesting.matchers.EquatableMatcher.equatableTo; | |
import static bravura.utils.abtesting.equatators.ExceptionEquatator.exceptionEquatator; | |
import static org.hamcrest.CoreMatchers.is; | |
import static org.junit.Assert.assertThat; | |
public final class MethodEquatator { | |
public static <T> void check(String methodName, MethodArgument[] args, Equatator<T> sameAs) | |
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { | |
Object[] args1 = MethodArgument.getValues(args).clone(); | |
Method method1 = DateFunctions.class.getDeclaredMethod(methodName, MethodArgument.getTypes(args)); | |
T result1 = null; | |
Exception error1 = null; | |
try { | |
result1 = (T) method1.invoke(null, args1); | |
} catch (InvocationTargetException | IllegalAccessException error) { | |
throw error; | |
} catch (Exception error) { | |
error1 = error; | |
} | |
Object[] args2 = MethodArgument.getValues(args).clone(); | |
Method method2 = DateFunctionsOriginal.class.getDeclaredMethod(methodName, MethodArgument.getTypes(args)); | |
T result2 = null; | |
Exception error2 = null; | |
try { | |
result2 = (T) method2.invoke(null, args2); | |
} catch (InvocationTargetException | IllegalAccessException error) { | |
throw error; | |
} catch (Exception error) { | |
error2 = error; | |
} | |
for (int idx = 0; idx < args.length; idx++) { | |
assertThat("Input arguments should have the same side-effects", | |
args1[idx], is(equatableTo(args2[idx], args[idx].getEquatator()))); | |
} | |
assertThat("The results should be the same.", | |
result1, is(equatableTo(result2, sameAs))); | |
assertThat("The errors should be the same.", | |
error1, is(equatableTo(error2, exceptionEquatator))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment