Skip to content

Commit

Permalink
more tests!
Browse files Browse the repository at this point in the history
  • Loading branch information
renatillas committed Aug 4, 2024
1 parent 6805309 commit b32ef1e
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 173 deletions.
23 changes: 23 additions & 0 deletions birdie_snapshots/memory_store_load_events.accepted
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
version: 1.1.8
title: memory store load events
file: ./test/eventsourcing_test.gleam
test_name: memory_store_load_events_test
---
[
MemoryStoreEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
1,
AccountOpened("92085b42-032c-4d7a-84de-a86d67123858"),
),
MemoryStoreEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
2,
CustomerDepositedCash(10.0, 10.0),
),
MemoryStoreEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
3,
CustomerWithdrewCash(5.99, 4.01),
),
]
32 changes: 32 additions & 0 deletions birdie_snapshots/sqlite_store_load_events.accepted
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
version: 1.1.8
title: sqlite store load events
file: ./test/sqlite_store_test.gleam
test_name: sqlite_store_load_events_test
---
[
SerializedEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
1,
AccountOpened("92085b42-032c-4d7a-84de-a86d67123858"),
"BankAccountEvent",
"1.0",
"BankAccount",
),
SerializedEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
2,
CustomerDepositedCash(10.0, 10.0),
"BankAccountEvent",
"1.0",
"BankAccount",
),
SerializedEventEnvelop(
"92085b42-032c-4d7a-84de-a86d67123858",
3,
CustomerWithdrewCash(5.99, 4.01),
"BankAccountEvent",
"1.0",
"BankAccount",
),
]
2 changes: 1 addition & 1 deletion gleam.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "eventsourcing"
version = "0.2.0"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
Expand Down
4 changes: 2 additions & 2 deletions src/eventsourcing/memory_store.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ fn load_aggregate(

let #(aggregate, sequence) =
list.fold(
over: commited_events |> list.reverse,
over: commited_events,
from: #(memory_store.empty_aggregate, 0),
with: fn(aggregate_and_sequence, event_envelop) {
let #(aggregate, _) = aggregate_and_sequence
Expand All @@ -135,7 +135,7 @@ fn commit(
let eventsourcing.AggregateContext(aggregate_id, _, sequence) = context
let wrapped_events = wrap_events(aggregate_id, sequence, events)
let past_events = load_commited_events(memory_store, aggregate_id)
let events = list.append(wrapped_events, past_events)
let events = list.append(past_events, wrapped_events)
io.println(
"storing: "
<> wrapped_events |> list.length |> int.to_string
Expand Down
108 changes: 61 additions & 47 deletions test/eventsourcing_test.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import birdie
import eventsourcing
import eventsourcing/memory_store
import example_bank_account
import gleam/int
import gleam/io
import gleam/list
Expand All @@ -14,10 +15,16 @@ pub fn main() {

pub fn memory_store_execute_test() {
let mem_store =
memory_store.new(BankAccount(opened: False, balance: 0.0), handle, apply)
memory_store.new(
example_bank_account.BankAccount(opened: False, balance: 0.0),
example_bank_account.handle,
example_bank_account.apply,
)
let query = fn(
aggregate_id: String,
events: List(eventsourcing.EventEnvelop(BankAccountEvent)),
events: List(
eventsourcing.EventEnvelop(example_bank_account.BankAccountEvent),
),
) {
io.println_error(
"Aggregate Bank Account with ID: "
Expand All @@ -31,23 +38,23 @@ pub fn memory_store_execute_test() {
eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
OpenAccount("92085b42-032c-4d7a-84de-a86d67123858"),
example_bank_account.OpenAccount("92085b42-032c-4d7a-84de-a86d67123858"),
)
|> should.be_ok
|> should.equal(Nil)

eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
DepositMoney(10.0),
example_bank_account.DepositMoney(10.0),
)
|> should.be_ok
|> should.equal(Nil)

eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
WithDrawMoney(5.99),
example_bank_account.WithDrawMoney(5.99),
)
|> should.be_ok
|> should.equal(Nil)
Expand All @@ -60,49 +67,56 @@ pub fn memory_store_execute_test() {
|> birdie.snap(title: "memory store")
}

pub type BankAccount {
BankAccount(opened: Bool, balance: Float)
}

pub type BankAccountCommand {
OpenAccount(account_id: String)
DepositMoney(amount: Float)
WithDrawMoney(amount: Float)
}
pub fn memory_store_load_events_test() {
let mem_store =
memory_store.new(
example_bank_account.BankAccount(opened: False, balance: 0.0),
example_bank_account.handle,
example_bank_account.apply,
)
let query = fn(
aggregate_id: String,
events: List(
eventsourcing.EventEnvelop(example_bank_account.BankAccountEvent),
),
) {
io.println_error(
"Aggregate Bank Account with ID: "
<> aggregate_id
<> " commited "
<> events |> list.length |> int.to_string
<> " events.",
)
}
let event_sourcing = eventsourcing.new(mem_store, [query])
eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
example_bank_account.OpenAccount("92085b42-032c-4d7a-84de-a86d67123858"),
)
|> should.be_ok
|> should.equal(Nil)

pub type BankAccountEvent {
AccountOpened(account_id: String)
CustomerDepositedCash(amount: Float, balance: Float)
CustomerWithdrewCash(amount: Float, balance: Float)
}
eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
example_bank_account.DepositMoney(10.0),
)
|> should.be_ok
|> should.equal(Nil)

pub fn handle(
bank_account: BankAccount,
command: BankAccountCommand,
) -> Result(List(BankAccountEvent), Nil) {
case command {
OpenAccount(account_id) -> Ok([AccountOpened(account_id)])
DepositMoney(amount) -> {
let balance = bank_account.balance +. amount
case amount >. 0.0 {
True -> Ok([CustomerDepositedCash(amount:, balance:)])
False -> Error(Nil)
}
}
WithDrawMoney(amount) -> {
let balance = bank_account.balance -. amount
case amount >. 0.0 && balance >. 0.0 {
True -> Ok([CustomerWithdrewCash(amount:, balance:)])
False -> Error(Nil)
}
}
}
}
eventsourcing.execute(
event_sourcing,
"92085b42-032c-4d7a-84de-a86d67123858",
example_bank_account.WithDrawMoney(5.99),
)
|> should.be_ok
|> should.equal(Nil)

pub fn apply(bank_account: BankAccount, event: BankAccountEvent) {
case event {
AccountOpened(_) -> BankAccount(..bank_account, opened: True)
CustomerDepositedCash(_, balance) -> BankAccount(..bank_account, balance:)
CustomerWithdrewCash(_, balance) -> BankAccount(..bank_account, balance:)
}
memory_store.load_events(
mem_store.eventstore,
"92085b42-032c-4d7a-84de-a86d67123858",
)
|> pprint.format
|> birdie.snap(title: "memory store load events")
}
120 changes: 120 additions & 0 deletions test/example_bank_account.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import decode
import gleam/dynamic
import gleam/json
import gleam/result

pub type BankAccount {
BankAccount(opened: Bool, balance: Float)
}

pub const bank_account_type = "BankAccount"

pub type BankAccountCommand {
OpenAccount(account_id: String)
DepositMoney(amount: Float)
WithDrawMoney(amount: Float)
}

pub type BankAccountEvent {
AccountOpened(account_id: String)
CustomerDepositedCash(amount: Float, balance: Float)
CustomerWithdrewCash(amount: Float, balance: Float)
}

pub const bank_account_event_type = "BankAccountEvent"

pub fn handle(
bank_account: BankAccount,
command: BankAccountCommand,
) -> Result(List(BankAccountEvent), Nil) {
case command {
OpenAccount(account_id) -> Ok([AccountOpened(account_id)])
DepositMoney(amount) -> {
let balance = bank_account.balance +. amount
case amount >. 0.0 {
True -> Ok([CustomerDepositedCash(amount:, balance:)])
False -> Error(Nil)
}
}
WithDrawMoney(amount) -> {
let balance = bank_account.balance -. amount
case amount >. 0.0 && balance >. 0.0 {
True -> Ok([CustomerWithdrewCash(amount:, balance:)])
False -> Error(Nil)
}
}
}
}

pub fn apply(bank_account: BankAccount, event: BankAccountEvent) {
case event {
AccountOpened(_) -> BankAccount(..bank_account, opened: True)
CustomerDepositedCash(_, balance) -> BankAccount(..bank_account, balance:)
CustomerWithdrewCash(_, balance) -> BankAccount(..bank_account, balance:)
}
}

pub fn event_encoder(event: BankAccountEvent) -> String {
case event {
AccountOpened(account_id) ->
json.object([
#("event-type", json.string("account-opened")),
#("account-id", json.string(account_id)),
])
CustomerDepositedCash(amount, balance) ->
json.object([
#("event-type", json.string("customer-deposited-cash")),
#("amount", json.float(amount)),
#("balance", json.float(balance)),
])
CustomerWithdrewCash(amount, balance) ->
json.object([
#("event-type", json.string("customer-withdrew-cash")),
#("amount", json.float(amount)),
#("balance", json.float(balance)),
])
}
|> json.to_string
}

pub fn event_decoder(
string: String,
) -> Result(BankAccountEvent, List(dynamic.DecodeError)) {
let account_opened_decoder =
decode.into({
use account_id <- decode.parameter
AccountOpened(account_id)
})
|> decode.field("account-id", decode.string)

let customer_deposited_cash =
decode.into({
use amount <- decode.parameter
use balance <- decode.parameter
CustomerDepositedCash(amount, balance)
})
|> decode.field("amount", decode.float)
|> decode.field("balance", decode.float)

let customer_withdrew_cash =
decode.into({
use amount <- decode.parameter
use balance <- decode.parameter
CustomerWithdrewCash(amount, balance)
})
|> decode.field("amount", decode.float)
|> decode.field("balance", decode.float)

let decoder =
decode.at(["event-type"], decode.string)
|> decode.then(fn(event_type) {
case event_type {
"account-opened" -> account_opened_decoder
"customer-deposited-cash" -> customer_deposited_cash
"customer-withdrew-cash" -> customer_withdrew_cash
_ -> decode.fail("event-type")
}
})
json.decode(from: string, using: decode.from(decoder, _))
|> result.map_error(fn(_) { [] })
}
Loading

0 comments on commit b32ef1e

Please sign in to comment.