Created
November 19, 2019 19:23
-
-
Save fotonmoton/72e971692a66702dc260453703248130 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 BankAccount | |
type Account = decimal option ref | |
let mkBankAccount(): Account = ref None | |
let openAccount (account: Account): Account = | |
account := Some 0m | |
account | |
let closeAccount account = | |
account := None | |
account | |
let getBalance account = !account | |
let updateBalance (change: decimal) (account: Account) = | |
lock account (fun () -> | |
match !account with | |
| None -> account := Some change | |
| Some balance -> account := Some (balance + change)) | |
account |
This file contains hidden or 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
// This file was created manually and its version is 2.0.0. | |
module BankAccountTest | |
open Xunit | |
open FsUnit.Xunit | |
open BankAccount | |
[<Fact>] | |
let ``Returns empty balance after opening`` () = | |
let account = mkBankAccount() |> openAccount | |
getBalance account |> should equal (Some 0.0m) | |
[<Fact>] | |
let ``Check basic balance`` () = | |
let account = mkBankAccount() |> openAccount | |
let openingBalance = account |> getBalance | |
let updatedBalance = | |
account | |
|> updateBalance 10.0m | |
|> getBalance | |
openingBalance |> should equal (Some 0.0m) | |
updatedBalance |> should equal (Some 10.0m) | |
[<Fact>] | |
let ``Balance can increment or decrement`` () = | |
let account = mkBankAccount() |> openAccount | |
let openingBalance = account |> getBalance | |
let addedBalance = | |
account | |
|> updateBalance 10.0m | |
|> getBalance | |
let subtractedBalance = | |
account | |
|> updateBalance -15.0m | |
|> getBalance | |
openingBalance |> should equal (Some 0.0m) | |
addedBalance |> should equal (Some 10.0m) | |
subtractedBalance |> should equal (Some -5.0m) | |
[<Fact>] | |
let ``Account can be closed`` () = | |
let account = | |
mkBankAccount() | |
|> openAccount | |
|> closeAccount | |
getBalance account |> should equal None | |
account |> should not' (equal None) | |
[<Fact>] | |
let ``Account can be updated from multiple threads`` () = | |
let account = | |
mkBankAccount() | |
|> openAccount | |
let updateAccountAsync = | |
async { | |
account | |
|> updateBalance 1.0m | |
|> ignore | |
} | |
updateAccountAsync | |
|> List.replicate 1000 | |
|> Async.Parallel | |
|> Async.RunSynchronously | |
|> ignore | |
getBalance account |> should equal (Some 1000.0m) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment