Current section

Files

Jump to
espec lib espec example.ex
Raw

lib/espec/example.ex

defmodule ESpec.Example do
@moduledoc """
Defines macros 'example' and 'it'.
These macros defines function with random name which will be called when example runs.
Example structs %ESpec.Example are accumulated in @examples attribute
"""
@doc """
Expampe struct.
description - the description of example,
module - spec module,
function - random function name,
opts - options,
file - spec file path,
line - the line where example is defined,
context - example context. Accumulator for 'contexts' and 'lets',
shared - marks example as shared,
status - example status (:new, :success, :failure, :pending),
result - the value returned by example block or the pending message
error - store an error.
"""
defstruct description: "", module: nil, function: nil, opts: [],
file: nil, line: nil, context: [], shared: false, async: false,
status: :new, result: nil, error: %ESpec.AssertionError{}
@doc "Description with contexts."
def context_descriptions(%ESpec.Example{context: context, description: _description, function: _function}) do
context
|> Enum.filter(fn(struct) -> struct.__struct__ == ESpec.Context end)
|> Enum.map(&(&1.description))
end
@doc "Filters success examples."
def success(results) do
results |> Enum.filter(&(&1.status == :success))
end
@doc "Filters failed examples."
def failure(results) do
results |> Enum.filter(&(&1.status === :failure))
end
@doc "Filters pending examples."
def pendings(results) do
results |> Enum.filter(&(&1.status === :pending))
end
@doc "Extracts specific structs from example context."
def extract_befores_and_lets(example), do: extract(example.context, [ESpec.Before, ESpec.Let])
def extract_finallies(example), do: extract(example.context, [ESpec.Finally])
def extract_contexts(example), do: extract(example.context, [ESpec.Context])
@doc "Extracts example options."
def extract_option(example, option) do
contexts = ESpec.Example.extract_contexts(example)
opts = List.flatten(example.opts ++ Enum.reverse(Enum.map(contexts, &(&1.opts))))
opt = Enum.find(opts, fn({k, _v}) -> k == option end)
if opt do
{^option, value} = opt
value
else
nil
end
end
defp extract(context, modules) do
Enum.filter(context, &Enum.member?(modules, &1.__struct__))
end
@doc "Message for skipped examples."
def skip_message(example) do
skipper = extract_option(example, :skip)
if skipper === true do
"Temporarily skipped without a reason."
else
"Temporarily skipped with: #{skipper}."
end
end
@doc "Message for pending examples."
def pending_message(example) do
if example.opts[:pending] === true do
"Pending example."
else
"Pending with message: #{example.opts[:pending]}."
end
end
end