126 lines
2.6 KiB
Elixir
126 lines
2.6 KiB
Elixir
Code.require_file("../test_helper.exs", __DIR__)
|
|
|
|
defmodule Kernel.WithTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
test "basic with" do
|
|
assert with({:ok, res} <- ok(41), do: res) == 41
|
|
assert with(res <- four(), do: res + 10) == 14
|
|
end
|
|
|
|
test "matching with" do
|
|
assert with(_..42 <- 1..42, do: :ok) == :ok
|
|
assert with({:ok, res} <- error(), do: res) == :error
|
|
assert with({:ok, _} = res <- ok(42), do: elem(res, 1)) == 42
|
|
end
|
|
|
|
test "with guards" do
|
|
assert with(x when x < 2 <- four(), do: :ok) == 4
|
|
assert with(x when x > 2 <- four(), do: :ok) == :ok
|
|
assert with(x when x < 2 when x == 4 <- four(), do: :ok) == :ok
|
|
end
|
|
|
|
test "pin matching with" do
|
|
key = :ok
|
|
assert with({^key, res} <- ok(42), do: res) == 42
|
|
end
|
|
|
|
test "two levels with" do
|
|
result =
|
|
with {:ok, n1} <- ok(11),
|
|
n2 <- 22,
|
|
do: n1 + n2
|
|
|
|
assert result == 33
|
|
|
|
result =
|
|
with n1 <- 11,
|
|
{:ok, n2} <- error(),
|
|
do: n1 + n2
|
|
|
|
assert result == :error
|
|
end
|
|
|
|
test "binding inside with" do
|
|
result =
|
|
with {:ok, n1} <- ok(11),
|
|
n2 = n1 + 10,
|
|
{:ok, n3} <- ok(22),
|
|
do: n2 + n3
|
|
|
|
assert result == 43
|
|
|
|
result =
|
|
with {:ok, n1} <- ok(11),
|
|
n2 = n1 + 10,
|
|
{:ok, n3} <- error(),
|
|
do: n2 + n3
|
|
|
|
assert result == :error
|
|
end
|
|
|
|
test "does not leak variables to else" do
|
|
state = 1
|
|
|
|
result =
|
|
with 1 <- state,
|
|
state = 2,
|
|
:ok <- error(),
|
|
do: state,
|
|
else: (_ -> state)
|
|
|
|
assert result == 1
|
|
assert state == 1
|
|
end
|
|
|
|
test "errors in with" do
|
|
assert_raise RuntimeError, fn ->
|
|
with({:ok, res} <- oops(), do: res)
|
|
end
|
|
|
|
assert_raise RuntimeError, fn ->
|
|
with({:ok, res} <- ok(42), res = res + oops(), do: res)
|
|
end
|
|
end
|
|
|
|
test "else conditions" do
|
|
assert (with {:ok, res} <- four() do
|
|
res
|
|
else
|
|
{:error, error} -> error
|
|
res -> res + 1
|
|
end) == 5
|
|
|
|
assert (with {:ok, res} <- four() do
|
|
res
|
|
else
|
|
res when res == 4 -> res + 1
|
|
res -> res
|
|
end) == 5
|
|
|
|
assert with({:ok, res} <- four(), do: res, else: (_ -> :error)) == :error
|
|
end
|
|
|
|
test "else conditions with match error" do
|
|
assert_raise WithClauseError, "no with clause matching: :error", fn ->
|
|
with({:ok, res} <- error(), do: res, else: ({:error, error} -> error))
|
|
end
|
|
end
|
|
|
|
defp four() do
|
|
4
|
|
end
|
|
|
|
defp error() do
|
|
:error
|
|
end
|
|
|
|
defp ok(num) do
|
|
{:ok, num}
|
|
end
|
|
|
|
defp oops() do
|
|
raise("oops")
|
|
end
|
|
end
|