Skip to content

Commit 90ea4e0

Browse files
committed
Add ExUnit.TmpDir.tmp_dir/0
Inspired by golang/go#35998.
1 parent 42af53f commit 90ea4e0

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

lib/ex_unit/lib/ex_unit/case.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ defmodule ExUnit.Case do
513513

514514
test = %ExUnit.Test{name: name, case: mod, tags: tags, module: mod}
515515
Module.put_attribute(mod, :ex_unit_tests, test)
516+
Module.put_attribute(mod, :ex_unit_test, test)
517+
Module.put_attribute(mod, :ex_unit_tmp_dirs, [])
516518

517519
for attribute <- Module.get_attribute(mod, :ex_unit_registered_test_attributes) do
518520
Module.delete_attribute(mod, attribute)

lib/ex_unit/lib/ex_unit/tmp_dir.ex

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
defmodule ExUnit.TmpDir do
2+
@doc """
3+
Returns a path to a temporary directory for the current test.
4+
5+
The directory is lazily created on the first access and is automatically
6+
removed once the test finishes (regardless if the test suceeds or fails).
7+
"""
8+
defmacro tmp_dir do
9+
test = Module.get_attribute(__CALLER__.module, :ex_unit_test)
10+
11+
unless test do
12+
raise "cannot invoke tmp_dir/0 outside of a test. Please make sure you have invoked " <>
13+
"\"use ExUnit.Case\" in the current module"
14+
end
15+
16+
path = Path.join([System.tmp_dir(), "#{inspect(test.module)}_#{test.name}"])
17+
tmp_dirs = Module.get_attribute(__CALLER__.module, :ex_unit_tmp_dirs)
18+
19+
if test.name in tmp_dirs do
20+
quote do
21+
unquote(path)
22+
end
23+
else
24+
Module.put_attribute(__CALLER__.module, :ex_unit_tmp_dirs, [test.name | tmp_dirs])
25+
26+
quote bind_quoted: [path: path] do
27+
File.mkdir_p!(path)
28+
on_exit(fn -> File.rm_rf!(path) end)
29+
path
30+
end
31+
end
32+
end
33+
end

lib/mix/test/mix/shell_test.exs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Code.require_file("../test_helper.exs", __DIR__)
22

33
defmodule Mix.ShellTest do
44
use MixTest.Case
5+
import ExUnit.TmpDir
56

67
defp capture_io(fun) do
78
fun |> ExUnit.CaptureIO.capture_io() |> String.replace("\r\n", "\n")
@@ -20,12 +21,10 @@ defmodule Mix.ShellTest do
2021

2122
test "with :cd" do
2223
Mix.shell(Mix.Shell.IO)
23-
tmp_dir = System.tmp_dir()
24-
File.mkdir_p!(tmp_dir)
25-
{pwd, 0} = System.cmd("pwd", [], cd: tmp_dir)
24+
{pwd, 0} = System.cmd("pwd", [], cd: tmp_dir())
2625

2726
assert ExUnit.CaptureIO.capture_io(fn ->
28-
Mix.shell().cmd("pwd", cd: tmp_dir)
27+
Mix.shell().cmd("pwd", cd: tmp_dir())
2928
end) == pwd
3029
after
3130
Mix.shell(Mix.Shell.Process)

0 commit comments

Comments
 (0)