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

212 lines
6.7 KiB
Elixir

Code.require_file("../test_helper.exs", __DIR__)
import PathHelpers
defmodule Kernel.ParallelCompilerTest do
use ExUnit.Case
import ExUnit.CaptureIO
describe "compile" do
test "solves dependencies between modules" do
fixtures = [
fixture_path("parallel_compiler/bar.ex"),
fixture_path("parallel_compiler/foo.ex")
]
assert capture_io(fn ->
assert {:ok, [BarParallel, FooParallel], []} =
Kernel.ParallelCompiler.compile(fixtures)
end) =~ "message_from_foo"
after
Enum.map([FooParallel, BarParallel], fn mod ->
:code.purge(mod)
:code.delete(mod)
end)
end
test "solves dependencies between structs" do
fixtures = [
fixture_path("parallel_struct/bar.ex"),
fixture_path("parallel_struct/foo.ex")
]
assert {:ok, modules, []} = Kernel.ParallelCompiler.compile(fixtures)
assert [BarStruct, FooStruct] = Enum.sort(modules)
after
Enum.map([FooStruct, BarStruct], fn mod ->
:code.purge(mod)
:code.delete(mod)
end)
end
test "returns struct undefined error when local struct is undefined" do
fixture = fixture_path("parallel_struct/undef.ex")
expected_msg = "Undef.__struct__/1 is undefined, cannot expand struct Undef"
assert capture_io(fn ->
assert {:error, [{^fixture, 3, msg}], []} =
Kernel.ParallelCompiler.compile([fixture])
assert msg =~ expected_msg
end) =~ expected_msg
end
test "does not hang on missing dependencies" do
fixture = fixture_path("parallel_compiler/bat.ex")
expected_msg =
"ThisModuleWillNeverBeAvailable.__struct__/1 is undefined, cannot expand struct ThisModuleWillNeverBeAvailable"
assert capture_io(fn ->
assert {:error, [{^fixture, 7, msg}], []} =
Kernel.ParallelCompiler.compile([fixture])
assert msg =~ expected_msg
end) =~ "== Compilation error"
end
test "handles possible deadlocks" do
foo = fixture_path("parallel_deadlock/foo.ex")
bar = fixture_path("parallel_deadlock/bar.ex")
fixtures = [foo, bar]
msg =
capture_io(fn ->
assert {:error, [bar_error, foo_error], []} = Kernel.ParallelCompiler.compile(fixtures)
assert bar_error == {bar, nil, "deadlocked waiting on module FooDeadlock"}
assert foo_error == {foo, nil, "deadlocked waiting on module BarDeadlock"}
end)
assert msg =~ "Compilation failed because of a deadlock between files."
assert msg =~ "fixtures/parallel_deadlock/foo.ex => BarDeadlock"
assert msg =~ "fixtures/parallel_deadlock/bar.ex => FooDeadlock"
assert msg =~ ~r"== Compilation error in file .+parallel_deadlock/foo\.ex =="
assert msg =~ "** (CompileError) deadlocked waiting on module BarDeadlock"
assert msg =~ ~r"== Compilation error in file .+parallel_deadlock/bar\.ex =="
assert msg =~ "** (CompileError) deadlocked waiting on module FooDeadlock"
end
test "supports warnings as errors" do
warnings_as_errors = Code.compiler_options()[:warnings_as_errors]
fixture = fixture_path("warnings_sample.ex")
try do
Code.compiler_options(warnings_as_errors: true)
msg =
capture_io(:stderr, fn ->
assert {:error, [error], []} = Kernel.ParallelCompiler.compile([fixture])
msg = "this clause cannot match because a previous clause at line 2 always matches"
assert error == {fixture, 3, msg}
end)
assert msg =~
"Compilation failed due to warnings while using the --warnings-as-errors option\n"
after
Code.compiler_options(warnings_as_errors: warnings_as_errors)
:code.purge(WarningsSample)
:code.delete(WarningsSample)
end
end
test "does not use incorrect line number when error originates in another file" do
File.mkdir_p!(tmp_path())
file_a = tmp_path("error_line_a.ex")
File.write!(file_a, """
defmodule A do
def fun(arg), do: arg / 2
end
""")
file_b = tmp_path("error_line_b.ex")
File.write!(file_b, """
defmodule B do
def fun(arg) do
A.fun(arg)
:ok
end
end
B.fun(:not_a_number)
""")
capture_io(fn ->
assert {:error, [{^file_b, nil, _}], _} =
Kernel.ParallelCompiler.compile([file_a, file_b])
end)
end
test "gets correct line number for UndefinedFunctionError" do
File.mkdir_p!(tmp_path())
file = tmp_path("undef_error.ex")
File.write!(file, """
defmodule UndefErrorLine do
Bogus.fun()
end
""")
capture_io(fn ->
assert {:error, [{^file, 2, _}], _} = Kernel.ParallelCompiler.compile([file])
end)
end
end
describe "require" do
test "returns struct undefined error when local struct is undefined" do
fixture = fixture_path("parallel_struct/undef.ex")
expected_msg = "Undef.__struct__/1 is undefined, cannot expand struct Undef"
assert capture_io(fn ->
assert {:error, [{^fixture, 3, msg}], []} =
Kernel.ParallelCompiler.require([fixture])
assert msg =~ expected_msg
end) =~ expected_msg
end
test "does not hang on missing dependencies" do
fixture = fixture_path("parallel_compiler/bat.ex")
expected_msg =
"ThisModuleWillNeverBeAvailable.__struct__/1 is undefined, cannot expand struct ThisModuleWillNeverBeAvailable"
assert capture_io(fn ->
assert {:error, [{^fixture, 7, msg}], []} =
Kernel.ParallelCompiler.require([fixture])
assert msg =~ expected_msg
end) =~ "== Compilation error"
end
test "supports warnings as errors" do
warnings_as_errors = Code.compiler_options()[:warnings_as_errors]
fixture = fixture_path("warnings_sample.ex")
try do
Code.compiler_options(warnings_as_errors: true)
msg =
capture_io(:stderr, fn ->
assert {:error, [error], []} = Kernel.ParallelCompiler.require([fixture])
message =
"this clause cannot match because a previous clause at line 2 always matches"
assert error == {fixture, 3, message}
end)
assert msg =~
"Compilation failed due to warnings while using the --warnings-as-errors option\n"
after
Code.compiler_options(warnings_as_errors: warnings_as_errors)
:code.purge(WarningsSample)
:code.delete(WarningsSample)
end
end
end
end