From 04d16d93f86432e28faeb492445fc16f240553b7 Mon Sep 17 00:00:00 2001 From: Christian Koch Date: Wed, 20 Jul 2022 11:57:36 -0500 Subject: [PATCH] fix(ExFactor.Extractor): create path! for new modules Ensure we attempt create a new path as needed and raise exceptions on File failures. --- lib/ex_factor/extractor.ex | 6 +++- test/ex_factor/extractor_test.exs | 54 ++++++++++++++++++++++++------- test/ex_factor_test.exs | 10 ++++++ 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/lib/ex_factor/extractor.ex b/lib/ex_factor/extractor.ex index 0a44cfd..431a745 100644 --- a/lib/ex_factor/extractor.ex +++ b/lib/ex_factor/extractor.ex @@ -83,7 +83,11 @@ defmodule ExFactor.Extractor do end defp write_file(target_path, contents, module, _dry_run) do - _ = File.write(target_path, contents, [:write]) + target_path + |> Path.dirname() + |> File.mkdir_p!() + + File.write!(target_path, contents, [:write]) %{ module: module, diff --git a/test/ex_factor/extractor_test.exs b/test/ex_factor/extractor_test.exs index cef8557..c6b4b39 100644 --- a/test/ex_factor/extractor_test.exs +++ b/test/ex_factor/extractor_test.exs @@ -2,20 +2,16 @@ defmodule ExFactor.ExtractorTest do use ExUnit.Case alias ExFactor.Extractor - setup_all do + setup do File.mkdir_p("test/tmp") + File.mkdir_p("lib/ex_factor/tmp") on_exit(fn -> + File.rm_rf("lib/ex_factor/tmp") File.rm_rf("test/tmp") end) end - setup do - File.rm_rf("lib/ex_factor/tmp") - File.mkdir_p("lib/ex_factor/tmp") - :ok - end - describe "emplace/1" do test "requires some options" do opts = [ @@ -32,6 +28,45 @@ defmodule ExFactor.ExtractorTest do test "noop when no matching fns found in source" do end + test "create the dir path if necessary" do + content = """ + defmodule ExFactorSampleModule do + @somedoc "This is somedoc" + # a comment and no aliases + _docp = "here's an arbitrary module underscore" + @spec pub1(term()) :: term() + def pub1(arg1) do + :pub1_ok + end + end + """ + + File.write("test/tmp/source_module.ex", content) + + opts = [ + target_module: "ExFactor.Test.NewModule", + source_module: "ExFactorSampleModule", + source_path: "test/tmp/source_module.ex", + source_function: :pub1, + arity: 1 + ] + + Extractor.emplace(opts) + file = File.read!("lib/ex_factor/test/new_module.ex") + + assert file =~ "def pub1(arg1) do" + assert file =~ "defmodule ExFactor.Test.NewModule do" + # includes additional attrs + assert file =~ "@spec pub1(term()) :: term()" + assert file =~ "@somedoc \"This is somedoc\"" + # assert the added elements get flattened correctly + refute file =~ "[@somedoc \"This is somedoc\", " + # comments don't get moved + refute file =~ "# a comment and no aliases" + + File.rm_rf("lib/ex_factor/test") + end + test "write a new file with the function" do content = """ defmodule ExFactorSampleModule do @@ -48,7 +83,6 @@ defmodule ExFactor.ExtractorTest do File.write("test/tmp/source_module.ex", content) target_path = "test/tmp/target_module.ex" - File.rm(target_path) opts = [ target_path: target_path, @@ -71,8 +105,6 @@ defmodule ExFactor.ExtractorTest do refute file =~ "[@somedoc \"This is somedoc\", " # comments don't get moved refute file =~ "# a comment and no aliases" - File.rm("test/tmp/source_module.ex") - File.rm("test/tmp/target_module.ex") end test "write a new file add a moduledoc comment" do @@ -88,7 +120,6 @@ defmodule ExFactor.ExtractorTest do File.write("test/tmp/source_module.ex", content) target_path = "test/tmp/target_module.ex" - File.rm(target_path) opts = [ target_path: target_path, @@ -122,7 +153,6 @@ defmodule ExFactor.ExtractorTest do File.write("test/tmp/source_module.ex", content) target_path = "test/tmp/target_module.ex" - File.rm(target_path) opts = [ target_path: target_path, diff --git a/test/ex_factor_test.exs b/test/ex_factor_test.exs index e14bb55..2efe8ec 100644 --- a/test/ex_factor_test.exs +++ b/test/ex_factor_test.exs @@ -9,6 +9,16 @@ defmodule ExFactorTest do end) end + describe "path/1" do + test "convert a module name to a file path" do + assert "lib/test_module.ex" == ExFactor.path(TestModule) + end + + test "convert a multi-atom module name to a file path" do + assert "lib/my/test/module_name.ex" == ExFactor.path(My.Test.ModuleName) + end + end + describe "refactor/1" do test "it refactors the functions into a new module, specified in opts" do File.rm("lib/ex_factor/tmp/source_module.ex")