All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy