Packages

A spec-compliant Open Responses server for Elixir and Phoenix, with pluggable provider adapters and first-class streaming.

Current section

Files

Jump to
open_responses lib mix tasks open_responses.compliance.ex
Raw

lib/mix/tasks/open_responses.compliance.ex

defmodule Mix.Tasks.OpenResponses.Compliance do
@moduledoc """
Run the Open Responses upstream compliance suite against a running server.
## Usage
Start your server in one terminal:
PHX_SERVER=true MIX_ENV=test mix phx.server
Then in another terminal:
mix open_responses.compliance
By default, targets `http://localhost:4000/v1`. Pass `--base-url` to
target a different host:
mix open_responses.compliance --base-url http://staging.example.com/v1
## Prerequisites
Requires [Bun](https://bun.sh) and a clone of the compliance test runner.
The task will clone the runner into `tmp/compliance` if it is not present.
Alternatively, point the official interactive tester at your running server:
https://www.openresponses.org/compliance
## Options
- `--base-url` — base URL of the server under test (default: http://localhost:4000/v1)
- `--api-key` — API key to pass in the Authorization header (default: empty)
- `--filter` — comma-separated list of test case IDs to run
"""
use Mix.Task
@repo_url "https://github.com/openresponses/openresponses.git"
@clone_dir "tmp/compliance"
@shortdoc "Run the Open Responses compliance suite against a server"
@impl Mix.Task
def run(args) do
{opts, _rest, _invalid} =
OptionParser.parse(args,
strict: [base_url: :string, api_key: :string, filter: :string]
)
base_url = Keyword.get(opts, :base_url, "http://localhost:4000/v1")
api_key = Keyword.get(opts, :api_key, "")
filter = Keyword.get(opts, :filter)
ensure_bun!()
ensure_clone!()
cmd_args = build_args(base_url, api_key, filter)
Mix.shell().info("Running compliance suite against #{base_url} ...")
case System.cmd("bun", cmd_args,
cd: @clone_dir,
into: IO.stream(:stdio, :line),
stderr_to_stdout: true
) do
{_, 0} ->
Mix.shell().info("Compliance suite passed.")
{_, code} ->
Mix.raise("Compliance suite exited with code #{code}.")
end
end
defp ensure_bun! do
case System.find_executable("bun") do
nil -> Mix.raise("Bun is required. Install it from https://bun.sh")
_ -> :ok
end
end
defp ensure_clone! do
unless File.dir?(@clone_dir) do
Mix.shell().info("Cloning compliance runner into #{@clone_dir} ...")
File.mkdir_p!("tmp")
case System.cmd("git", ["clone", "--depth", "1", @repo_url, @clone_dir],
stderr_to_stdout: true
) do
{_, 0} ->
System.cmd("bun", ["install"], cd: @clone_dir, stderr_to_stdout: true)
{output, code} ->
Mix.raise("git clone failed (exit #{code}):\n#{output}")
end
end
end
defp build_args(base_url, api_key, filter) do
base = ["run", "bin/compliance-tests.ts", "--base-url", base_url, "--api-key", api_key]
if filter, do: base ++ ["--filter", filter], else: base
end
end