Files
n8n-openai-adapter/lib/elixir/test/elixir/kernel/cli_test.exs
T

260 lines
8.2 KiB
Elixir

Code.require_file("../test_helper.exs", __DIR__)
import PathHelpers
defmodule Retry do
# Tests that write to stderr fail on Windows due to late writes,
# so we do a simple retry already them.
defmacro stderr_test(msg, context \\ quote(do: _), do: block) do
if windows?() do
quote do
test unquote(msg), unquote(context) do
unquote(__MODULE__).retry(fn -> unquote(block) end, 3)
end
end
else
quote do
test(unquote(msg), unquote(context), do: unquote(block))
end
end
end
def retry(fun, 1) do
fun.()
end
def retry(fun, n) do
try do
fun.()
rescue
_ -> retry(fun, n - 1)
end
end
end
defmodule Kernel.CLITest do
use ExUnit.Case, async: true
import ExUnit.CaptureIO
import Retry
defp run(argv) do
{config, argv} = Kernel.CLI.parse_argv(argv)
assert Kernel.CLI.process_commands(config) == []
argv
end
test "argv handling" do
assert capture_io(fn ->
assert run(["-e", "IO.puts :ok", "sample.exs", "-o", "1", "2"]) ==
["sample.exs", "-o", "1", "2"]
end) == "ok\n"
assert capture_io(fn ->
assert run(["-e", "IO.puts :ok", "--", "sample.exs", "-o", "1", "2"]) ==
["sample.exs", "-o", "1", "2"]
end) == "ok\n"
assert capture_io(fn ->
assert run(["-e", "", "--", "sample.exs", "-o", "1", "2"]) ==
["sample.exs", "-o", "1", "2"]
end)
end
stderr_test "--help smoke test" do
output = elixir('--help')
assert output =~ "Usage: elixir"
end
test "--version smoke test" do
output = elixir('--version')
assert output =~ "Erlang/OTP #{System.otp_release()}"
assert output =~ "Elixir #{System.version()}"
output = iex('--version')
assert output =~ "Erlang/OTP #{System.otp_release()}"
assert output =~ "IEx #{System.version()}"
output = elixir('--version -e "IO.puts(:test_output)"')
assert output =~ "Erlang/OTP #{System.otp_release()}"
assert output =~ "Elixir #{System.version()}"
assert output =~ "Standalone options can't be combined with other options"
end
test "--short-version smoke test" do
output = elixir('--short-version')
assert output =~ System.version()
refute output =~ "Erlang"
end
stderr_test "combining --help results in error" do
output = elixir('-e 1 --help')
assert output =~ "--help : Standalone options can't be combined with other options"
output = elixir('--help -e 1')
assert output =~ "--help : Standalone options can't be combined with other options"
end
stderr_test "combining --short-version results in error" do
output = elixir('--short-version -e 1')
assert output =~ "--short-version : Standalone options can't be combined with other options"
output = elixir('-e 1 --short-version')
assert output =~ "--short-version : Standalone options can't be combined with other options"
end
test "properly parses paths" do
root = fixture_path("../../..") |> to_charlist
args =
'-pa "#{root}/*" -pz "#{root}/lib/*" -e "IO.inspect(:code.get_path(), limit: :infinity)"'
list = elixir(args)
{path, _} = Code.eval_string(list, [])
# pa
assert to_charlist(Path.expand('ebin', root)) in path
assert to_charlist(Path.expand('lib', root)) in path
assert to_charlist(Path.expand('src', root)) in path
# pz
assert to_charlist(Path.expand('lib/list', root)) in path
end
stderr_test "properly formats errors" do
assert String.starts_with?(elixir('-e ":erlang.throw 1"'), "** (throw) 1")
assert String.starts_with?(elixir('-e ":erlang.error 1"'), "** (ErlangError) Erlang error: 1")
assert String.starts_with?(elixir('-e "1 +"'), "** (TokenMissingError)")
assert elixir('-e "Task.async(fn -> raise ArgumentError end) |> Task.await"') =~
"an exception was raised:\n ** (ArgumentError) argument error"
assert elixir('-e "IO.puts(Process.flag(:trap_exit, false)); exit({:shutdown, 1})"') ==
"false\n"
end
stderr_test "blames exceptions" do
error = elixir('-e "Access.fetch :foo, :bar"')
assert error =~ "** (FunctionClauseError) no function clause matching in Access.fetch/2"
assert error =~ "The following arguments were given to Access.fetch/2"
assert error =~ ":foo"
assert error =~ "def fetch(-%module{} = container-, +key+)"
assert error =~ ~r"\(elixir #{System.version()}\) lib/access\.ex:\d+: Access\.fetch/2"
end
end
defmodule Kernel.CLI.RPCTest do
use ExUnit.Case, async: true
import Retry
defp rpc_eval(command) do
node = "cli-rpc#{System.unique_integer()}@127.0.0.1"
elixir('--name #{node} --rpc-eval #{node} "#{command}"')
end
test "invokes command on remote node" do
assert rpc_eval("IO.puts :ok") == "ok\n"
end
test "invokes command on remote node without host" do
node = "cli-rpc#{System.unique_integer()}"
assert elixir('--name #{node}@127.0.0.1 --rpc-eval #{node} "IO.puts :ok"') == "ok\n"
end
stderr_test "properly formats errors" do
assert String.starts_with?(rpc_eval(":erlang.throw 1"), "** (throw) 1")
assert String.starts_with?(rpc_eval(":erlang.error 1"), "** (ErlangError) Erlang error: 1")
assert String.starts_with?(rpc_eval("1 +"), "** (TokenMissingError)")
assert rpc_eval("Task.async(fn -> raise ArgumentError end) |> Task.await") =~
"an exception was raised:\n ** (ArgumentError) argument error"
assert rpc_eval("IO.puts(Process.flag(:trap_exit, false)); exit({:shutdown, 1})") ==
"false\n"
end
end
defmodule Kernel.CLI.AtExitTest do
use ExUnit.Case, async: true
test "invokes at_exit callbacks" do
assert elixir(fixture_path("at_exit.exs") |> to_charlist) ==
"goodbye cruel world with status 1\n"
end
end
defmodule Kernel.CLI.CompileTest do
use ExUnit.Case, async: true
import Retry
@moduletag :tmp_dir
setup context do
beam_file_path = Path.join([context.tmp_dir, "Elixir.CompileSample.beam"])
fixture = fixture_path("compile_sample.ex")
{:ok, [beam_file_path: beam_file_path, fixture: fixture]}
end
test "compiles code", context do
assert elixirc('#{context.fixture} -o #{context.tmp_dir}') == ""
assert File.regular?(context.beam_file_path)
# Assert that the module is loaded into memory with the proper destination for the BEAM file.
Code.append_path(context.tmp_dir)
assert :code.which(CompileSample) |> List.to_string() == Path.expand(context.beam_file_path)
after
:code.purge(CompileSample)
:code.delete(CompileSample)
Code.delete_path(context.tmp_dir)
end
@tag :windows
stderr_test "compiles code with Windows paths", context do
try do
fixture = String.replace(context.fixture, "/", "\\")
tmp_dir_path = String.replace(context.tmp_dir, "/", "\\")
assert elixirc('#{fixture} -o #{tmp_dir_path}') == ""
assert File.regular?(context[:beam_file_path])
# Assert that the module is loaded into memory with the proper destination for the BEAM file.
Code.append_path(context.tmp_dir)
assert :code.which(CompileSample) |> List.to_string() ==
Path.expand(context[:beam_file_path])
after
:code.purge(CompileSample)
:code.delete(CompileSample)
Code.delete_path(context.tmp_dir)
end
end
stderr_test "fails on missing patterns", context do
output = elixirc('#{context.fixture} non_existing.ex -o #{context.tmp_dir}')
assert output =~ "non_existing.ex"
refute output =~ "compile_sample.ex"
refute File.exists?(context.beam_file_path)
end
stderr_test "fails on missing write access to .beam file", context do
compilation_args = '#{context.fixture} -o #{context.tmp_dir}'
assert elixirc(compilation_args) == ""
assert File.regular?(context.beam_file_path)
# Set the .beam file to read-only
File.chmod!(context.beam_file_path, 4)
{:ok, %{access: access}} = File.stat(context.beam_file_path)
# Can only assert when read-only applies to the user
if access != :read_write do
output = elixirc(compilation_args)
expected =
"(File.Error) could not write to file #{inspect(context.beam_file_path)}: permission denied"
assert output =~ expected
end
end
end