Projection extends TransactionalEntity<I, M, B> implements EventPlayer, EventSubscriber,
                   HasVersionColumn<I, M>, HasLifecycleColumns<I, M> { static boolean playOn(Projection<?, ?, ?> projection, Iterable<Event> events) { ProjectionTransaction<?, ?, ?> tx = ProjectionTransaction.start(projection); projection.play(events); tx.commitIfActive(); return projection.changed(); } protected  Projection(); protected  Projection(I id); @Override BatchDispatchOutcome play(Iterable<Event> events);  }
@Test @DisplayName("expose `play events` operation to package") void exposePlayingEvents() { StringImported stringImported = StringImported .newBuilder() .setValue("eins zwei drei") .build(); Int32Imported integerImported = Int32Imported .newBuilder() .setValue(123) .build(); Version nextVersion = Versions.increment(projection.version()); Event e1 = eventFactory.createEvent(stringImported, nextVersion); Event e2 = eventFactory.createEvent(integerImported, Versions.increment(nextVersion)); boolean projectionChanged = Projection.playOn(projection, ImmutableList.of(e1, e2)); String projectionState = projection.state().getValue(); assertTrue(projectionChanged); assertTrue(projectionState.contains(stringImported.getValue())); assertTrue(projectionState.contains(String.valueOf(integerImported.getValue()))); }