reather
setup
Mix.install([
{:reather, "~> 0.1"},
{:mok, "~> 0.1"}
])
example
defmodule Target do
use Reather
require Mok
defmodule Impure do
reather read("invalid") do
Left.new(:enoent)
end
reather read("valid") do
Right.new(99)
end
end
reather read_and_multiply(filename) do
env <- Reather.ask()
input <- Impure.read(filename) |> Mok.inject(env)
multiply(input)
end
reatherp multiply(input) do
%{number: number} <- Reather.ask()
Right.new(input * number)
end
def mock, do: Mok.mock(%{&Target.Impure.read/1 => Right.new(77)})
end
private 함수인 multiply
에서 사용될 값을 Reather.run
을 통해 넣어줄 수 있다. (like Algae.Reader)
# 99 * 10
Target.read_and_multiply("valid") |> Reather.run(%{number: 10})
Reather.run
에 function capture 와 리턴값을 넣어두면, 함수를 쉽게 mocking 할 수 있다. (like definject)
# 77 * 10
Target.read_and_multiply("valid")
|> Reather.run(%{number: 10} |> Map.merge(Target.mock()))
defr vs reather
defr
defr get_moment_model_info(_, %{input: %{project_id: project_id}}, _) do
monad %Right{} do
moment_model_info <- ContentLogic.get_moment_model_info(project_id) |> run(%{})
return %{moment_model_info: moment_model_info} |> ContentView.render()
end
end
reather
reather get_moment_model_info(_, %{input: %{project_id: project_id}}, _) do
moment_model_info <- ContentLogic.get_moment_model_info(project_id)
%{moment_model_info: moment_model_info} |> ContentView.render()
end