Packages

A polite, well mannered and thoroughly upstanding testing framework for Elixir

Current section

Files

Jump to
amrita lib mix tasks amrita.ex
Raw

lib/mix/tasks/amrita.ex

defmodule Mix.Tasks.Amrita do
use Mix.Task
@switches [force: :boolean, color: :boolean, cover: :boolean,
trace: :boolean, max_cases: :integer, include: :keep,
exclude: :keep, seed: :integer, only: :keep, compile: :boolean,
start: :boolean]
@shortdoc "Run Amrita tests"
@recursive true
def run(args) do
{ opts, files, _ } = OptionParser.parse(args, switches: @switches)
unless System.get_env("MIX_ENV") do
Mix.env(:test)
end
Mix.Task.run "app.start", args
project = Mix.Project.config
case Application.load(:ex_unit) do
:ok -> :ok
{:error, {:already_loaded, :ex_unit}} -> :ok
end
# Start the app and configure exunit with command line options
# before requiring test_helper.exs so that the configuration is
# available in test_helper.exs. Then configure exunit again so
# that command line options override test_helper.exs
Amrita.Engine.Start.configure(opts)
opts = amrita_opts(opts)
test_paths = project[:test_paths] || ["test"]
Enum.each(test_paths, &require_test_helper(&1))
Amrita.Engine.Start.configure(opts)
test_files = parse_files(files, test_paths)
test_pattern = project[:test_pattern] || "*.exs"
files = Mix.Utils.extract_files(test_files, test_pattern)
Kernel.ParallelRequire.files files
end
@doc false
def amrita_opts(opts) do
opts = opts
|> filter_opts(:include)
|> filter_opts(:exclude)
|> filter_only_opts()
default_opts(opts) ++
Dict.take(opts, [:trace, :max_cases, :include, :exclude, :seed])
end
defp default_opts(opts) do
# Set autorun to false because Mix
# automatically runs the test suite for us.
case Dict.get(opts, :color) do
nil -> [autorun: false]
enabled? -> [autorun: false, colors: [enabled: enabled?]]
end
end
defp parse_files([], test_paths) do
test_paths
end
defp parse_files([single_file], _test_paths) do
# Check if the single file path matches test/path/to_test.exs:123, if it does
# apply `--only line:123` and trim the trailing :123 part.
{single_file, opts} = ExUnit.Filters.parse_path(single_file)
ExUnit.configure(opts)
[single_file]
end
defp parse_files(files, _test_paths) do
files
end
defp parse_filters(opts, key) do
if Keyword.has_key?(opts, key) do
ExUnit.Filters.parse(Keyword.get_values(opts, key))
end
end
defp filter_opts(opts, key) do
if filters = parse_filters(opts, key) do
Keyword.put(opts, key, filters)
else
opts
end
end
defp filter_only_opts(opts) do
if filters = parse_filters(opts, :only) do
opts
|> Keyword.put_new(:include, [])
|> Keyword.put_new(:exclude, [])
|> Keyword.update!(:include, &(filters ++ &1))
|> Keyword.update!(:exclude, &[:test|&1])
else
opts
end
end
defp require_test_helper(dir) do
file = Path.join(dir, "test_helper.exs")
if File.exists?(file) do
Code.require_file file
else
raise Mix.Error, message: "Cannot run tests because test helper file #{inspect file} does not exist"
end
end
end