@@ -183,6 +183,13 @@ defmodule Mox do
183183 `$callers` is used to determine the process that actually defined the
184184 expectations.
185185
186+ > #### Parent PIDs {: .tip}
187+ > [Since OTP 25](https://erlang.org/documentation/doc-15.0-rc2/erts-14.3/doc/html/notes.html#erts-13-0),
188+ > `Process.info/2` supports a `:parent` key for retrieving the parent of the given PID.
189+ > Mox started using this in v1.3.0 to determine process tree structures in case `$callers`
190+ > is not available in the process dictionary. This means that even more allowance cases
191+ > are taken care of automatically.
192+
186193 #### Explicit allowances as lazy/deferred functions
187194
188195 Under some circumstances, the process might not have been already started
@@ -941,7 +948,27 @@ defmodule Mox do
941948
942949 # Find the pid of the actual caller
943950 defp caller_pids do
944- Process . get ( :"$callers" , [ ] )
951+ case Process . get ( :"$callers" ) do
952+ nil -> [ self ( ) | recursive_parents ( self ( ) ) ]
953+ pids when is_list ( pids ) -> pids
954+ end
955+ end
956+
957+ # A PID with no parent has :undefined as its parent.
958+ defp recursive_parents ( :undefined ) do
959+ [ ]
960+ end
961+
962+ defp recursive_parents ( pid ) when is_pid ( pid ) do
963+ Process . info ( pid , :parent )
964+ rescue
965+ # erlang:process_info(Pid, parent) is not available, as it was released in
966+ # ERTS 13.0 (https://erlang.org/documentation/doc-15.0-rc2/erts-14.3/doc/html/notes.html#erts-13-0)
967+ ArgumentError ->
968+ [ ]
969+ else
970+ { :parent , parent_pid } ->
971+ [ parent_pid | recursive_parents ( parent_pid ) ]
945972 end
946973
947974 ## Ownership
0 commit comments