io.agistep.event.test.EventSourcingAssertions Maven / Gradle / Ivy
The newest version!
package io.agistep.event.test;
import io.agistep.aggregator.IdUtils;
import io.agistep.event.Event;
import io.agistep.event.EventSource;
import org.assertj.core.api.ObjectAssert;
import java.util.function.Consumer;
import java.util.function.Supplier;
import static io.agistep.event.test.EventFixtureBuilder.eventsWith;
import static io.agistep.event.test.EventMatchConditions.*;
import static org.assertj.core.api.Assertions.assertThat;
public final class EventSourcingAssertions {
public static XYZ assertEventSourcing() {
return new XYZ<>();
}
public static ABC assertEventSourcing(Supplier initAggregate) {
return new ABC<>(initAggregate);
}
public static class ABC {
private final Supplier initAggregate;
ABC(Supplier initAggregate) {
this.initAggregate = initAggregate;
}
public DEF given() {
return given(new Event[0]);
}
public DEF given(Object first, Object ... payloads) {
// TODO first 가 null이면
EventFixtureBuilder eventsWith = eventsWith(first);
for (int i = 0; i < payloads.length; ++i) {
eventsWith.next(payloads[i]);
}
return new DEF<>(initAggregate, eventsWith.build());
}
public DEF given(Event ... recently) {
return new DEF<>(initAggregate, recently);
}
}
public static class DEF {
private final Supplier initAggregate;
private final Event[] recently;
DEF(Supplier initAggregate, Event[] recently) {
this.initAggregate = initAggregate;
this.recently = recently;
}
public HIG when(Consumer aggregateProcessor) {
return new HIG<>(this, aggregateProcessor);
}
}
public static class XYZ {
XYZ() {
}
public FFF when(Supplier aggregateProcessor) {
return new FFF<>(this, aggregateProcessor);
}
}
public static class HIG {
private final DEF def;
private final Consumer aggregateProcessor;
public HIG(DEF def, Consumer aggregateProcessor) {
this.def = def;
this.aggregateProcessor = aggregateProcessor;
}
public void doTest() {
Pair pair = getPair(def.recently, def.initAggregate);
aggregateProcessor.accept(pair.aggregate);
}
public ObjectAssert expected(Object ... payloads) {
return assertThat(testEventSourcing(
def.initAggregate,
def.recently,
aggregateProcessor,
payloads));
}
private AGG testEventSourcing(Supplier initAggregate, Event[] recently, Consumer aggregateProcessor, Object[] expected) {
Pair pair = getPair(recently, initAggregate);
aggregateProcessor.accept(pair.aggregate);
abc(pair.aggregate, pair.latestSeq, expected);
return pair.aggregate;
}
private Pair getPair(Event[] recently, Supplier initAggregate) {
AGG aggregate = initAggregate.get();
EventSource.replay(aggregate, recently);
final long latestSeq = getLatestSeq(aggregate);
return new Pair<>(aggregate, latestSeq);
}
private static long getLatestSeq(Object aggregate) {
long seq;
try {
seq = EventSource.getLatestSeqOf(aggregate);
if(EventSource.getHoldEvents(aggregate).isEmpty()) {
return seq;
}else {
return seq - EventSource.getHoldEvents(aggregate).size();
}
} catch (Exception e) {
return -1;
}
}
private void abc(Object aggregate, long seq, Object... expectedPayload) {
final long aggregateId = IdUtils.idOf(aggregate);
Event[] expected = getExpected(aggregateId, seq, expectedPayload);
Event[] actual = getActual(aggregateId);
assertThat(actual.length).isEqualTo(expected.length);
for (int i = 0; i < expected.length; i++) {
//assertThat(actual[i]).is(idCondition(expected[i]));
assertThat(actual[i]).is(aggregateIdCondition(expected[i]));
assertThat(actual[i]).is(seqCondition(expected[i]));
assertThat(actual[i]).is(nameCondition(expected[i]));
assertThat(actual[i]).is(payloadCondition(expected[i]));
assertThat(actual[i]).is(occurredAtCondition(expected[i]));
}
HoldingEventLogger.init().clear();
EventSource.clearAll();
}
private Event[] getActual(long aggregateId) {
return HoldingEventLogger.init().getEvent(aggregateId);
}
private static Event[] getExpected(long aggregateId, long seq, Object[] expectedPayload) {
if (expectedPayload == null || expectedPayload.length == 0) {
return new Event[0];
}
EventFixtureBuilder eventsWith = eventsWith(aggregateId, expectedPayload[0]);
for (int i = 1; i < expectedPayload.length; ++i) {
eventsWith.next(expectedPayload[i]);
}
return eventsWith.build(seq);
}
}
public static class FFF {
private final XYZ xyz;
private final Supplier aggregateProcessor;
public FFF(XYZ xyz, Supplier aggregateProcessor) {
this.xyz = xyz;
this.aggregateProcessor = aggregateProcessor;
}
public ObjectAssert expected(Object ... payloads) {
return assertThat(testEventSourcing(
aggregateProcessor,
payloads));
}
private AGG testEventSourcing(Supplier aggregateProcessor, Object[] expected) {
AGG aggregate = aggregateProcessor.get();
abc(aggregate, expected);
return aggregate;
}
private static long getLatestSeq(Object aggregate) {
try {
long seq = EventSource.getLatestSeqOf(aggregate);
if(EventSource.getHoldEvents(aggregate).isEmpty()) {
return seq;
}else {
return seq - EventSource.getHoldEvents(aggregate).size();
}
} catch (Exception e) {
return -1;
}
}
private void abc(Object aggregate, Object... expectedPayload) {
final long aggregateId = IdUtils.idOf(aggregate);
final long latestSeq = getLatestSeq(aggregate);
Event[] expected = getExpected(aggregateId, latestSeq, expectedPayload);
Event[] actual = getActual(aggregateId);
assertThat(actual.length).isEqualTo(expected.length);
for (int i = 0; i < expected.length; i++) {
//assertThat(actual[i]).is(idCondition(expected[i]));
assertThat(actual[i]).is(aggregateIdCondition(expected[i]));
assertThat(actual[i]).is(seqCondition(expected[i]));
assertThat(actual[i]).is(nameCondition(expected[i]));
assertThat(actual[i]).is(payloadCondition(expected[i]));
assertThat(actual[i]).is(occurredAtCondition(expected[i]));
}
HoldingEventLogger.init().clear();
EventSource.clearAll();
}
private Event[] getActual(long aggregateId) {
return HoldingEventLogger.init().getEvent(aggregateId);
}
private static Event[] getExpected(long aggregateId, long seq, Object[] expectedPayload) {
if (expectedPayload == null || expectedPayload.length == 0) {
return new Event[0];
}
EventFixtureBuilder eventsWith = eventsWith(aggregateId, expectedPayload[0]);
for (int i = 1; i < expectedPayload.length; ++i) {
eventsWith.next(expectedPayload[i]);
}
return eventsWith.build(seq);
}
}
private static class Pair {
final AGG aggregate;
final long latestSeq;
Pair(AGG aggregate, long latestSeq) {
this.aggregate = aggregate;
this.latestSeq = latestSeq;
}
}
}