package com.spotify.heroic.grammar; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; import static com.spotify.heroic.grammar.ExpressionTests.visitorTest; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; @RunWith(MockitoJUnitRunner.class) public abstract class AbstractExpressionTest<E extends Expression> { private final ParseException e = new ParseException("", null, 0, 0, 0, 0); @Mock protected Context ctx; @Mock protected Expression.Scope scope; @Mock protected Expression lookup; @Mock protected Expression a; @Mock protected Expression b; @Before public final void abstractSetup() { doReturn(lookup).when(scope).lookup(eq(ctx), anyString()); doReturn(lookup).when(lookup).eval(scope); doReturn(a).when(a).eval(scope); doReturn(b).when(b).eval(scope); doReturn("a").when(a).toString(); doReturn("b").when(b).toString(); doReturn("a").when(a).toRepr(); doReturn("b").when(b).toRepr(); doReturn(e).when(ctx).castError(anyObject(), any(Class.class)); } protected abstract E build(Context ctx); protected abstract BiFunction<Expression.Visitor<Void>, E, Void> visitorMethod(); protected E build() { return build(ctx); } protected Stream<Consumer<E>> accessors() { return Stream.of(); } protected <V> Consumer<E> accessorTest(final V expected, final Function<E, V> accessor) { return e -> { assertEquals(expected, accessor.apply(e)); }; } @Test public void getContextTest() { final E expr = build(); assertEquals(ctx, expr.getContext()); } @Test public void visitTest() { visitorTest(build(), visitorMethod()); } @Test public void selfCastTest() { final E expr = build(); assertEquals(expr, expr.cast(expr.getClass())); } @Test public void evalTest() { build().eval(scope); } @Test public final void accessorsTest() { final E e = build(); accessors().forEach(accessor -> { accessor.accept(e); }); } @Test public void toStringTest() { final String str = build().toString(); assertFalse(str.isEmpty()); // assert that default Object#toString has been overriden. assertFalse(str.startsWith("java.lang.Object")); } @Test(expected = ParseException.class) public void castErrorTest() { build().cast(IllegalExpression.class); } interface IllegalExpression extends Expression { } }