Current section

Files

Jump to
excheck lib excheck predicate.ex
Raw

lib/excheck/predicate.ex

defmodule ExCheck.Predicate do
@moduledoc """
Provides macros for predicates.
"""
@doc """
Verify the property is hold for all the generated samples.
> for_all x in int, do: x * x >= 0
"""
defmacro for_all({:in, _, [x, generator]}, [do: property]) do
quote do
{ :"prop:forall", unquote(generator), unquote(stringify(x)),
fn(unquote(x)) -> unquote(property) end, unquote(stringify(property)) }
end
end
@doc """
Verify the property is hold for all the generated samples.
> for_all(x, int) do
> x * x >= 0
> end
"""
defmacro for_all(x, generator, [do: property]) do
quote do
{ :"prop:forall", unquote(generator), unquote(stringify(x)),
fn(unquote(x)) -> unquote(property) end, unquote(stringify(property)) }
end
end
@doc """
Skip samples that does not satisfy the predicate.
"""
defmacro implies(predicate, [do: property]) do
quote do
{ :"prop:implies", unquote(predicate), unquote(stringify(predicate)),
fn() -> unquote(property) end, unquote(stringify(property)) }
end
end
@doc """
Specify the block to be called when the test is failed.
"""
defmacro when_fail(action, [do: property]) do
quote do
{ :"prop:whenfail", fn() -> unquote(action) end,
fn() -> unquote(property) end, unquote(stringify(property)) }
end
end
@doc """
Specify the block to be executed with spawn_link
"""
defmacro trap_exit([do: property]) do
quote do
{ :"prop:trapexit", fn() -> unquote(property) end,
unquote(stringify(property)) }
end
end
@doc """
Specify the block to be executed with timeout.
"""
defmacro timeout(limit, [do: property]) do
quote do
{ :"prop:timeout", unquote(limit),
fn() -> unquote(property) end, unquote(stringify(property)) }
end
end
@doc """
Generate samples which satisfies the predicate.
"""
defmacro such_that({:when, _, [{:in, _, [x, generator]}, predicate]}) do
quote do
:triq_dom.suchthat(
unquote(generator), fn(unquote(x)) -> unquote(predicate) end)
end
end
defp stringify(tree) do
tree |> Macro.to_string |> String.to_char_list
end
end