defmodule Mix.Lvn.TestHelper do @moduledoc false # stolen from phx_new import ExUnit.Assertions import ExUnit.CaptureIO def tmp_path do Path.expand("../../tmp", __DIR__) end defp random_string(len) do len |> :crypto.strong_rand_bytes() |> Base.encode64() |> binary_part(0, len) end def in_tmp(which, function) do path = Path.join([tmp_path(), random_string(10) <> to_string(which)]) try do File.rm_rf!(path) File.mkdir_p!(path) File.cd!(path, function) after File.rm_rf!(path) end end def in_tmp_project(which, function) do conf_before = Application.get_env(:phoenix, :generators) || [] path = Path.join([tmp_path(), random_string(10) <> to_string(which)]) try do File.rm_rf!(path) File.mkdir_p!(path) File.cd!(path, fn -> File.touch!("mix.exs") File.write!(".formatter.exs", """ [ import_deps: [:phoenix], inputs: ["*.exs"] ] """) function.() end) after File.rm_rf!(path) Application.put_env(:phoenix, :generators, conf_before) end end def in_tmp_live_project(test, func) do app = Mix.Phoenix.context_app() in_tmp_project(test, fn -> File.mkdir_p!("lib") File.touch!("lib/#{app}_web.ex") File.touch!("lib/#{app}.ex") func.() end) end def in_tmp_umbrella_project(which, function) do conf_before = Application.get_env(:phoenix, :generators) || [] path = Path.join([tmp_path(), random_string(10) <> to_string(which)]) try do apps_path = Path.join(path, "apps") config_path = Path.join(path, "config") File.rm_rf!(path) File.mkdir_p!(path) File.mkdir_p!(apps_path) File.mkdir_p!(config_path) File.touch!(Path.join(path, "mix.exs")) for file <- ~w(config.exs dev.exs test.exs prod.exs) do File.write!(Path.join(config_path, file), "import Config\n") end File.cd!(apps_path, function) after Application.put_env(:phoenix, :generators, conf_before) File.rm_rf!(path) end end def in_tmp_live_umbrella_project(test, func) do app = Mix.Phoenix.context_app() in_tmp_umbrella_project(test, fn -> File.mkdir_p!("#{app}/lib") File.mkdir_p!("#{app}_web/lib") File.touch!("#{app}/lib/#{app}.ex") File.touch!("#{app}_web/lib/#{app}_web.ex") func.() end) end def in_project(app, path, fun) do %{name: name, file: file} = Mix.Project.pop() try do capture_io(:stderr, fn -> Mix.Project.in_project(app, path, [], fun) end) after Mix.Project.push(name, file) end end def assert_file(file) do assert File.regular?(file), "Expected #{file} to exist, but does not" end def refute_file(file) do refute File.regular?(file), "Expected #{file} to not exist, but it does" end def assert_file(file, match) do cond do is_list(match) -> assert_file(file, &Enum.each(match, fn m -> assert &1 =~ m end)) is_binary(match) or is_struct(match, Regex) -> assert_file(file, &assert(&1 =~ match)) is_function(match, 1) -> assert_file(file) match.(File.read!(file)) true -> raise inspect({file, match}) end end def modify_file(path, function) when is_binary(path) and is_function(function, 1) do path |> File.read!() |> function.() |> write_file!(path) end defp write_file!(content, path) do File.write!(path, content) end def with_generator_env(app_name \\ :phoenix, new_env, fun) do config_before = Application.fetch_env(app_name, :generators) Application.put_env(app_name, :generators, new_env) try do fun.() after case config_before do {:ok, config} -> Application.put_env(app_name, :generators, config) :error -> Application.delete_env(app_name, :generators) end end end def umbrella_mixfile_contents do """ defmodule Umbrella.MixProject do use Mix.Project def project do [ apps_path: "apps", deps: deps() ] end defp deps do [] end end """ end def flush do receive do _ -> flush() after 0 -> :ok end end end