Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💥 Configless operation #108

Merged
merged 19 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,55 @@ end

## Usage

Run the mix task:

```shell
mix test.interactive
mix test.interactive <options> [-- <mix test arguments>]
mix test.interactive <mix test arguments>
mix test.interactive --help
mix test.interactive --version
```

Your tests will run immediately (and every time a file changes).

If you don't want tests to run automatically when files change, you can start `mix test.interactive` with the `--no-watch` flag:
### Options

```shell
mix test.interactive --no-watch
```
`mix test.interactive` understands the following options, most of which
correspond to configuration settings below.

Note that, if you want to pass both mix test.interactive options and mix test
arguments, you must separate them with `--`.

If an option is provided on the command line, it will override the same option
specified in the configuration.

- `--(no-)clear`: Clear the console before each run (default `false`).
- `--command <command> [--arg <arg>]`: Custom command and arguments for
running tests (default: "mix" with no arguments). NOTE: Use `--arg` multiple
times to specify more than one argument.
- `--exclude <regex>`: Exclude files/directories from triggering test runs
(default: `["~r/\.#/", "~r{priv/repo/migrations}"`]) NOTE: Use `--exclude`
multiple times to specify more than one regex.
- `--extra-extensions <extension>`: Watch files with additional extensions
(default: []).
- `--runner <module name>`: Use a custom runner module (default:
`MixTestInteractive.PortRunner`).
- `--task <task name>`: Run a different mix task (default: `"test"`).
- `--(no-)timestamp`: Display the current time before running the tests
(default: `false`).
- `--(no-)watch`: Don't run tests when a file changes (default: `true`).

All of the `<mix test arguments>` are passed through to `mix test` on every
test run.

`mix test.interactive` will detect the `--stale` and `--failed` flags and use those as initial settings in interactive mode. You can then toggle those flags on and off as needed. It will also detect any filename or pattern arguments and use those as initial settings. However, it does not detect any filenames passed with `--include` or `--only`. Note that if you specify a pattern on the command-line, `mix test.interactive` will find all test files matching that pattern and pass those to `mix test` as if you had used the `p` command.

### Patterns and filenames

`mix test.interactive` can take the same filename or filename:line_number
patterns that `mix test` understands. It also allows you to specify one or
more "patterns" - strings that match one or more test files. When you provide
one or more patterns on the command-line, `mix test.interactive` will find all
test files matching those patterns and pass them to `mix test` as if you had
used the `p` command (described below).

After the tests run, you can use the interactive mode to change which tests will run.

Expand All @@ -62,21 +98,11 @@ Use the `Enter` key to re-run the current set of tests without requiring a file

Use the `q` command, or press `Ctrl-D` to exit the program.

## Passing Arguments To Tasks

Any command line arguments passed to the `mix test.interactive` task will be passed
through to the task being run, along with any arguments added by interactive mode. If I want to see detailed trace information for my tests, I can run:

```
mix test.interactive --trace
```

`mix test.interactive` will detect the `--stale` and `--failed` flags and use those as initial settings in interactive mode. You can then toggle those flags on and off as needed. It will also detect any filename or pattern arguments and use those as initial settings. However, it does not detect any filenames passed with `--include` or `--only`. Note that if you specify a pattern on the command-line, `mix test.interactive` will find all test files matching that pattern and pass those to `mix test` as if you had used the `p` command.

## Configuration

`mix test.interactive` can be configured with various options using application
configuration.
configuration. You can also use command line arguments to specify these
configuration options, or to override configured options.

### `clear`: Clear the console before each run

Expand Down
39 changes: 33 additions & 6 deletions lib/mix/tasks/test/interactive.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,43 @@ defmodule Mix.Tasks.Test.Interactive do
## Usage

```shell
mix test.interactive [options] pattern...
mix test.interactive <options> [-- <mix test arguments>]
mix test.interactive <mix test arguments>
mix test.interactive --help
mix test.interactive --version
```

Your tests will run immediately (and every time a file changes).

### Options

`mix test.interactive` understands the following options:
- `--no-watch`: Don't run tests when a file changes
`mix test.interactive` understands the following options, most of which
correspond to configuration settings below.

Note that, if you want to pass both mix test.interactive options and mix test
arguments, you must separate them with `--`.

If an option is provided on the command line, it will override the same option
specified in the configuration.

