Skip to content

Instantly share code, notes, and snippets.

@Ouarzy
Created October 24, 2018 16:04
Show Gist options
  • Save Ouarzy/cbbd947ff11d6add50721423e96bdb5c to your computer and use it in GitHub Desktop.
Save Ouarzy/cbbd947ff11d6add50721423e96bdb5c to your computer and use it in GitHub Desktop.
F# example for aggregates
module Tests
open Xunit
open Swensen.Unquote
open System
module OnlineReservation =
type RoomId = string
type BookId = string
type CustomerId = string
type RoomChoosed = {
Period : DateTime * DateTime
RoomId : RoomId
CustomerId : CustomerId
BookId : BookId
}
type RoomCanceled ={
BookId : BookId
}
type RoomEvent = RoomChoosed of RoomChoosed | RoomCanceled of RoomCanceled
type ChooseRoom = {
Period : DateTime * DateTime
CustomerId : CustomerId
RoomId : RoomId
}
type DecisionProjection = {
BookId : BookId
IsChoosen : bool
IsCancel : bool
}
let choose generateId chooseRoomCommand =
{Period = chooseRoomCommand.Period; RoomId = chooseRoomCommand.RoomId; CustomerId = chooseRoomCommand.CustomerId; BookId = generateId(); }
let apply state event =
match event with
| RoomChoosed choosed -> { state with BookId = choosed.BookId; IsChoosen = true; }
| RoomCanceled _ -> {state with IsCancel = true}
let cancel history =
let decisionProjection = history |> List.fold apply {BookId = String.Empty; IsChoosen = false; IsCancel = false}
match decisionProjection.IsCancel with
| false -> RoomCanceled {BookId = decisionProjection.BookId} :: history
| true -> history
let generateFakeBookId ()=
"BookId"
open OnlineReservation
let expectedPeriod = (DateTime.Now, DateTime.Now)
let expectedCustomerId = "customerId"
let expectedRoomId = "roomId"
let expectedBookId = generateFakeBookId()
let roomChoosed = RoomChoosed {Period = expectedPeriod; CustomerId = expectedCustomerId; RoomId = expectedRoomId; BookId = expectedBookId}
let roomCanceled = RoomCanceled {BookId = expectedBookId}
[<Fact>]
let ``OnlineReservation should raise RoomChoosed when Choose`` () =
let chooseRoom = {Period = expectedPeriod; CustomerId = expectedCustomerId; RoomId = expectedRoomId}
let event = OnlineReservation.choose generateFakeBookId chooseRoom
test <@ event = {Period = expectedPeriod; CustomerId = expectedCustomerId; RoomId = expectedRoomId; BookId = expectedBookId} @>
[<Fact>]
let ``OnlineReservation with RoomChoosed should raise RoomCanceled when Cancel`` () =
test <@ [roomChoosed] |> OnlineReservation.cancel = [roomCanceled ; roomChoosed ] @>
[<Fact>]
let ``OnlineReservation with RoomCanceld should NOT raise RoomCanceled when Cancel`` () =
test <@ [roomCanceled; roomChoosed; ] |> OnlineReservation.cancel = [roomCanceled ; roomChoosed ] @>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment