Skip to content

Commit 59dd708

Browse files
fix tests
1 parent 795a5d8 commit 59dd708

File tree

6 files changed

+73
-5
lines changed

6 files changed

+73
-5
lines changed

lessons/otp-concurrency/simple_bank/config/config.exs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# and its dependencies with the aid of the Mix.Config module.
33
use Mix.Config
44

5+
56
# This configuration is loaded before any dependency and is restricted
67
# to this project. If another project depends on this project, this
78
# file won't be loaded nor affect the parent project. For this reason,

lessons/otp-concurrency/simple_bank/lib/simple_bank.ex

+64-2
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,53 @@ defmodule SimpleBank do
99
"""
1010
@type reason :: atom
1111

12+
alias SimpleBank.Account
13+
1214
def start_link(initial_state \\ %{}) do
1315
GenServer.start_link(__MODULE__, initial_state)
1416
end
1517

1618
@spec register(pid(), String.t()) :: {:ok, String.t()} | {:error, reason}
1719
def register(bank_pid, name) do
20+
case get_account(bank_pid, name) do
21+
nil ->
22+
account = %Account{balance: 0, id: UUID.uuid4(), name: name}
23+
GenServer.cast(bank_pid, {:register, account})
24+
{:ok, account.id}
25+
%Account{} ->
26+
{:error, :existing_account}
27+
end
28+
end
29+
30+
def get_account(bank_pid, name) do
31+
GenServer.call(bank_pid, {:get_account, name})
32+
end
33+
34+
def get_account_by_id(bank_pid, account_id) do
35+
GenServer.call(bank_pid, {:get_account_by_id, account_id})
1836
end
1937

2038
@spec deposit(pid(), String.t(), pos_integer()) :: {:ok, pos_integer()} | {:error, reason}
2139
def deposit(bank_pid, account_id, amount) when is_integer(amount) and amount > 0 do
40+
case get_account_by_id(bank_pid, account_id) do
41+
nil -> {:error, :missing_account}
42+
account ->
43+
account = GenServer.call(bank_pid, {:deposit, account, amount})
44+
{:ok, account.balance}
45+
end
2246
end
2347

24-
def deposit(_bank_pid, _account_id, _amount) do
25-
{:error, :missing_account}
48+
def deposit(_bank_pid, _account_id, amount) when is_integer(amount) and amount <= 0 do
49+
{:error, :pos_integer_only}
2650
end
2751

2852
@spec balance(pid(), String.t()) :: {:ok, pos_integer} | {:error, reason}
2953
def balance(bank_pid, account_id) do
54+
case get_account_by_id(bank_pid, account_id) do
55+
nil -> {:error, :missing_account}
56+
account ->
57+
{:ok, account.balance}
58+
end
3059
end
3160

3261
@spec withdrawl(pid(), String.t(), pos_integer()) :: {:ok, {pos_integer(), pos_integer()}} | {:error, reason}
@@ -36,4 +65,37 @@ defmodule SimpleBank do
3665
def init(initial_state) do
3766
{:ok, initial_state}
3867
end
68+
69+
def handle_cast({:register, account}, state) do
70+
{:ok, [state | account]}
71+
end
72+
73+
def handle_call({:get_account, account_name}, _from, state) do
74+
case Enum.find(state, fn account -> account.name == account_name end) do
75+
nil -> {:reply, nil, state}
76+
account -> {:reply, account, state}
77+
end
78+
end
79+
80+
def handle_call({:get_account_by_id, account_id}, _from, state) do
81+
case Enum.find(state, fn account -> account.id == account_id end) do
82+
nil -> {:reply, nil, state}
83+
account -> {:reply, account, state}
84+
end
85+
end
86+
87+
def handle_call({:deposit, account, amount}, _from, state) do
88+
account = do_deposit(account, amount)
89+
new_state = update_account_in_state(account, state)
90+
{:reply, account, new_state}
91+
end
92+
93+
def do_deposit(account, amount) do
94+
Map.put(account, :balance, account.balance + amount)
95+
end
96+
97+
def update_account_in_state(account, state) do
98+
accounts = Enum.reject(state, fn a -> a.id == account.id end)
99+
[accounts | account]
100+
end
39101
end

lessons/otp-concurrency/simple_bank/mix.exs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ defmodule SimpleBank.MixProject do
2121
# Run "mix help deps" to learn about dependencies.
2222
defp deps do
2323
[
24+
{ :elixir_uuid, "~> 1.2" }
2425
# {:dep_from_hexpm, "~> 0.3.0"},
2526
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
2627
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
%{
2+
"elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"},
3+
}

lessons/otp-concurrency/simple_bank/test/simple_bank_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule SimpleBankTest do
99
end
1010

1111
describe "register/2" do
12-
test "creates a new account and generates an account id", %{bank: bank_pid} do
12+
test "creates a new account with the given name and a randomly generated id. HINT: We've included the `elixir-uuid` dependency so that you can generate a random UUID string. See docs here https://github.com/zyro/elixir-uuid", %{bank: bank_pid} do
1313
{:ok, account_id} = SimpleBank.register(bank_pid, "Another Test Account")
1414
assert is_binary(account_id)
1515
end
@@ -21,7 +21,7 @@ defmodule SimpleBankTest do
2121

2222
describe "deposit/3" do
2323
test "increases the account balance by the deposited amount", %{bank: bank_pid} do
24-
assert {:ok, 10} == SimpleBank.deposit(bank_pid, "test_id", 10)
24+
assert {:ok, 110} == SimpleBank.deposit(bank_pid, "test_id", 10)
2525
end
2626

2727
test "does not allow deposits of negative amounts", %{bank: bank_pid} do
@@ -35,7 +35,7 @@ defmodule SimpleBankTest do
3535

3636
describe "balance/2" do
3737
test "returns the current account balance", %{bank: bank_pid} do
38-
assert {:ok, 110} == SimpleBank.deposit(bank_pid, "test_id", 10)
38+
assert {:ok, 100} == SimpleBank.balance(bank_pid, "test_id")
3939
end
4040

4141
test "raises an error if the account does not exist", %{bank: bank_pid} do
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
ExUnit.configure seed: 0
12
ExUnit.start()

0 commit comments

Comments
 (0)