- `--(no-)clear`: Clear the console before each run (default `false`).
- `--command <command> [--arg <arg>]`: Custom command and arguments for
running tests (default: "mix" with no arguments). NOTE: Use `--arg` multiple
times to specify more than one argument.
- `--exclude <regex>`: Exclude files/directories from triggering test runs
(default: `["~r/\.#/", "~r{priv/repo/migrations}"`]) NOTE: Use `--exclude`
multiple times to specify more than one regex.
- `--extra-extensions <extension>`: Watch files with additional extensions
(default: []).
- `--runner <module name>`: Use a custom runner module (default:
`MixTestInteractive.PortRunner`).
- `--task <task name>`: Run a different mix task (default: `"test"`).
- `--(no-)timestamp`: Display the current time before running the tests
(default: `false`).
- `--(no-)watch`: Don't run tests when a file changes (default: `true`).

All other options are passed through to `mix test` on every test run.
All of the `<mix test arguments>` are passed through to `mix test` on every
test run.

`mix test.interactive` will detect the `--stale` and `--failed` flags and use
those as initial settings in interactive mode. You can then toggle those flags
Expand Down Expand Up @@ -61,8 +87,8 @@ defmodule Mix.Tasks.Test.Interactive do
operation of `mix test.interactive` with the following settings:

- `clear: true`: Clear the console before each run (default: `false`).
- `command: <program>` or `command: {<program>, [<arg>, ...]}`:
Use the provided command and arguments to run the test task (default: `mix`).
- `command: <program>` or `command: {<program>, [<arg>, ...]}`: Use the
provided command and arguments to run the test task (default: `mix`).
- `exclude: [patterns...]`: A list of `Regex`es to ignore when watching for
changes (default: `[~r/\.#/, ~r{priv/repo/migrations}]`).
- `extra_extensions: [<ext>...]`: Additional filename extensions to include
Expand All @@ -78,6 +104,7 @@ defmodule Mix.Tasks.Test.Interactive do
use Mix.Task

@preferred_cli_env :test
@requirements ["app.config"]

defdelegate run(args), to: MixTestInteractive
end
38 changes: 32 additions & 6 deletions lib/mix_test_interactive.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,45 @@ defmodule MixTestInteractive do
@moduledoc """
Interactively run your Elixir project's tests.
"""

alias MixTestInteractive.CommandLineParser
alias MixTestInteractive.InitialSupervisor
alias MixTestInteractive.InteractiveMode
alias MixTestInteractive.MainSupervisor

@application :mix_test_interactive

@doc """
Start the interactive test runner.
"""
@spec run([String.t()]) :: no_return()
def run(args \\ []) when is_list(args) do
Mix.env(:test)
{:ok, _} = Application.ensure_all_started(:mix_test_interactive)
case CommandLineParser.parse(args) do
{:ok, :help} ->
IO.puts(CommandLineParser.usage_message())

InteractiveMode.command_line_arguments(args)
loop()
{:ok, :version} ->
IO.puts("mix test.interactive v#{Application.spec(@application, :vsn)}")

{:ok, %{config: config, settings: settings}} ->
{:ok, _apps} = Application.ensure_all_started(@application)

{:ok, _supervisor} =
DynamicSupervisor.start_child(InitialSupervisor, {MainSupervisor, config: config, settings: settings})

loop()

{:error, error} ->
message = [
:bright,
:red,
Exception.message(error),
:reset,
"\n\nTry `mix test.interactive --help` for more information"
]

formatted = IO.ANSI.format(message)
IO.puts(:standard_error, formatted)
exit({:shutdown, 1})
end
end

defp loop do
Expand Down
15 changes: 0 additions & 15 deletions lib/mix_test_interactive/app_config.ex

This file was deleted.

9 changes: 1 addition & 8 deletions lib/mix_test_interactive/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@ defmodule MixTestInteractive.Application do

use Application

alias MixTestInteractive.Config
alias MixTestInteractive.InteractiveMode
alias MixTestInteractive.Watcher

@impl Application
def start(_type, _args) do
config = Config.new()

children = [
{InteractiveMode, config: config},
{Watcher, config: config}
{DynamicSupervisor, strategy: :one_for_one, name: MixTestInteractive.InitialSupervisor}
]

opts = [strategy: :one_for_one, name: MixTestInteractive.Supervisor]
Expand Down
Loading