Packages
espec
1.2.0
1.10.0
1.9.2
1.9.1
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.0
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
0.8.28
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.7
0.3.5
0.3.0
0.2.0
0.1.0
BDD testing framework for Elixir inspired by RSpec.
Current section
Files
Jump to
Current section
Files
lib/espec/let/let_impl.ex
defmodule ESpec.Let.Impl do
@moduledoc """
'let' implementation is here.
"""
@agent_name :espec_let_agent
@doc "This function is used by the let macro to implement lazy evaluation"
def let_eval(module, var) do
case agent_get({self(), module, var}) do
{:todo, module, funcname} ->
shared = agent_get({self(), :shared})
result = apply(module, funcname, [shared])
agent_put({self(), module, var}, {:done, result})
result
{:done, result} ->
result
nil ->
funcname = case var do
:subject -> "subject"
_ -> "let function `#{var}/0`"
end
raise ESpec.LetError, "The #{funcname} is not defined in the current scope!"
end
end
@doc "Starts Agent to save state of 'lets'."
def start_agent, do: Agent.start_link(fn -> Map.new end, name: @agent_name)
@doc "Stops Agent"
def stop_agent, do: Agent.stop(@agent_name)
@doc "Resets stored let value and prepares for evaluation. Called by ExampleRunner."
def run_before(let) do
agent_module = if let.shared, do: let.shared_module, else: let.module
agent_put({self(), agent_module, let.var}, {:todo, let.module, let.function})
end
@doc "Clears all let values for the given module. Called by ExampleRunner."
def clear_lets(module) do
me = self()
Agent.update(@agent_name, fn(map) ->
keys_to_remove = Map.keys(map) |> Enum.filter(&match?({^me, ^module, _}, &1))
Map.drop(map, keys_to_remove)
end)
end
@doc "Updates the shared map that is available to let blocks. Called by ExampleRunner."
def update_shared(shared) do
agent_put({self(), :shared}, shared)
end
defp agent_get(key) do
dict = Agent.get(@agent_name, &(&1))
Map.get(dict, key)
end
defp agent_put(key, value), do: Agent.update(@agent_name, &(Map.put(&1, key, value)))
def random_let_name, do: String.to_atom("let_#{ESpec.Support.random_string}")
end