@@ -647,11 +647,17 @@ defmodule Mox do
647647 end
648648
649649 defp do_stub_with ( mock , module , behaviours , _behaviours_common ) do
650- for behaviour <- behaviours ,
651- { fun , arity } <- behaviour . behaviour_info ( :callbacks ) ,
652- function_exported? ( mock , fun , arity ) do
653- stub ( mock , fun , :erlang . make_fun ( module , fun , arity ) )
654- end
650+ key_expectation_list =
651+ for behaviour <- behaviours ,
652+ { fun , arity } <- behaviour . behaviour_info ( :callbacks ) ,
653+ function_exported? ( mock , fun , arity ) do
654+ {
655+ { mock , fun , arity } ,
656+ { 0 , [ ] , :erlang . make_fun ( module , fun , arity ) }
657+ }
658+ end
659+
660+ add_expectations! ( mock , key_expectation_list )
655661
656662 mock
657663 end
@@ -675,30 +681,47 @@ defmodule Mox do
675681 raise ArgumentError , "unknown function #{ name } /#{ arity } for mock #{ inspect ( mock ) } "
676682 end
677683
678- case add_expectation ( self ( ) , key , value ) do
684+ case add_expectations ( self ( ) , mock , [ { key , value } ] ) do
679685 :ok ->
680686 :ok
681687
682- { :error , { :currently_allowed , owner_pid } } ->
683- inspected = inspect ( self ( ) )
688+ { :error , error } ->
689+ raise ArgumentError , expectation_error_to_message ( error , mock )
690+ end
691+ end
684692
685- raise ArgumentError , """
686- cannot add expectations/stubs to #{ inspect ( mock ) } in the current process (#{ inspected } ) \
687- because the process has been allowed by #{ inspect ( owner_pid ) } . \
688- You cannot define expectations/stubs in a process that has been allowed
689- """
693+ defp add_expectations! ( mock , key_expectation_list ) do
694+ validate_mock! ( mock )
690695
691- { :error , { :not_shared_owner , global_pid } } ->
692- inspected = inspect ( self ( ) )
696+ case add_expectations ( self ( ) , mock , key_expectation_list ) do
697+ :ok ->
698+ :ok
693699
694- raise ArgumentError , """
695- cannot add expectations/stubs to #{ inspect ( mock ) } in the current process (#{ inspected } ) \
696- because Mox is in global mode and the global process is #{ inspect ( global_pid ) } . \
697- Only the process that set Mox to global can set expectations/stubs in global mode
698- """
700+ { :error , error } ->
701+ raise ArgumentError , expectation_error_to_message ( error , mock )
699702 end
700703 end
701704
705+ defp expectation_error_to_message ( { :currently_allowed , owner_pid } , mock ) do
706+ inspected = inspect ( self ( ) )
707+
708+ """
709+ cannot add expectations/stubs to #{ inspect ( mock ) } in the current process (#{ inspected } ) \
710+ because the process has been allowed by #{ inspect ( owner_pid ) } . \
711+ You cannot define expectations/stubs in a process that has been allowed
712+ """
713+ end
714+
715+ defp expectation_error_to_message ( { :not_shared_owner , global_pid } , mock ) do
716+ inspected = inspect ( self ( ) )
717+
718+ """
719+ cannot add expectations/stubs to #{ inspect ( mock ) } in the current process (#{ inspected } ) \
720+ because Mox is in global mode and the global process is #{ inspect ( global_pid ) } . \
721+ Only the process that set Mox to global can set expectations/stubs in global mode
722+ """
723+ end
724+
702725 @ doc """
703726 Allows other processes to share expectations and stubs
704727 defined by owner process.
@@ -924,10 +947,10 @@ defmodule Mox do
924947 end
925948 end
926949
927- defp add_expectation ( owner_pid , { mock , _ , _ } = key , expectation ) do
950+ defp add_expectations ( owner_pid , mock , key_expectation_list ) do
928951 case ensure_pid_can_add_expectation ( owner_pid , mock ) do
929952 :ok ->
930- update_fun = & { :ok , init_or_merge_expectations ( & 1 , key , expectation ) }
953+ update_fun = & { :ok , init_or_merge_expectations ( & 1 , key_expectation_list ) }
931954 :ok = get_and_update! ( owner_pid , mock , update_fun )
932955
933956 { :error , reason } ->
@@ -984,13 +1007,18 @@ defmodule Mox do
9841007 end
9851008 end
9861009
987- defp init_or_merge_expectations ( current_exps , key , { n , calls , stub } = new_exp )
1010+ defp init_or_merge_expectations ( current_exps , [ { key , { n , calls , stub } = new_exp } | tail ] )
9881011 when is_map ( current_exps ) or is_nil ( current_exps ) do
989- Map . update ( current_exps || % { } , key , new_exp , fn { current_n , current_calls , _current_stub } ->
990- { current_n + n , current_calls ++ calls , stub }
991- end )
1012+ init_or_merge_expectations (
1013+ Map . update ( current_exps || % { } , key , new_exp , fn { current_n , current_calls , _current_stub } ->
1014+ { current_n + n , current_calls ++ calls , stub }
1015+ end ) ,
1016+ tail
1017+ )
9921018 end
9931019
1020+ defp init_or_merge_expectations ( current_exps , [ ] ) , do: current_exps
1021+
9941022 defp ok_or_remote ( source ) when node ( source ) == node ( ) , do: :ok
9951023 defp ok_or_remote ( _source ) , do: :remote
9961024end
0 commit comments