1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
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{<h1 id="hello">hello</h1>\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
|