1
exercism fetch lfe bank-account

test/bank-account-tests.lfe

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
94
95
96
97
98
99
100
101
102
103
104
(defmodule bank-account-tests
  (behaviour ltest-unit)
  (export all))

(include-lib "ltest/include/ltest-macros.lfe")

(deftest create
  (let ((account (bank-account:create)))
    (is-equal 0 (bank-account:balance account))))

(deftest close-account
  (let ((account (bank-account:create)))
    (bank-account:deposit account 1)
    (is-equal 1 (bank-account:close account))
    (is-error 'function_clause (bank-account:balance account))))

(deftest deposit
  (let ((account (bank-account:create)))
    (bank-account:deposit account 1)
    (is-equal 1 (bank-account:balance account))))

(deftest deposit-fail
  (let ((account (bank-account:create)))
    (bank-account:deposit account -1)
    (is-equal 0 (bank-account:balance account))))

(deftest deposit-many
  (let* ((account (bank-account:create))
         (first   (progn (handle-all 'deposit account (lists:seq 1 10))
                         (bank-account:balance account)))
         (last    (progn (timer:sleep 100)
                         (bank-account:balance account))))
    (is (< first 55))
    (is-equal 55 last)))

(deftest withdraw
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:withdraw account 1))))
    (is-equal 1 amount)
    (is-equal 9 (bank-account:balance account))))

(deftest withdraw-fail
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:withdraw account -1))))
    (is-equal 0 amount)
    (is-equal 10 (bank-account:balance account))))

(deftest withdraw-excessive
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:withdraw account 20))))
    (is-equal 10 amount)
    (is-equal 0 (bank-account:balance account))))

(deftest withdraw-many
  (let* ((account (bank-account:create))
         (first   (progn (bank-account:deposit account 55)
                         (handle-all 'withdraw account (lists:seq 1 10))
                         (bank-account:balance account)))
         (last    (progn (timer:sleep 100)
                         (bank-account:balance account))))
    (is (> first 0))
    (is-equal 0 last)))

(deftest charge
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:charge account 2))))
    (is-equal 2 amount)
    (is-equal 8 (bank-account:balance account))))

(deftest charge-fail
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:charge account -2))))
    (is-equal 0 amount)
    (is-equal 10 (bank-account:balance account))))

(deftest charge-excessive
  (let* ((account (bank-account:create))
         (amount  (progn (bank-account:deposit account 10)
                         (bank-account:charge account 20))))
    (is-equal 0 amount)
    (is-equal 10 (bank-account:balance account))))

(deftest charge-many
  (let* ((account (bank-account:create))
         (first   (progn (bank-account:deposit account 55)
                         (dotimes 10 (lambda (_) (bank-account:charge account 10)))
                         (bank-account:balance account)))
         (last    (progn (timer:sleep 100)
                         (bank-account:balance account))))
    (is (> first 0))
    (is-equal 5 last)))

(defun dotimes (times f) (lists:foreach f (lists:seq 1 times)))

(defun handle-all (request account amounts)
  (lists:foreach
    (lambda (amount)
      (spawn (lambda () (call 'bank-account request account amount))))
    amounts))