Skip to content

Commit

Permalink
This is not your uncle Java
Browse files Browse the repository at this point in the history
Added slimmed version of Java Exercise using latest Java 22 pattern matching improvements
  • Loading branch information
oskardudycz committed May 4, 2024
1 parent 6a7c92b commit eae48a0
Show file tree
Hide file tree
Showing 25 changed files with 233 additions and 433 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public abstract class EventStoreDBTest {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);;

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,79 +78,3 @@ case ProductItemRemovedFromShoppingCart(_, var productItem) ->
};
}
}
//
//static ShoppingCart evolve(EventStoreDBClient eventStore, String streamName) {
// // 1. Add logic here
// ShoppingCart shoppingCart = null;
//
//
// for (var event : getEvents(eventStore, streamName)) {
// switch (event) {
// case ShoppingCartOpened opened -> shoppingCart = new ShoppingCart(
// opened.shoppingCartId(),
// opened.clientId(),
// ShoppingCartStatus.Pending,
// new PricedProductItem[]{},
// null,
// null
// );
// case ProductItemAddedToShoppingCart productItemAdded ->
// shoppingCart = new ShoppingCart(
// shoppingCart.id(),
// shoppingCart.clientId(),
// shoppingCart.status(),
// Stream.concat(Arrays.stream(shoppingCart.productItems()), Stream.of(productItemAdded.productItem()))
// .collect(groupingByOrdered(PricedProductItem::productId))
// .entrySet().stream()
// .map(group -> group.getValue().size() == 1 ?
// group.getValue().get(0) :
// new PricedProductItem(
// group.getKey(),
// group.getValue().stream().mapToInt(PricedProductItem::quantity).sum(),
// group.getValue().get(0).unitPrice()
// )
// )
// .toArray(PricedProductItem[]::new),
// shoppingCart.confirmedAt(),
// shoppingCart.canceledAt()
// );
// case ProductItemRemovedFromShoppingCart productItemRemoved ->
// shoppingCart = new ShoppingCart(
// shoppingCart.id(),
// shoppingCart.clientId(),
// shoppingCart.status(),
// Arrays.stream(shoppingCart.productItems())
// .map(pi -> pi.productId().equals(productItemRemoved.productItem().productId()) ?
// new PricedProductItem(
// pi.productId(),
// pi.quantity() - productItemRemoved.productItem().quantity(),
// pi.unitPrice()
// )
// : pi
// )
// .filter(pi -> pi.quantity > 0)
// .toArray(PricedProductItem[]::new),
// shoppingCart.confirmedAt(),
// shoppingCart.canceledAt()
// );
// case ShoppingCartConfirmed confirmed -> shoppingCart = new ShoppingCart(
// shoppingCart.id(),
// shoppingCart.clientId(),
// ShoppingCartStatus.Confirmed,
// shoppingCart.productItems(),
// confirmed.confirmedAt(),
// shoppingCart.canceledAt()
// );
// case ShoppingCartCanceled canceled -> shoppingCart = new ShoppingCart(
// shoppingCart.id(),
// shoppingCart.clientId(),
// ShoppingCartStatus.Canceled,
// shoppingCart.productItems(),
// shoppingCart.confirmedAt(),
// canceled.canceledAt()
// );
// }
// }
//
// return shoppingCart;
//}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public final class DefaultSerializer {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public final class DefaultSerializer {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Database {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

