// Path: core/src/test/java/eventsrc4j/EventStorageSpec.java
// public final class EventStorageSpec<K, S, E> implements WStreamAction.Factory<K, S, E> {
// 
//   private final Gen<K> keys;
// 
//   private final Gen<E> events;
// 
//   public EventStorageSpec(Gen<K> keys, Gen<E> events) {
//     this.keys = keys;
//     this.events = events;
//   }
// 
//   public Property read_return_write(EventStorage<K, S, E> eventStorage) {
//     return property(keys, events, key -> event -> {
// 
//       WritableEventStream<K, S, E> stream = eventStorage.stream(key);
// 
//       Option<S> lastSeq =
//           stream.read(none(), Fold.last())
//               .runUnchecked()
//               .map(Events::getSeq);
// 
//       WriteResult<K, S, E> writeResult = stream
//           .write(lastSeq, Instant.EPOCH, singletonList(event))
//           .runUnchecked();
// 
//       return prop(
//           writeResult.events().map(
//               writtenEvents -> writtenEvents.length() == 1
//                   && writtenEvents.equals(stream
//                   .read(lastSeq, Fold.toList())
//                   .runUnchecked())
//           ).orSome(false)
//       );
//     });
//   }
// 
//   public Property read_return_write_actions(
//       Function<K, Predicate<WStreamAction<K, S, E, Boolean>>> actionInterpreter) {
//     return property(keys, events, key -> event -> {
// 
//       WStreamAction<K, S, E, Option<S>> lastSeqA = ReadEventStream(Option.none(), Fold.last())
//           .map(last -> last.map(Events::getSeq));
// 
//       WStreamAction<K, S, E, Boolean> compareEventsA = lastSeqA.bind(lastSeq -> {
// 
//             WStreamAction<K, S, E, List<Event<K, S, E>>> writeEventsA =
//                 WriteEvents(lastSeq, Instant.EPOCH, single(event))
//                     .map(WriteResults::getEvents)
//                     .map(es -> es.orSome(nil()));
// 
//             WStreamAction<K, S, E, List<Event<K, S, E>>> readEventsA = ReadEventStream(lastSeq, Fold.toList());
// 
//             return writeEventsA.bind(writtenEvents ->
//                 readEventsA.map(readEvents -> writtenEvents.length() == 1 && writtenEvents.equals(readEvents))
//             );
//           }
//       );
// 
//       return prop(actionInterpreter.apply(key).test(compareEventsA));
//     });
//   }
// 
//   public Property concurrent_write_fails(EventStorage<K, S, E> eventStorage) {
//     return property(keys, events, key -> event -> {
// 
//       WritableEventStream<K, S, E> stream = eventStorage.stream(key);
// 
//       Option<S> lastSeq =
//           stream.read(none(), Fold.last())
//               .runUnchecked()
//               .map(Events::getSeq);
// 
//       stream
//           .write(lastSeq, Instant.EPOCH, single(event))
//           .runUnchecked();
// 
//       WriteResult<K, S, E> concurrentWrite = stream
//           .write(lastSeq, Instant.EPOCH, single(event))
//           .runUnchecked();
// 
//       return prop(concurrentWrite.events().isNone());
//     });
//   }
// }
// 
// Path: core/src/main/java/eventsrc4j/Sequence.java
// public interface Sequence<S> extends Comparator<S> {
// 
//   S first();
// 
//   S next(S seq);
// 
//   Sequence<Long> longs = new Sequence<Long>() {
// 
//     public int compare(Long seq1, Long seq2) {
//       return seq1.compareTo(seq2);
//     }
// 
//     public Long first() {
//       return 1L;
//     }
// 
//     public Long next(Long seq) {
//       return seq + 1;
//     }
//   };
// }


import eventsrc4j.EventStorageSpec;
import eventsrc4j.Sequence;
import fj.test.Arbitrary;
import fj.test.Property;
import fj.test.reflect.CheckParams;
import fj.test.runner.PropertyTestRunner;
import org.junit.runner.RunWith;
import static fj.test.Gen.elements;
package eventsrc4j.memory;



@RunWith(PropertyTestRunner.class)
@CheckParams(maxSize = 10000, minSuccessful = 200)
public final class MemoryEventStorageTest {

