defmodule PandocTest do
use ExUnit.Case, async: true
alias Pandoc.Watcher
import ExUnit.CaptureIO
@version Pandoc.latest_version()
test "run on default" do
assert capture_io(fn ->
assert Pandoc.run(:default, ["--version"]) == 0
end) =~ @version
end
test "run on profile" do
assert capture_io(fn ->
assert Pandoc.run(:another, []) == 0
end) =~ @version
end
test "updates on install" do
Application.put_env(:pandoc, :version, "3.6")
Mix.Task.rerun("pandoc.install", ["--if-missing"])
assert capture_io(fn ->
assert Pandoc.run(:default, ["--version"]) == 0
end) =~ "3.6"
Application.delete_env(:pandoc, :version)
Mix.Task.rerun("pandoc.install", ["--if-missing"])
assert capture_io(fn ->
assert Pandoc.run(:default, ["--version"]) == 0
end) =~ @version
after
Application.delete_env(:pandoc, :version)
end
test "install and run multiple concurrently" do
bin_path = Pandoc.bin_path()
assert :ok = File.exists?(bin_path) && File.rm!(bin_path)
results =
[:extra1, :extra2, :extra3]
|> Enum.map(fn profile ->
Application.put_env(:pandoc, profile, args: ["--version"])
Task.async(fn ->
capture_io(fn ->
ret_code = Pandoc.install_and_run(profile, [])
# Let the first finished task set the binary file to read and execute only,
# so that the others will fail if they try to overwrite it.
File.chmod!(bin_path, 0o500)
ret_code == 0
end)
end)
end)
|> Task.await_many(:infinity)
File.chmod!(bin_path, 0o700)
assert Enum.all?(results)
end
test "installs with custom URL" do
assert :ok =
Mix.Task.rerun("pandoc.install", [
"https://github.com/jgm/pandoc/releases/download/$version/pandoc-$version-$target.tar.gz"
])
end
test "starts watching and writes to stdio" do
in_tmp("documents", fn ->
task = Task.async(fn -> Pandoc.watch(:default) end)
%{pid: pid, ref: ref} = task
:timer.sleep(200)
{_, watcher_pid, _, _} =
Pandoc.Supervisor
|> Supervisor.which_children()
|> Enum.find(fn
{Watcher, _, _, _} -> true
_ -> false
end)
assert capture_io(fn ->
# Redirect watcher output to current process so it can be captured
Process.group_leader(watcher_pid, Process.group_leader())
File.write!("hello.md", "# hello")
Task.yield(task, 200)
end) =~ ~s{hello
\n}
assert :ok = Supervisor.terminate_child(Pandoc.Supervisor, Watcher)
assert_receive {:DOWN, ^ref, :process, ^pid, :normal}, 1000
end)
after
File.rm_rf!(tmp_path())
end
defp in_tmp(which, function) do
path = tmp_path(which)
File.rm_rf!(path)
File.mkdir_p!(path)
File.cd!(path, function)
end
defp tmp_path, do: Path.expand("../tmp", __DIR__)
defp tmp_path(extension), do: Path.join(tmp_path(), extension)
end