View Source MixTester (MixTester v1.1.0)

Small tool to automate mix project creation specifically for testing.

Summary

Types

Accepts same options as System.cmd function

Output and exit code returned by executed command

  • :name (string) — Name of the mix project (doesn't have to be unique)
  • :new (string) — String of options for mix new name
  • :application_env (application_env) — A configuration for the project
  • :system_env (env maps) — System env configuration
  • :project - A kv to override what's written in mix.exs's project function
  • :application - A kv to override what's written in mix.exs's application function

Functions

Changes Elixir AST of file

Deletes project

Removes all existing projects

Executes command in project root

Checks if path exists in the project

Expands path from relative path of the project

Executes mix command in project root

Executes mix test in the project. Returns true or false

Create a directory for specified file.

Reads the existing file from project

Sets up the mix project for testing

Executes shell command in the project

Writes a file in the project

Types

@type application_env() :: %{
  required(config_file :: String.t()) => %{
    required({app :: atom(), key :: atom()}) => value :: any()
  }
}
@type command_option() :: {atom(), any()}

Accepts same options as System.cmd function

@type command_result() :: {binary(), non_neg_integer()}

Output and exit code returned by executed command

@type setup_option() ::
  {:name, String.t()}
  | {:new, String.t()}
  | {:application_env, application_env()}
  • :name (string) — Name of the mix project (doesn't have to be unique)
  • :new (string) — String of options for mix new name
  • :application_env (application_env) — A configuration for the project
  • :system_env (env maps) — System env configuration
  • :project - A kv to override what's written in mix.exs's project function
  • :application - A kv to override what's written in mix.exs's application function

Functions

Link to this function

at_ast(project, filename, func)

View Source
@spec at_ast(MixTester.Project.t(), Path.t(), (Macro.t() -> Macro.t())) :: :ok

Changes Elixir AST of file

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.at_ast(project, "lib/example.ex", fn ast ->
...>   Macro.prewalk(ast, fn
...>     :world -> :not_the_world_mhahaha
...>     other -> other
...>   end)
...> end)
iex> {_, 2} = MixTester.mix_cmd(project, "test")
@spec cleanup(MixTester.Project.t()) :: :ok

Deletes project

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.cleanup(project)
iex> MixTester.exists?(project, "mix.exs")
false
@spec cleanup_all() :: :ok

Removes all existing projects

Example:

iex> project1 = MixTester.setup(name: :example)
iex> project2 = MixTester.setup(name: :example)
iex> MixTester.cleanup_all()
iex> MixTester.exists?(project1, "mix.exs")
false
iex> MixTester.exists?(project2, "mix.exs")
false
Link to this function

cmd(project, command, args, opts \\ [])

View Source

Executes command in project root

Example:

iex> project = MixTester.setup(name: :example)
iex> {ls, 0} = MixTester.cmd(project, "ls", ["-l", "-a"])
iex> ls =~ "mix.exs"
Link to this function

exists?(project, filename)

View Source
@spec exists?(MixTester.Project.t(), Path.t()) :: boolean()

Checks if path exists in the project

Example:

iex> project = MixTester.setup()
iex> MixTester.exists?(project, "mix.exs")
true
iex> MixTester.exists?(project, "this_file_does_not_exist_actually.txt")
false
Link to this function

expand(project, filename)

View Source
@spec expand(MixTester.Project.t(), Path.t()) :: Path.t()

Expands path from relative path of the project

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.expand(project, "mix.exs")
"/tmp/mix_tester/123/example/mix.exs"
Link to this function

mix_cmd(project, command, args \\ [], opts \\ [])

View Source

Executes mix command in project root

Example:

iex> project = MixTester.setup(name: :example)
iex> {_, 0} = MixTester.mix_cmd(project, "compile")
Link to this macro

mix_test(project, args \\ [], opts \\ [])

View Source (macro)

Executes mix test in the project. Returns true or false

Example

iex> project = MixTester.setup(name: :example)
iex> true = MixTester.mix_test(project)
Link to this function

mkdir_p(project, filename)

View Source
@spec mkdir_p(MixTester.Project.t(), Path.t()) :: Path.t()

Create a directory for specified file.

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.mkdir_p(project, "priv/static/file")
iex> MixTester.sh(project, "ls priv/")
{"static\n", 0}
@spec read(MixTester.Project.t(), Path.t()) :: binary()

Reads the existing file from project

Example:

iex> project = MixTester.setup(name: :example)
iex> "defmodule Example" <> _ = MixTester.read(project, "lib/example.ex")
@spec setup([setup_option()]) :: MixTester.Project.t()

Sets up the mix project for testing

Example:

iex> deps = [pathex: "~> 2.5"]
iex> project = MixTester.setup(name: :example, project: [deps: deps])
iex> "defmodule Example" <> _ = MixTester.read(project, "lib/example.ex")
Link to this function

sh(project, command_string, opts \\ [])

View Source
@spec sh(MixTester.Project.t(), command :: String.t(), [command_option()]) ::
  command_result()

Executes shell command in the project

Example:

iex> project = MixTester.setup(name: :example)
iex> {ls, 0} = MixTester.sh(project, "ls -la")
iex> ls =~ "mix.exs"
Link to this function

write(project, filename, content, modes \\ [])

View Source
@spec write(MixTester.Project.t(), Path.t(), iodata(), list()) :: :ok

Writes a file in the project

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.write(project, "priv/something.txt", "Hello!")
iex> MixTester.read(project, "priv/something.txt")
"Hello!"
Link to this function

write_ast(project, filename, ast, modes \\ [])

View Source
@spec write_ast(MixTester.Project.t(), Path.t(), Macro.t(), list()) :: :ok

Writes an AST in the file

Example:

iex> project = MixTester.setup(name: :example)
iex> MixTester.write_ast(project, "test/test_helper.exs", quote do: ExUnit.start(max_failures: 1))
iex> {_, 0} = MixTester.mix_cmd(project, "test")
iex> MixTester.read(project, "test/test_helper.exs")
"ExUnit.start(max_failures: 1)"