  private static final EventStorageSpec<Integer, Long, MemoryEventStorageTest.Event> spec =
// Path: core/src/test/java/eventsrc4j/EventStorageSpec.java
// public final class EventStorageSpec<K, S, E> implements WStreamAction.Factory<K, S, E> {
// 
//   private final Gen<K> keys;
// 
//   private final Gen<E> events;
// 
//   public EventStorageSpec(Gen<K> keys, Gen<E> events) {
//     this.keys = keys;
//     this.events = events;
//   }
// 
//   public Property read_return_write(EventStorage<K, S, E> eventStorage) {
//     return property(keys, events, key -> event -> {
// 
//       WritableEventStream<K, S, E> stream = eventStorage.stream(key);
// 
//       Option<S> lastSeq =
//           stream.read(none(), Fold.last())
//               .runUnchecked()
//               .map(Events::getSeq);
// 
//       WriteResult<K, S, E> writeResult = stream
//           .write(lastSeq, Instant.EPOCH, singletonList(event))
//           .runUnchecked();
// 
//       return prop(
//           writeResult.events().map(
//               writtenEvents -> writtenEvents.length() == 1
//                   && writtenEvents.equals(stream
//                   .read(lastSeq, Fold.toList())
//                   .runUnchecked())
//           ).orSome(false)
//       );
//     });
//   }
// 
//   public Property read_return_write_actions(
//       Function<K, Predicate<WStreamAction<K, S, E, Boolean>>> actionInterpreter) {
//     return property(keys, events, key -> event -> {
// 
//       WStreamAction<K, S, E, Option<S>> lastSeqA = ReadEventStream(Option.none(), Fold.last())
//           .map(last -> last.map(Events::getSeq));
// 
//       WStreamAction<K, S, E, Boolean> compareEventsA = lastSeqA.bind(lastSeq -> {
// 
//             WStreamAction<K, S, E, List<Event<K, S, E>>> writeEventsA =
//                 WriteEvents(lastSeq, Instant.EPOCH, single(event))
//                     .map(WriteResults::getEvents)
//                     .map(es -> es.orSome(nil()));
// 
//             WStreamAction<K, S, E, List<Event<K, S, E>>> readEventsA = ReadEventStream(lastSeq, Fold.toList());
// 
//             return writeEventsA.bind(writtenEvents ->
//                 readEventsA.map(readEvents -> writtenEvents.length() == 1 && writtenEvents.equals(readEvents))
//             );
//           }
//       );
// 
//       return prop(actionInterpreter.apply(key).test(compareEventsA));
//     });
//   }
// 
//   public Property concurrent_write_fails(EventStorage<K, S, E> eventStorage) {
//     return property(keys, events, key -> event -> {
// 
//       WritableEventStream<K, S, E> stream = eventStorage.stream(key);
// 
//       Option<S> lastSeq =
//           stream.read(none(), Fold.last())
//               .runUnchecked()
//               .map(Events::getSeq);
// 
//       stream
//           .write(lastSeq, Instant.EPOCH, single(event))
//           .runUnchecked();
// 
//       WriteResult<K, S, E> concurrentWrite = stream
//           .write(lastSeq, Instant.EPOCH, single(event))
//           .runUnchecked();
// 
//       return prop(concurrentWrite.events().isNone());
//     });
//   }
// }
// 
// Path: core/src/main/java/eventsrc4j/Sequence.java
// public interface Sequence<S> extends Comparator<S> {
// 
//   S first();
// 
//   S next(S seq);
// 
//   Sequence<Long> longs = new Sequence<Long>() {
// 
//     public int compare(Long seq1, Long seq2) {
//       return seq1.compareTo(seq2);
//     }
// 
//     public Long first() {
//       return 1L;
//     }
// 
//     public Long next(Long seq) {
//       return seq + 1;
//     }
//   };
// }


// Path: core/src/test/java/eventsrc4j/memory/MemoryEventStorageTest.java
import eventsrc4j.EventStorageSpec;
import eventsrc4j.Sequence;
import fj.test.Arbitrary;
import fj.test.Property;
import fj.test.reflect.CheckParams;
import fj.test.runner.PropertyTestRunner;
import org.junit.runner.RunWith;
import static fj.test.Gen.elements;

package eventsrc4j.memory;



@RunWith(PropertyTestRunner.class)
@CheckParams(maxSize = 10000, minSuccessful = 200)
public final class MemoryEventStorageTest {

  private static final EventStorageSpec<Integer, Long, MemoryEventStorageTest.Event> spec =
      new EventStorageSpec<>(Arbitrary.arbInteger, elements(Event.values()));