Skip to content

Commit e3158d1

Browse files
nomicfluxjnape
authored andcommitted
Cleaned up type params; made double-run effects clearer
1 parent 2b659fb commit e3158d1

File tree

2 files changed

+71
-38
lines changed

2 files changed

+71
-38
lines changed
Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
package com.jnape.palatable.lambda.matchers;
22

33
import com.jnape.palatable.lambda.adt.Either;
4-
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
5-
import com.jnape.palatable.lambda.io.IO;
6-
import com.jnape.palatable.lambda.monad.MonadRec;
74
import com.jnape.palatable.lambda.monad.transformer.builtin.StateT;
85
import org.junit.Test;
96
import testsupport.matchers.StateTMatcher;
107

118
import java.util.concurrent.atomic.AtomicInteger;
129

1310
import static com.jnape.palatable.lambda.adt.Either.left;
11+
import static com.jnape.palatable.lambda.adt.Either.right;
1412
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1513
import static com.jnape.palatable.lambda.io.IO.io;
1614
import static com.jnape.palatable.lambda.monad.transformer.builtin.StateT.stateT;
15+
import static org.hamcrest.CoreMatchers.not;
1716
import static org.hamcrest.MatcherAssert.assertThat;
1817
import static org.hamcrest.core.IsEqual.equalTo;
1918
import static org.junit.Assert.assertEquals;
@@ -25,37 +24,57 @@
2524
public class StateTMatcherTest {
2625

2726
@Test
28-
public void whenEvalWithMatcher() {
29-
assertThat(stateT(Either.right(1)),
30-
StateTMatcher.whenEvaluatedWith("0", isRightThat(equalTo(1))));
27+
public void whenEvaluatedWithMatcher() {
28+
assertThat(stateT(right(1)),
29+
whenEvaluatedWith("0", isRightThat(equalTo(1))));
3130
}
3231

3332
@Test
34-
public void whenExecWithMatcher() {
35-
assertThat(stateT(Either.right(1)),
33+
public void whenEvaluatedWithMatcherOnObject() {
34+
assertThat(stateT(right(1)),
35+
whenEvaluatedWith("0", not(equalTo(new Object()))));
36+
}
37+
38+
@Test
39+
public void whenExecutedWithMatcher() {
40+
assertThat(stateT(right(1)),
3641
whenExecutedWith(left("0"), isRightThat(isLeftThat(equalTo("0")))));
3742
}
3843

44+
45+
@Test
46+
public void whenExecutedWithMatcherOnObject() {
47+
assertThat(stateT(right(1)),
48+
whenExecutedWith(left("0"), not(equalTo(new Object()))));
49+
}
50+
3951
@Test
4052
public void whenRunWithUsingTwoMatchers() {
41-
assertThat(stateT(Either.right(1)),
42-
StateTMatcher.<Either<String, Integer>, Either<String, ?>, Integer, Either<String, Integer>, Either<String, Either<String, Integer>>, Either<String, Tuple2<Integer, Either<String, Integer>>>>whenRunWith(left("0"),
43-
isRightThat(equalTo(1)), isRightThat(isLeftThat(equalTo("0")))));
53+
//noinspection RedundantTypeArguments
54+
assertThat(stateT(right(1)),
55+
StateTMatcher.<Either<String, Object>, Either<Object, ?>, Integer, Either<Object, Integer>, Either<Object, Either<String, Object>>>whenRunWithBoth(left("0"),
56+
isRightThat(equalTo(1)),
57+
isRightThat(isLeftThat(equalTo("0")))));
4458
}
4559

4660
@Test
4761
public void whenRunWithUsingOneTupleMatcher() {
48-
assertThat(stateT(Either.right(1)),
49-
StateTMatcher.<Either<String, Integer>, Either<String, ?>, Integer, Either<String, Integer>, Either<String, Either<String, Integer>>, Either<String, Tuple2<Integer, Either<String, Integer>>>>whenRunWith(left("0"),
62+
assertThat(stateT(right(1)),
63+
whenRunWith(left("0"),
5064
isRightThat(equalTo(tuple(1, left("0"))))));
5165
}
5266

67+
@Test
68+
public void whenRunWithUsingOneTupleMatcherOnObject() {
69+
assertThat(stateT(right(1)),
70+
whenRunWith(left("0"), not(equalTo(new Object()))));
71+
}
72+
5373
@Test
5474
public void onlyRunsStateOnceWithTupleMatcher() {
5575
AtomicInteger count = new AtomicInteger(0);
5676

57-
assertThat(StateT.gets(s -> io(count::incrementAndGet)),
58-
StateTMatcher.<Integer, IO<?>, Integer, IO<Integer>, IO<Integer>, IO<Tuple2<Integer, Integer>>>whenRunWith(0, yieldsValue(equalTo(tuple(1, 0)))));
77+
assertThat(StateT.gets(s -> io(count::incrementAndGet)), whenRunWith(0, yieldsValue(equalTo(tuple(1, 0)))));
5978
assertEquals(1, count.get());
6079
}
6180
}

src/test/java/testsupport/matchers/StateTMatcher.java

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
import static com.jnape.palatable.lambda.io.IO.io;
1515
import static org.hamcrest.Matchers.equalTo;
1616

17-
public class StateTMatcher<S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> extends TypeSafeMatcher<StateT<S, M, A>> {
17+
public class StateTMatcher<S, M extends MonadRec<?, M>, A> extends TypeSafeMatcher<StateT<S, M, A>> {
1818
private final S initialState;
1919

20-
private final Either<Matcher<? super MTS>, These<Matcher<? super MA>, Matcher<? super MS>>> matcher;
20+
private final Either<Matcher<? super MonadRec<Tuple2<A, S>, M>>, These<Matcher<? super MonadRec<A, M>>, Matcher<? super MonadRec<S, M>>>> matcher;
2121

22-
private StateTMatcher(S initialState, These<Matcher<? super MA>, Matcher<? super MS>> matchers) {
22+
private StateTMatcher(S initialState, These<Matcher<? super MonadRec<A, M>>, Matcher<? super MonadRec<S, M>>> matchers) {
2323
this.initialState = initialState;
2424
this.matcher = right(matchers);
2525
}
2626

27-
private StateTMatcher(S initialState, Matcher<? super MTS> matcher) {
27+
private StateTMatcher(S initialState, Matcher<? super MonadRec<Tuple2<A, S>, M>> matcher) {
2828
this.initialState = initialState;
2929
this.matcher = left(matcher);
3030
}
@@ -44,9 +44,9 @@ public void describeTo(Description description) {
4444
theseMatchers -> theseMatchers.match(a -> io(() -> a.describeTo(description.appendText("Value matching "))),
4545
b -> io(() -> b.describeTo(description.appendText("State matching "))),
4646
ab -> io(() -> {
47-
description.appendText("Value matching: ");
47+
description.appendText("Value run matching: ");
4848
ab._1().describeTo(description);
49-
description.appendText(" and state matching: ");
49+
description.appendText(", then state run matching: ");
5050
ab._2().describeTo(description);
5151
})))
5252
.unsafePerformIO();
@@ -69,46 +69,60 @@ protected void describeMismatchSafely(StateT<S, M, A> item, Description mismatch
6969
b.describeMismatch(ran.fmap(Tuple2::_2), mismatchDescription);
7070
}),
7171
ab -> io(() -> {
72-
mismatchDescription.appendText("value matching: ");
72+
mismatchDescription.appendText("value run matching: ");
7373
ab._1().describeMismatch(ran.fmap(Tuple2::_1), mismatchDescription);
74-
mismatchDescription.appendText(" and state matching: ");
74+
mismatchDescription.appendText(", then state run matching: ");
7575
ab._2().describeMismatch(ran.fmap(Tuple2::_2), mismatchDescription);
7676
})))
7777
.unsafePerformIO();
7878
}
7979

80-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenRunWith(S initialState, Matcher<? super MTS> bothMatcher) {
81-
return new StateTMatcher<>(initialState, bothMatcher);
80+
public static <S, M extends MonadRec<?, M>, A, MAS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A> whenRunWith(S initialState, Matcher<? super MAS> bothMatcher) {
81+
return new StateTMatcher<S, M, A>(initialState, extendMatcher(bothMatcher));
8282
}
8383

84-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenRun(S initialState, MTS both) {
84+
public static <S, M extends MonadRec<?, M>, A> StateTMatcher<S, M, A> whenRun(S initialState, MonadRec<Tuple2<A, S>, M> both) {
8585
return whenRunWith(initialState, equalTo(both));
8686
}
8787

88-
// Note: This constructor will run both matchers, which can run effects twice
89-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenRunWith(S initialState, Matcher<? super MA> valueMatcher, Matcher<? super MS> stateMatcher) {
90-
return new StateTMatcher<>(initialState, These.both(valueMatcher, stateMatcher));
88+
// Note: This constructor will run both matchers, which will run effects twice
89+
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>> StateTMatcher<S, M, A> whenRunWithBoth(S initialState, Matcher<? super MA> valueMatcher, Matcher<? super MS> stateMatcher) {
90+
return new StateTMatcher<S, M, A>(initialState, These.both(extendMatcher(valueMatcher), extendMatcher(stateMatcher)));
9191
}
9292

93-
// Note: This constructor will run both matchers, which can run effects twice
93+
// Note: This constructor will run both matchers, which will run effects twice
9494
@SuppressWarnings("unused")
95-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenRun(S initialState, MA value, MS state) {
96-
return whenRunWith(initialState, equalTo(value), equalTo(state));
95+
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>> StateTMatcher<S, M, A> whenRunBoth(S initialState, MonadRec<A, M> value, MonadRec<S, M> state) {
96+
return whenRunWithBoth(initialState, equalTo(value), equalTo(state));
9797
}
9898

99-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenExecutedWith(S initialState, Matcher<? super MS> stateMatcher) {
100-
return new StateTMatcher<>(initialState, These.b(stateMatcher));
99+
public static <S, M extends MonadRec<?, M>, A, MS extends MonadRec<S, M>> StateTMatcher<S, M, A> whenExecutedWith(S initialState, Matcher<? super MS> stateMatcher) {
100+
return new StateTMatcher<S, M, A>(initialState, These.b(extendMatcher(stateMatcher)));
101101
}
102102

103-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenExecuted(S initialState, MS state) {
103+
public static <S, M extends MonadRec<?, M>, A> StateTMatcher<S, M, A> whenExecuted(S initialState, MonadRec<S, M> state) {
104104
return whenExecutedWith(initialState, equalTo(state));
105105
}
106106

107-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenEvaluatedWith(S initialState, Matcher<? super MA> valueMatcher) {
108-
return new StateTMatcher<>(initialState, These.a(valueMatcher));
107+
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>> StateTMatcher<S, M, A> whenEvaluatedWith(S initialState, Matcher<? super MA> valueMatcher) {
108+
return new StateTMatcher<S, M, A>(initialState, These.a(extendMatcher(valueMatcher)));
109109
}
110110

111-
public static <S, M extends MonadRec<?, M>, A, MA extends MonadRec<A, M>, MS extends MonadRec<S, M>, MTS extends MonadRec<Tuple2<A, S>, M>> StateTMatcher<S, M, A, MA, MS, MTS> whenEvaluated(S initialState, MA value) {
111+
public static <S, M extends MonadRec<?, M>, A> StateTMatcher<S, M, A> whenEvaluated(S initialState, MonadRec<A, M> value) {
112112
return whenEvaluatedWith(initialState, equalTo(value));
113113
}
114+
115+
private static <X, M extends MonadRec<?, M>, MX extends MonadRec<X, M>> Matcher<MonadRec<X, M>> extendMatcher(Matcher<? super MX> matcher) {
116+
return new TypeSafeMatcher<MonadRec<X, M>>() {
117+
@Override
118+
protected boolean matchesSafely(MonadRec<X, M> item) {
119+
return matcher.matches(item);
120+
}
121+
122+
@Override
123+
public void describeTo(Description description) {
124+
matcher.describeTo(description);
125+
}
126+
};
127+
}
114128
}

0 commit comments

Comments
 (0)