Current section

Files

Jump to
ex_spec lib ex_spec.ex
Raw

lib/ex_spec.ex

defmodule ExSpec do
@moduledoc """
ExSpec is a simple wrapper around ExUnit that adds Rspec-style macros. Specifically, it adds `context` and `it`.
While it takes inspiration from Rspec, ExSpec is significantly simplier. The `context` macro has only two functions:
1. Aid test organization
2. Prepend to the message of any `it` defined within its do blocks
The `it` macro is identical to `ExUnit.Case.test` except that it is aware of the messages of its surrounding `context` blocks. It also works seemlessly with `ExUnit`'s `describe` function.
Other than the functionality described above, ExSpec is just ExUnit. When `use`ing `ExSpec`, any options provided will be passed to `ExUnit.Case` (e.g. `async: true`).
A simple example is shown below. For more examples, see the tests.
### Example
defmodule PersonTest do
use ExSpec, async: true
describe "name" do
context "with first and last name" do
it "joins the names with a space" do
drew = %Person{first_name: "Drew", last_name: "Olson"}
assert Person.name(drew) == "Drew Olson"
end
end
context "with only a first name" do
it "returns the first name" do
drew = %Person{first_name: "Drew", last_name: nil}
assert Person.name(drew) == "Drew"
end
end
end
end
"""
defmacro __using__(options) do
quote do
import ExSpec
use ExUnit.Case, unquote(options)
Module.put_attribute(__MODULE__, :ex_spec_contexts, [])
end
end
defmacro context(message, body) do
quote do
previous_contexts = Module.get_attribute(__MODULE__, :ex_spec_contexts)
context = %ExSpec.Context{name: unquote(message)}
Module.put_attribute(__MODULE__, :ex_spec_contexts, [context|previous_contexts])
unquote(body)
Module.put_attribute(__MODULE__, :ex_spec_contexts, previous_contexts)
end
end
defmacro it(message) do
quote do
full_message = ExSpec.Helpers.full_message(__MODULE__, unquote(message))
ExUnit.Case.test(full_message)
end
end
defmacro it(message, var \\ quote(do: _), body) do
quote do
full_message = ExSpec.Helpers.full_message(__MODULE__, unquote(message))
ExUnit.Case.test(full_message, unquote(var), unquote(body))
end
end
end