Skip to content

Commit

Permalink
✨ Add new TestRunner behaviour for custom runners (#115)
Browse files Browse the repository at this point in the history
Use the behaviour for all internal implementations including for tests. Also, convert a second DummyRunner to use `start_supervised!`.
  • Loading branch information
randycoulman authored Sep 21, 2024
1 parent 6e217c2 commit 8b7ac58
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ ignore files with any of these extensions, you can specify an `exclude` regexp
By default `mix test.interactive` uses an internal module named
`MixTestInteractive.PortRunner` to run the tests. If you want to run the tests
in a different way, you can supply your own runner module instead. Your module
must implement a `run/2` function that takes a `MixTestInteractive.Config`
struct and a list of `String.t()` arguments.
must implement the `MixTestInteractive.TestRunner` behaviour, either implicitly
or explicitly.

```elixir
# config/config.exs
Expand Down
5 changes: 4 additions & 1 deletion lib/mix_test_interactive/command_line_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,10 @@ defmodule MixTestInteractive.CommandLineParser do
if function_exported?(module, :run, 2) do
{:ok, module}
else
{:error, UsageError.exception("--runner: '#{runner}' must name a module that implements a `run/2` function")}
{:error,
UsageError.exception(
"--runner: '#{runner}' must name a module that implements the `MixTestInteractive.TestRunner` behaviour"
)}
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/mix_test_interactive/port_runner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ defmodule MixTestInteractive.PortRunner do
On Windows, `mix` is run directly and ANSI mode is not enabled, as it is not always
supported by Windows command processors.
"""
@behaviour MixTestInteractive.TestRunner

alias MixTestInteractive.Config
alias MixTestInteractive.TestRunner

@application :mix_test_interactive

Expand All @@ -22,7 +24,7 @@ defmodule MixTestInteractive.PortRunner do
@doc """
Run tests based on the current configuration.
"""
@spec run(Config.t(), [String.t()], os_type(), runner()) :: :ok
@impl TestRunner
def run(%Config{} = config, task_args, os_type \\ :os.type(), runner \\ &System.cmd/3) do
{command, command_args} = config.command

Expand Down
11 changes: 11 additions & 0 deletions lib/mix_test_interactive/test_runner.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule MixTestInteractive.TestRunner do
@moduledoc """
Behaviour for custom test runners.
Any custom runner defined in the configuration or by command-line options must
implement this behaviour, either explicitly or implicitly.
"""
alias MixTestInteractive.Config

@callback run(Config.t(), [String.t()]) :: :ok
end
7 changes: 6 additions & 1 deletion test/mix_test_interactive/command_line_parser_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ defmodule MixTestInteractive.CommandLineParserTest do

defmodule CustomRunner do
@moduledoc false
def run(_config, _args), do: :noop
@behaviour MixTestInteractive.TestRunner

alias MixTestInteractive.TestRunner

@impl TestRunner
def run(_config, _args), do: :ok
end

defmodule NotARunner do
Expand Down
7 changes: 7 additions & 0 deletions test/mix_test_interactive/end_to_end_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,24 @@ defmodule MixTestInteractive.EndToEndTest do

defmodule DummyRunner do
@moduledoc false
@behaviour MixTestInteractive.TestRunner

use Agent

alias MixTestInteractive.TestRunner

def start_link(test_pid) do
Agent.start_link(fn -> test_pid end, name: __MODULE__)
end

@impl TestRunner
def run(config, args) do
Agent.update(__MODULE__, fn test_pid ->
send(test_pid, {config, args})
test_pid
end)

:ok
end
end

Expand Down
13 changes: 12 additions & 1 deletion test/mix_test_interactive/runner_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ defmodule MixTestInteractive.RunnerTest do

defmodule DummyRunner do
@moduledoc false
@behaviour MixTestInteractive.TestRunner

use Agent

alias MixTestInteractive.TestRunner

def start_link(initial_state) do
Agent.start_link(fn -> initial_state end, name: __MODULE__)
end

@impl TestRunner
def run(config, args) do
Agent.get_and_update(__MODULE__, fn data -> {:ok, [{config, args} | data]} end)
end
end

setup do
{:ok, _} = Agent.start_link(fn -> [] end, name: DummyRunner)
_pid = start_supervised!({DummyRunner, []})
:ok
end

Expand Down

0 comments on commit 8b7ac58

Please sign in to comment.