@@ -269,10 +269,8 @@ defmodule Mox do
269
269
"""
270
270
@ type t ( ) :: module ( )
271
271
272
- alias NimbleOwnership , as: N
273
-
274
272
@ timeout 30000
275
- @ ownership_server { :global , Mox.Server }
273
+ @ this { :global , Mox.Server }
276
274
277
275
defmodule UnexpectedCallError do
278
276
defexception [ :message ]
@@ -295,7 +293,7 @@ defmodule Mox do
295
293
"""
296
294
@ spec set_mox_private ( term ( ) ) :: :ok
297
295
def set_mox_private ( _context \\ % { } ) do
298
- N . set_mode_to_private ( @ ownership_server )
296
+ NimbleOwnership . set_mode_to_private ( @ this )
299
297
end
300
298
301
299
@ doc """
@@ -319,7 +317,7 @@ defmodule Mox do
319
317
end
320
318
321
319
def set_mox_global ( _context ) do
322
- N . set_mode_to_shared ( @ ownership_server , self ( ) )
320
+ NimbleOwnership . set_mode_to_shared ( @ this , self ( ) )
323
321
end
324
322
325
323
@ doc """
@@ -735,12 +733,13 @@ defmodule Mox do
735
733
raise ArgumentError , "owner_pid and allowed_pid must be different"
736
734
end
737
735
738
- case N . allow ( @ ownership_server , owner_pid , allowed_pid_or_function , mock , @ timeout ) do
736
+ case NimbleOwnership . allow ( @ this , owner_pid , allowed_pid_or_function , mock , @ timeout ) do
739
737
:ok ->
740
738
mock
741
739
742
740
{ :error , % NimbleOwnership.Error { reason: :not_allowed } } ->
743
- :ok = init_mock ( owner_pid , mock )
741
+ # Init the mock and re-allow.
742
+ _ = get_and_update! ( owner_pid , mock , & { & 1 , % { } } )
744
743
allow ( mock , owner_pid , allowed_via )
745
744
mock
746
745
@@ -806,7 +805,7 @@ defmodule Mox do
806
805
end
807
806
808
807
defp verify_mock_or_all! ( owner_pid , mock_or_all ) do
809
- all_expectations = N . get_owned ( @ ownership_server , owner_pid , _default = % { } , @ timeout )
808
+ all_expectations = NimbleOwnership . get_owned ( @ this , owner_pid , _default = % { } , @ timeout )
810
809
811
810
pending =
812
811
for { _mock , expected_funs } <- all_expectations ,
@@ -915,76 +914,77 @@ defmodule Mox do
915
914
916
915
@ doc false
917
916
def start_link_ownership do
918
- case N . start_link ( name: @ ownership_server ) do
917
+ case NimbleOwnership . start_link ( name: @ this ) do
919
918
{ :error , { :already_started , _ } } -> :ignore
920
919
other -> other
921
920
end
922
921
end
923
922
924
923
defp add_expectation ( owner_pid , { mock , _ , _ } = key , expectation ) do
925
- # First, make sure that the owner_pid is either the owner or that the mock
926
- # isn't owned yet. Otherwise, return an error.
927
- case N . fetch_owner ( @ ownership_server , [ owner_pid ] , mock , @ timeout ) do
928
- { tag , ^ owner_pid } when tag in [ :ok , :shared_owner ] -> :ok
929
- { :shared_owner , other_owner } -> throw ( { :error , { :not_shared_owner , other_owner } } )
930
- { :ok , other_owner } -> throw ( { :error , { :currently_allowed , other_owner } } )
931
- :error -> :ok
932
- end
933
-
934
- update_fun = fn
935
- nil ->
936
- { nil , % { key => expectation } }
924
+ case ensure_pid_can_add_expectation ( owner_pid , mock ) do
925
+ :ok ->
926
+ update_fun = & { :ok , init_or_merge_expectations ( & 1 , key , expectation ) }
927
+ :ok = get_and_update! ( owner_pid , mock , update_fun )
937
928
938
- % { } = expectations ->
939
- { nil , Map . update ( expectations , key , expectation , & merge_expectation ( & 1 , expectation ) ) }
929
+ { :error , reason } ->
930
+ { :error , reason }
940
931
end
941
-
942
- { :ok , _ } = N . get_and_update ( @ ownership_server , owner_pid , mock , update_fun , @ timeout )
943
- :ok
944
- catch
945
- { :error , reason } -> { :error , reason }
946
- end
947
-
948
- defp init_mock ( owner_pid , mock ) do
949
- { :ok , _ } = N . get_and_update ( @ ownership_server , owner_pid , mock , & { & 1 , % { } } , @ timeout )
950
- :ok
951
932
end
952
933
953
934
defp fetch_fun_to_dispatch ( caller_pids , { mock , _ , _ } = key ) do
954
- # If the mock doesn't have an owner, it can't have expectations so we return :no_expectation.
955
- owner_pid =
956
- case N . fetch_owner ( @ ownership_server , caller_pids , mock , @ timeout ) do
957
- { tag , owner_pid } when tag in [ :shared_owner , :ok ] -> owner_pid
958
- :error -> throw ( :no_expectation )
959
- end
960
-
961
935
parent = self ( )
962
936
963
- update_fun = fn expectations ->
964
- case expectations [ key ] do
965
- nil ->
966
- { :no_expectation , expectations }
937
+ with { :ok , owner_pid } <- fetch_owner_from_callers ( caller_pids , mock ) do
938
+ get_and_update! ( owner_pid , mock , fn expectations ->
939
+ case expectations [ key ] do
940
+ nil ->
941
+ { :no_expectation , expectations }
967
942
968
- { total , [ ] , nil } ->
969
- { { :out_of_expectations , total } , expectations }
943
+ { total , [ ] , nil } ->
944
+ { { :out_of_expectations , total } , expectations }
970
945
971
- { _ , [ ] , stub } ->
972
- { { ok_or_remote ( parent ) , stub } , expectations }
946
+ { _ , [ ] , stub } ->
947
+ { { ok_or_remote ( parent ) , stub } , expectations }
973
948
974
- { total , [ call | calls ] , stub } ->
975
- new_expectations = put_in ( expectations [ key ] , { total , calls , stub } )
976
- { { ok_or_remote ( parent ) , call } , new_expectations }
977
- end
949
+ { total , [ call | calls ] , stub } ->
950
+ new_expectations = put_in ( expectations [ key ] , { total , calls , stub } )
951
+ { { ok_or_remote ( parent ) , call } , new_expectations }
952
+ end
953
+ end )
954
+ end
955
+ end
956
+
957
+ # Make sure that the owner_pid is either the owner or that the mock
958
+ # isn't owned yet.
959
+ defp ensure_pid_can_add_expectation ( owner_pid , mock ) do
960
+ case NimbleOwnership . fetch_owner ( @ this , [ owner_pid ] , mock , @ timeout ) do
961
+ :error -> :ok
962
+ { tag , ^ owner_pid } when tag in [ :ok , :shared_owner ] -> :ok
963
+ { :shared_owner , other_owner } -> { :error , { :not_shared_owner , other_owner } }
964
+ { :ok , other_owner } -> { :error , { :currently_allowed , other_owner } }
978
965
end
966
+ end
979
967
980
- { :ok , return } = N . get_and_update ( @ ownership_server , owner_pid , mock , update_fun , @ timeout )
981
- return
982
- catch
983
- return -> return
968
+ defp fetch_owner_from_callers ( caller_pids , mock ) do
969
+ # If the mock doesn't have an owner, it can't have expectations so we return :no_expectation.
970
+ case NimbleOwnership . fetch_owner ( @ this , caller_pids , mock , @ timeout ) do
971
+ { tag , owner_pid } when tag in [ :shared_owner , :ok ] -> { :ok , owner_pid }
972
+ :error -> :no_expectation
973
+ end
984
974
end
985
975
986
- defp merge_expectation ( { current_n , current_calls , _current_stub } , { n , calls , stub } ) do
987
- { current_n + n , current_calls ++ calls , stub }
976
+ defp get_and_update! ( owner_pid , mock , update_fun ) do
977
+ case NimbleOwnership . get_and_update ( @ this , owner_pid , mock , update_fun , @ timeout ) do
978
+ { :ok , return } -> return
979
+ { :error , % NimbleOwnership.Error { } = error } -> raise error
980
+ end
981
+ end
982
+
983
+ defp init_or_merge_expectations ( current_exps , key , { n , calls , stub } = new_exp )
984
+ when is_map ( current_exps ) or is_nil ( current_exps ) do
985
+ Map . update ( current_exps || % { } , key , new_exp , fn { current_n , current_calls , _current_stub } ->
986
+ { current_n + n , current_calls ++ calls , stub }
987
+ end )
988
988
end
989
989
990
990
defp ok_or_remote ( source ) when node ( source ) == node ( ) , do: :ok
0 commit comments