Adds more extensive koans about spawn, spawn_link and spawn_monitor
This commit is contained in:
@@ -48,8 +48,10 @@ defmodule BlankAssertions do
|
|||||||
ExUnit.Assertions.refute(value, opts)
|
ExUnit.Assertions.refute(value, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def flunk(message \\ "Flunked!") do
|
defmacro flunk(message \\ "Flunked!") do
|
||||||
assert false, message: message
|
quote do
|
||||||
|
assert false, message: unquote(message)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp contains_blank?(expr) do
|
defp contains_blank?(expr) do
|
||||||
|
|||||||
@@ -13,19 +13,7 @@ defmodule Processes do
|
|||||||
|
|
||||||
koan "process can send messages to itself" do
|
koan "process can send messages to itself" do
|
||||||
send self(), "hola!"
|
send self(), "hola!"
|
||||||
receive do
|
assert_receive "hola!"
|
||||||
message -> assert message == "hola!"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
koan "a spawned process is independent of the current process" do
|
|
||||||
pid = spawn(fn -> receive do
|
|
||||||
{:hello, thing} -> assert thing == "world"
|
|
||||||
_ -> assert false
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
send pid, {:hello, "world"}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
koan "a common pattern is to include the sender in the message" do
|
koan "a common pattern is to include the sender in the message" do
|
||||||
@@ -40,9 +28,9 @@ defmodule Processes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
koan "you don't have to wait forever for messages" do
|
koan "you don't have to wait forever for messages" do
|
||||||
parent = self
|
parent = self()
|
||||||
spawn(fn -> receive do
|
spawn(fn -> receive do
|
||||||
_ -> assert false
|
_anything -> flunk "I really wasn't expecting messages"
|
||||||
after
|
after
|
||||||
10 -> send parent, {:waited_too_long, "I am inpatient"}
|
10 -> send parent, {:waited_too_long, "I am inpatient"}
|
||||||
end
|
end
|
||||||
@@ -50,4 +38,86 @@ defmodule Processes do
|
|||||||
|
|
||||||
assert_receive {:waited_too_long, "I am inpatient"}
|
assert_receive {:waited_too_long, "I am inpatient"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
koan "killing a process will terminate it" do
|
||||||
|
pid = spawn(fn -> Process.exit(self(), :kill) end)
|
||||||
|
:timer.sleep(500)
|
||||||
|
refute Process.alive?(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "killing a process kills it for good" do
|
||||||
|
pid = spawn(fn -> receive do
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
assert Process.alive?(pid)
|
||||||
|
Process.exit(pid, :kill)
|
||||||
|
refute Process.alive?(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "can trap a signal in a child process" do
|
||||||
|
parent = self()
|
||||||
|
pid = spawn(fn ->
|
||||||
|
Process.flag(:trap_exit, true)
|
||||||
|
send parent, :ready
|
||||||
|
receive do
|
||||||
|
{:EXIT, _pid, reason} -> send parent, {:exited, reason}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
wait()
|
||||||
|
Process.exit(pid, :random_reason)
|
||||||
|
|
||||||
|
assert_receive {:exited, :random_reason}
|
||||||
|
refute Process.alive?(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "quitting normally has no effect" do
|
||||||
|
pid = spawn(fn -> receive do
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
Process.exit(pid, :normal)
|
||||||
|
assert Process.alive?(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "quititing your own process normally does terminate it though" do
|
||||||
|
pid = spawn(fn -> receive do
|
||||||
|
:bye -> Process.exit(self(), :normal)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert Process.alive?(pid)
|
||||||
|
send pid, :bye
|
||||||
|
:timer.sleep(100)
|
||||||
|
refute Process.alive?(pid)
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "linked processes are informed about exit signals of children when trapping those signals" do
|
||||||
|
parent = self()
|
||||||
|
spawn(fn ->
|
||||||
|
Process.flag(:trap_exit, true)
|
||||||
|
spawn_link(fn -> Process.exit(self(), :normal) end)
|
||||||
|
receive do
|
||||||
|
{:EXIT, _pid ,reason} -> send parent, {:exited, reason}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert_receive {:exited, :normal}
|
||||||
|
end
|
||||||
|
|
||||||
|
koan "monitoring processes are informed via messages without having trapping" do
|
||||||
|
parent = self()
|
||||||
|
spawn(fn ->
|
||||||
|
spawn_monitor(fn -> Process.exit(self(), :normal) end)
|
||||||
|
receive do
|
||||||
|
{:DOWN, _ref, :process, _pid, reason} -> send parent, {:exited, reason}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert_receive {:exited, :normal}
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait do
|
||||||
|
receive do
|
||||||
|
:ready -> true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user