Current section

Files

Jump to
claude_agent_sdk lib mix tasks test.live.ex
Raw

lib/mix/tasks/test.live.ex

defmodule Mix.Tasks.Test.Live do
use Mix.Task
@shortdoc "Runs tests with live Claude API calls"
@moduledoc """
Runs tests against the live Claude API instead of using mocks.
This task temporarily disables mocking and runs the test suite with actual API calls.
Use with caution as it will make real API calls and incur costs.
## Usage
mix test.live
mix test.live test/specific_test.exs
## Options
All options are passed through to the underlying `mix test` task.
"""
@impl Mix.Task
def run(args) do
# Mark that we're running in live mode
System.put_env("LIVE_TESTS", "true")
# Start the application in test mode but with live API
Application.put_env(:claude_agent_sdk, :use_mock, false)
IO.puts("🔴 Running tests with LIVE API calls...")
IO.puts("⚠️ Warning: This will make real API calls and may incur costs!")
IO.puts(" Default: runs only @tag :live tests (override by passing file paths / flags)")
IO.puts("")
# Run test task using Mix.Task module
# This is the proper way to delegate to another task
args = normalize_args(args)
Mix.Task.run("test", args)
end
defp normalize_args(args) when is_list(args) do
args
|> maybe_put_color()
|> maybe_put_exclude_mock()
|> maybe_put_include_integration()
|> maybe_put_live_filters()
end
defp maybe_put_color([]), do: ["--color"]
defp maybe_put_color(args), do: args
defp maybe_put_exclude_mock(args) do
if exclude_mock?(args) do
args
else
args ++ ["--exclude", "mock"]
end
end
defp exclude_mock?(args) do
Enum.chunk_every(args, 2, 1, :discard)
|> Enum.any?(fn
["--exclude", "mock"] -> true
_ -> false
end)
end
defp maybe_put_include_integration(args) do
if include_tag?(args, "integration") do
args
else
args ++ ["--include", "integration"]
end
end
defp maybe_put_live_filters(args) do
cond do
only_specified?(args) ->
maybe_put_include_live(args)
contains_test_paths?(args) ->
maybe_put_include_live(args)
true ->
args ++ ["--only", "live"]
end
end
defp maybe_put_include_live(args) do
if include_tag?(args, "live") do
args
else
args ++ ["--include", "live"]
end
end
defp include_tag?(args, tag) do
Enum.chunk_every(args, 2, 1, :discard)
|> Enum.any?(fn
["--include", ^tag] -> true
_ -> false
end)
end
defp only_specified?(args), do: "--only" in args
defp contains_test_paths?(args) do
Enum.any?(args, fn arg ->
is_binary(arg) and
not String.starts_with?(arg, "-") and
(String.contains?(arg, "_test.exs") or String.starts_with?(arg, "test/"))
end)
end
end