Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ckoch-cars committed Sep 7, 2021
1 parent be2a382 commit 269c05a
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 44 deletions.
41 changes: 2 additions & 39 deletions lib/ex_factor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,9 @@ defmodule ExFactor do
Documentation for `ExFactor`.
"""

@doc """
Identify public functions from a module AST.
"""
def public_functions({:ok, ast}) do
# Macro.prewalk(ast, [], fn node, acc ->
# # walk_ast(node, acc, :def)
# {node, walk_ast(node, acc, :def)}
# # |> IO.inspect(label: "walk_ast")
# end)

Macro.postwalk(ast, [], fn node, acc ->
# walk_ast(node, acc, :def)
{node, walk_ast(node, acc, :def)}
# |> IO.inspect(label: "walk_ast")
end)
end

def private_functions({:ok, ast}) do
# Macro.prewalk(ast, [], fn node, acc ->
# # walk_ast(node, acc, :def)
# {node, walk_ast(node, acc, :def)}
# # |> IO.inspect(label: "walk_ast")
# end)
alias ExFactor.Parser, as: P

Macro.postwalk(ast, [], fn node, acc ->
# walk_ast(node, acc, :def)
{node, walk_ast(node, acc, :defp)}
# |> IO.inspect(label: "walk_ast")
end)
end

defp walk_ast({tkn, _, [{name, _meta, _args} | _]} = func, acc, token) when tkn == token do
# func |> IO.inspect(label: "walk func TOKEN: #{token}")
map = %{name: name, ast: func}
[map | acc]
end
def all_fns(input), do: P.all_functions(input)

defp walk_ast(_func, acc, _token) do
# func |> IO.inspect(label: "walk fallback token: #{token}")
acc
# |> IO.inspect(label: "fallback accum")
end
end
50 changes: 50 additions & 0 deletions lib/ex_factor/parser.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule ExFactor.Parser do
@moduledoc """
Documentation for `ExFactor`.
"""

@doc """
Identify public and private functions from a module AST.
"""
def all_functions({:ok, _ast} = input) do
{_ast, public_functions} = public_functions(input)
{ast, private_functions} = private_functions(input)
{ast, public_functions ++ private_functions}
end

@doc """
Identify public functions from a module AST.
"""
def public_functions({:ok, ast}) do
Macro.postwalk(ast, [], fn node, acc ->
{node, walk_ast(node, acc, :def)}
end)
end

@doc """
Identify private functions from a module AST.
"""
def private_functions({:ok, ast}) do
# Macro.prewalk(ast, [], fn node, acc ->
# # walk_ast(node, acc, :def)
# {node, walk_ast(node, acc, :def)}
# # |> IO.inspect(label: "walk_ast")
# end)

Macro.postwalk(ast, [], fn node, acc ->
# walk_ast(node, acc, :def)
{node, walk_ast(node, acc, :defp)}
# |> IO.inspect(label: "walk_ast")
end)
end

defp walk_ast({tkn, _, [{name, _meta, args} | _]} = func, acc, token) when tkn == token do
arity = length(args)
map = %{name: name, ast: func, arity: arity, defn: token}
[map | acc]
end

defp walk_ast(_func, acc, _token) do
acc
end
end
6 changes: 5 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule ExFactor.MixProject do
app: :ex_factor,
version: "0.1.0",
elixir: "~> 1.11",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps()
]
Expand All @@ -18,10 +19,13 @@ defmodule ExFactor.MixProject do
]
end

# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]

# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:credo, ">= 1.5.0", only: [:dev, :test]}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
Expand Down
4 changes: 0 additions & 4 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
}
118 changes: 118 additions & 0 deletions test/ex_factor/parser_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
defmodule ExFactor.ParserTest do
use ExUnit.Case
alias ExFactor.Parser

test "it should report public fns and their arity" do
{_ast, [f1]} = """
defmodule CredoSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
end
"""
|> Code.string_to_quoted()
|> Parser.public_functions()

assert f1.name == :pub1
assert f1.arity == 1
end

test "it should report TWO public fns" do
{_ast, [f1, f2]} = """
defmodule CredoSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
def pub2(arg2) do
:yes
end
defp pub3(arg3) do
:private
end
end
"""
|> Code.string_to_quoted()
|> Parser.public_functions()
assert f2.name == :pub1
assert f1.name == :pub2
end

test "it should report private fns and arity" do
{_ast, [f1]} = """
defmodule CredoSampleModule do
@somedoc "This is somedoc"
defp priv1(arg1, arg2) do
:ok
end
end
"""
|> Code.string_to_quoted()
|> Parser.private_functions()

assert f1.name == :priv1
assert f1.arity == 2
assert f1.defn == :defp
end

test "it should report TWO private fns" do
{_ast, [f1, f2]} = """
defmodule CredoSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
def pub2(arg2) do
:yes
end
defp priv3(arg3) do
:private
end
defp priv4(arg4) do
:private
end
end
"""
|> Code.string_to_quoted()
|> Parser.private_functions()
assert f2.name == :priv3
assert f1.name == :priv4
end

test "it should report all fns" do
{_ast, [f1, f2, f3]} = """
defmodule CredoSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
def pub2(arg2) do
:yes
end
defp priv3(arg3_1, arg3_2, arg3_3) do
:private
end
end
"""
|> Code.string_to_quoted()
|> Parser.all_functions()
assert f2.name == :pub1
assert f1.name == :pub2
assert f3.name == :priv3
assert f3.defn == :defp
assert f3.arity == 3
end

end

0 comments on commit 269c05a

Please sign in to comment.