Skip to content

Commit 7534087

Browse files
committed
Check if global process is alive before handling calls
Closes #107.
1 parent e0ea52f commit 7534087

1 file changed

Lines changed: 38 additions & 25 deletions

File tree

lib/mox/server.ex

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,37 @@ defmodule Mox.Server do
4040
{:ok, %{expectations: %{}, allowances: %{}, deps: %{}, mode: :private, global_owner_pid: nil}}
4141
end
4242

43+
def handle_call(msg, _from, state) do
44+
# The global process may have terminated and we did not receive
45+
# the DOWN message yet, so we always check accordingly if it is alive.
46+
with %{mode: :global, global_owner_pid: global_owner_pid} <- state,
47+
false <- Process.alive?(global_owner_pid) do
48+
handle_call(msg, reset_global_mode(state))
49+
else
50+
_ -> handle_call(msg, state)
51+
end
52+
end
53+
54+
def handle_info({:DOWN, _, _, pid, _}, state) do
55+
state =
56+
case state.global_owner_pid do
57+
^pid -> reset_global_mode(state)
58+
_ -> state
59+
end
60+
61+
state =
62+
case state.deps do
63+
%{^pid => {:DOWN, _}} -> down(state, pid)
64+
%{} -> state
65+
end
66+
67+
{:noreply, state}
68+
end
69+
70+
# handle_call
71+
4372
def handle_call(
4473
{:add_expectation, owner_pid, {mock, _, _} = key, expectation},
45-
_from,
4674
%{mode: :private} = state
4775
) do
4876
if allowance = state.allowances[owner_pid][mock] do
@@ -61,7 +89,6 @@ defmodule Mox.Server do
6189

6290
def handle_call(
6391
{:add_expectation, owner_pid, {_mock, _, _} = key, expectation},
64-
_from,
6592
%{mode: :global, global_owner_pid: global_owner_pid} = state
6693
) do
6794
if owner_pid != global_owner_pid do
@@ -78,7 +105,6 @@ defmodule Mox.Server do
78105

79106
def handle_call(
80107
{:fetch_fun_to_dispatch, caller_pids, {mock, _, _} = key},
81-
_from,
82108
%{mode: :private} = state
83109
) do
84110
owner_pid =
@@ -108,7 +134,6 @@ defmodule Mox.Server do
108134

109135
def handle_call(
110136
{:fetch_fun_to_dispatch, _caller_pids, {_mock, _, _} = key},
111-
_from,
112137
%{mode: :global} = state
113138
) do
114139
case state.expectations[state.global_owner_pid][key] do
@@ -127,7 +152,7 @@ defmodule Mox.Server do
127152
end
128153
end
129154

130-
def handle_call({:verify, owner_pid, mock, test_or_on_exit}, _from, state) do
155+
def handle_call({:verify, owner_pid, mock, test_or_on_exit}, state) do
131156
expectations = state.expectations[owner_pid] || %{}
132157

133158
pending =
@@ -146,16 +171,16 @@ defmodule Mox.Server do
146171
{:reply, pending, state}
147172
end
148173

149-
def handle_call({:verify_on_exit, pid}, _from, state) do
174+
def handle_call({:verify_on_exit, pid}, state) do
150175
state = maybe_add_and_monitor_pid(state, pid, :on_exit, fn {_, deps} -> {:on_exit, deps} end)
151176
{:reply, :ok, state}
152177
end
153178

154-
def handle_call({:allow, _, _, _}, _from, %{mode: :global} = state) do
179+
def handle_call({:allow, _, _, _}, %{mode: :global} = state) do
155180
{:reply, {:error, :in_global_mode}, state}
156181
end
157182

158-
def handle_call({:allow, mock, owner_pid, pid}, _from, %{mode: :private} = state) do
183+
def handle_call({:allow, mock, owner_pid, pid}, %{mode: :private} = state) do
159184
%{allowances: allowances, expectations: expectations} = state
160185
owner_pid = state.allowances[owner_pid][mock] || owner_pid
161186
allowance = allowances[pid][mock]
@@ -178,33 +203,21 @@ defmodule Mox.Server do
178203
end
179204
end
180205

181-
def handle_call({:set_mode, owner_pid, :global}, _from, state) do
206+
def handle_call({:set_mode, owner_pid, :global}, state) do
182207
state = maybe_add_and_monitor_pid(state, owner_pid)
183208
{:reply, :ok, %{state | mode: :global, global_owner_pid: owner_pid}}
184209
end
185210

186-
def handle_call({:set_mode, _owner_pid, :private}, _from, state) do
211+
def handle_call({:set_mode, _owner_pid, :private}, state) do
187212
{:reply, :ok, %{state | mode: :private, global_owner_pid: nil}}
188213
end
189214

190-
def handle_info({:DOWN, _, _, pid, _}, state) do
191-
state =
192-
case state.global_owner_pid do
193-
^pid -> %{state | mode: :private, global_owner_pid: nil}
194-
_ -> state
195-
end
196-
197-
state =
198-
case state.deps do
199-
%{^pid => {:DOWN, _}} -> down(state, pid)
200-
%{} -> state
201-
end
215+
# Helper functions
202216

203-
{:noreply, state}
217+
defp reset_global_mode(state) do
218+
%{state | mode: :private, global_owner_pid: nil}
204219
end
205220

206-
# Helper functions
207-
208221
defp down(state, pid) do
209222
{{_, deps}, state} = pop_in(state.deps[pid])
210223
{_, state} = pop_in(state.expectations[pid])

0 commit comments

Comments
 (0)