@@ -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