Created
October 24, 2018 16:04
-
-
Save Ouarzy/cbbd947ff11d6add50721423e96bdb5c to your computer and use it in GitHub Desktop.
F# example for aggregates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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