-
Notifications
You must be signed in to change notification settings - Fork 9
/
BankAccountTests.fs
93 lines (83 loc) · 2.56 KB
/
BankAccountTests.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module EsBankAccount.Tests.Domain.BankAccountTests
open System
open Xunit
open EsBankAccount.Domain.BankAccount
let spec = DeciderSpecResult (State.initial, evolve, decide)
[<Fact>]
let ``make a deposit`` () =
spec {
When
( Deposit (10m, DateTime.MinValue) )
Then
[ Deposited { Amount = 10m; Date = DateTime.MinValue } ]
}
[<Fact>]
let ``make a withdrawal`` () =
spec {
When
( Withdraw (10m, DateTime.MinValue, None) )
Then
[ Withdrawn { Amount = 10m; Date = DateTime.MinValue } ]
}
[<Fact>]
let ``when withdrawing, the threshold limit should not be exceeded`` () =
let thresholdLimit = -500m
spec {
Given
[ Withdrawn { Amount = 400m; Date = DateTime.MinValue } ]
When
( Withdraw (100m, DateTime.MinValue, Some thresholdLimit) )
Then
[ Withdrawn { Amount = 100m; Date = DateTime.MinValue } ]
When
( Withdraw (1m, DateTime.MinValue, Some thresholdLimit) )
Then
( ThresholdExceeded (-501m, thresholdLimit) |> WithdrawalError )
}
[<Fact>]
let ``close the account`` () =
spec {
When
( Close DateTime.MinValue )
Then
[ Closed {| ClosedOn = DateTime.MinValue |} ]
}
[<Fact>]
let ``close the account and withdraw the remaining amount`` () =
spec {
Given
[ Deposited { Amount = 100m; Date = DateTime.MinValue } ]
When
( Close DateTime.MinValue )
Then // assert scenario
( function Ok events -> Assert.NotEmpty events | _ -> () )
Then // true or false scenario
( function Ok [ Withdrawn _; Closed _ ] -> true | _ -> false )
Then // equality then structural diff scenario
[ Withdrawn { Amount = 100m; Date = DateTime.MinValue }
Closed {| ClosedOn = DateTime.MinValue |} ]
}
[<Fact>]
let ``negative balance cannot be closed`` () =
spec {
Given
[ Withdrawn { Amount = 50m; Date = DateTime.MinValue } ]
When
( Close DateTime.MinValue )
Then
( BalanceIsNegative -50m |> ClosingError )
}
[<Fact>]
let ``cannot deposit or withdraw if the account is already closed`` () =
spec {
Given
[ Closed {| ClosedOn = DateTime.MinValue |} ]
When
( Deposit (10m, DateTime.MinValue) )
Then
( AlreadyClosed )
When
( Withdraw (10m, DateTime.MinValue, None) )
Then
( AlreadyClosed )
}