public <T> void store(Class<T> typeClass, UUID id, Object obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class Database {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

public <T> void store(Class<T> typeClass, UUID id, Object obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public record DataWrapper(Object data, OffsetDateTime validFrom) {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

public <T> void store(Class<T> typeClass, UUID id, Object obj) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public double totalAmount() {
new JsonMapper()
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);

private CompletableFuture<WriteResult> appendEvents(EventStoreDBClient eventStore, String streamName, Object[] events) {
// 1. Add logic here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public abstract class EventStoreDBTest {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);;

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ record EventEnvelope(String eventType, String json) {
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
import io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.tools.EventStore;
import org.junit.jupiter.api.Test;

import java.time.OffsetDateTime;
import java.util.UUID;

import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.FunctionalTools.FoldLeft.foldLeft;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.PricedProductItem;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.productItems.ProductItems.ProductItem;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartEvent.*;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartService.ShoppingCartCommand.*;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartService.handle;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCart.Event.*;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartDecider.Command.*;
import static io.eventdriven.introductiontoeventsourcing.e06_business_logic_slimmed.immutable.ShoppingCartDecider.decide;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.*;

public class BusinessLogicTests {
static ShoppingCart getShoppingCart(EventStore eventStore, UUID shoppingCartId) {
var events = eventStore.readStream(ShoppingCartEvent.class, shoppingCartId);
var events = eventStore.readStream(ShoppingCart.Event.class, shoppingCartId);

return events.stream()
.collect(foldLeft(ShoppingCart::initial, ShoppingCart::evolve));
.collect(foldLeft(ShoppingCart.Initial::new, ShoppingCart::evolve));
}

@Test
Expand All @@ -37,54 +37,57 @@ public void runningSequenceOfBusinessLogic_ShouldGenerateSequenceOfEvents() {
var shoesPrice = 100;
var tShirtPrice = 50;

var pricedTwoPairOfShoes = new PricedProductItem(shoesId, 2, shoesPrice);
var pricedPairOfShoes = new PricedProductItem(shoesId, 1, shoesPrice);
var pricedTShirt = new PricedProductItem(tShirtId, 1, tShirtPrice);

var eventStore = new EventStore();
var now = OffsetDateTime.now();

// Open
ShoppingCartEvent result = handle(new OpenShoppingCart(shoppingCartId, clientId));
var shoppingCart = getShoppingCart(eventStore, shoppingCartId);
ShoppingCart.Event result = decide(new Open(shoppingCartId, clientId, now), shoppingCart);
eventStore.appendToStream(shoppingCartId, new Object[]{result});

// Add Two Pair of Shoes
var shoppingCart = getShoppingCart(eventStore, shoppingCartId);
result = handle(
FakeProductPriceCalculator.returning(shoesPrice),
new AddProductItemToShoppingCart(shoppingCartId, twoPairsOfShoes),
shoppingCart = getShoppingCart(eventStore, shoppingCartId);
result = decide(
new AddProductItem(shoppingCartId,
FakeProductPriceCalculator.returning(shoesPrice).calculate(twoPairsOfShoes), now),
shoppingCart
);
eventStore.appendToStream(shoppingCartId, new Object[]{result});

// Add T-Shirt
shoppingCart = getShoppingCart(eventStore, shoppingCartId);
result = handle(
FakeProductPriceCalculator.returning(tShirtPrice),
new AddProductItemToShoppingCart(shoppingCartId, tShirt),
result = decide(
new AddProductItem(shoppingCartId,
FakeProductPriceCalculator.returning(tShirtPrice).calculate(tShirt), now),
shoppingCart
);
eventStore.appendToStream(shoppingCartId, new Object[]{result});

// Remove a pair of shoes
shoppingCart = getShoppingCart(eventStore, shoppingCartId);
result = handle(
new RemoveProductItemFromShoppingCart(shoppingCartId, pricedPairOfShoes),
result = decide(
new RemoveProductItem(shoppingCartId, pricedPairOfShoes, now),
shoppingCart
);
eventStore.appendToStream(shoppingCartId, new Object[]{result});

// Confirm
shoppingCart = getShoppingCart(eventStore, shoppingCartId);
result = handle(
new ConfirmShoppingCart(shoppingCartId),
result = decide(
new Confirm(shoppingCartId, now),
shoppingCart
);
eventStore.appendToStream(shoppingCartId, new Object[]{result});

// Try Cancel
ShoppingCart finalShoppingCart = getShoppingCart(eventStore, shoppingCartId);
assertThrows(IllegalStateException.class, () -> {
var cancelResult = handle(
new CancelShoppingCart(shoppingCartId),
var cancelResult = decide(
new Cancel(shoppingCartId, now),
finalShoppingCart
);
eventStore.appendToStream(shoppingCartId, new Object[]{cancelResult});
Expand All @@ -93,28 +96,14 @@ public void runningSequenceOfBusinessLogic_ShouldGenerateSequenceOfEvents() {

shoppingCart = getShoppingCart(eventStore, shoppingCartId);

assertEquals(shoppingCartId, shoppingCart.id());
assertEquals(clientId, shoppingCart.clientId());
assertEquals(2, shoppingCart.productItems().size());
assertEquals(ShoppingCart.Status.Confirmed, shoppingCart.status());

assertEquals(shoesId, shoppingCart.productItems().get(0).productId());
assertEquals(pairOfShoes.quantity(), shoppingCart.productItems().get(0).quantity());
assertEquals(pricedPairOfShoes.unitPrice(), shoppingCart.productItems().get(0).unitPrice());

assertEquals(tShirtId, shoppingCart.productItems().get(1).productId());
assertEquals(tShirt.quantity(), shoppingCart.productItems().get(1).quantity());
assertEquals(pricedTShirt.unitPrice(), shoppingCart.productItems().get(1).unitPrice());

assertThat(shoppingCart.productItems().get(0)).usingRecursiveComparison().isEqualTo(pricedPairOfShoes);
assertThat(shoppingCart.productItems().get(1)).usingRecursiveComparison().isEqualTo(pricedTShirt);
assertThat(shoppingCart).isInstanceOf(ShoppingCart.Closed.class);

var events = eventStore.readStream(ShoppingCartEvent.class, shoppingCartId);
var events = eventStore.readStream(ShoppingCart.Event.class, shoppingCartId);
assertThat(events).hasSize(5);
assertThat(events.get(0)).isInstanceOf(ShoppingCartOpened.class);
assertThat(events.get(1)).isInstanceOf(ProductItemAddedToShoppingCart.class);
assertThat(events.get(2)).isInstanceOf(ProductItemAddedToShoppingCart.class);
assertThat(events.get(3)).isInstanceOf(ProductItemRemovedFromShoppingCart.class);
assertThat(events.get(4)).isInstanceOf(ShoppingCartConfirmed.class);
assertThat(events.get(0)).isEqualTo(new Opened(shoppingCartId, clientId, now));
assertThat(events.get(1)).isEqualTo(new ProductItemAdded(shoppingCartId, pricedTwoPairOfShoes, now));
assertThat(events.get(2)).isEqualTo(new ProductItemAdded(shoppingCartId, pricedTShirt, now));
assertThat(events.get(3)).isEqualTo(new ProductItemRemoved(shoppingCartId, pricedPairOfShoes, now));
assertThat(events.get(4)).isEqualTo(new Confirmed(shoppingCartId, now));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,20 @@ public Set<Characteristics> characteristics() {
LinkedHashMap::new,
Collectors.mapping(p -> p, toList()));
}

public static <State, Event> When<State, Event> when(State state, Event event){
return new When<>(state, event);
}

public static <State, Event> On<State, Event> on(State state, Event event){
return new On<>(state, event);
}

public record When<State, Event>(State state, Event event) {

}

public record On<State, Command>(State state, Command command) {
}
}

Loading

0 comments on commit eae48a0

Please sign in to comment.