Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 54 additions & 23 deletions apps/engine/lib/engine/search/indexer/extractors/ex_unit.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,76 @@ defmodule Engine.Search.Indexer.Extractors.ExUnit do
# setup block i.e. setup do... or setup arg do...
def extract({setup_fn, _, args} = setup, %Reducer{} = reducer)
when setup_fn in [:setup, :setup_all] and length(args) > 0 do
{:ok, module} = Analyzer.current_module(reducer.analysis, Reducer.position(reducer))
arity = arity_for(args)
subject = Formats.mfa(module, setup_fn, arity)
setup_type = :"ex_unit_#{setup_fn}"

case Metadata.location(setup) do
{:block, _, _, _} -> block_entry(reducer, setup, setup_type, subject)
{:expression, _} -> expression_entry(reducer, setup, setup_type, subject)
position = Reducer.position(reducer)

with true <- exunit_in_scope?(reducer, position),
{:ok, module} <- Analyzer.current_module(reducer.analysis, position) do
arity = arity_for(args)
subject = Formats.mfa(module, setup_fn, arity)
setup_type = :"ex_unit_#{setup_fn}"

case Metadata.location(setup) do
{:block, _, _, _} -> block_entry(reducer, setup, setup_type, subject)
{:expression, _} -> expression_entry(reducer, setup, setup_type, subject)
end
else
_ -> :ignored
end
end

# Test block test "test name" do ... or test "test name", arg do
def extract({:test, _, [{_, _, [test_name]} | _] = args} = test, %Reducer{} = reducer)
when is_binary(test_name) do
{:ok, module} = Analyzer.current_module(reducer.analysis, Reducer.position(reducer))
arity = arity_for(args)
module_name = Formats.module(module)
subject = "#{module_name}.[\"#{test_name}\"]/#{arity}"

case Metadata.location(test) do
{:block, _, _, _} -> block_entry(reducer, test, :ex_unit_test, subject)
{:expression, _} -> expression_entry(reducer, test, :ex_unit_test, subject)
position = Reducer.position(reducer)

with true <- exunit_in_scope?(reducer, position),
{:ok, module} <- Analyzer.current_module(reducer.analysis, position) do
arity = arity_for(args)
module_name = Formats.module(module)
subject = "#{module_name}.[\"#{test_name}\"]/#{arity}"

case Metadata.location(test) do
{:block, _, _, _} -> block_entry(reducer, test, :ex_unit_test, subject)
{:expression, _} -> expression_entry(reducer, test, :ex_unit_test, subject)
end
else
_ -> :ignored
end
end

# describe blocks
def extract({:describe, _, [{_, _, [describe_name]} | _] = args} = test, %Reducer{} = reducer) do
{:ok, module} = Analyzer.current_module(reducer.analysis, Reducer.position(reducer))
arity = arity_for(args)
module_name = Formats.module(module)
subject = "#{module_name}[\"#{describe_name}\"]/#{arity}"

block_entry(reducer, test, :ex_unit_describe, subject)
def extract({:describe, _, [{_, _, [describe_name]} | _] = args} = test, %Reducer{} = reducer)
when is_binary(describe_name) do
position = Reducer.position(reducer)

with true <- exunit_in_scope?(reducer, position),
{:ok, module} <- Analyzer.current_module(reducer.analysis, position) do
arity = arity_for(args)
module_name = Formats.module(module)
subject = "#{module_name}[\"#{describe_name}\"]/#{arity}"

block_entry(reducer, test, :ex_unit_describe, subject)
else
_ -> :ignored
end
end

def extract(_ign, _) do
:ignored
end

defp exunit_in_scope?(%Reducer{} = reducer, %Position{} = position) do
ExUnit.Case in Analyzer.uses_at(reducer.analysis, position) or
ExUnit.Case in Analyzer.requires_at(reducer.analysis, position) or
exunit_imported?(reducer, position)
end

defp exunit_imported?(%Reducer{} = reducer, %Position{} = position) do
Enum.any?(Analyzer.imports_at(reducer.analysis, position), fn {mod, _, _} ->
mod == ExUnit.Case
end)
end

defp expression_entry(%Reducer{} = reducer, ast, type, subject) do
path = reducer.analysis.document.path
block = Reducer.current_block(reducer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup do
:ok
end
Expand All @@ -46,6 +47,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup arg do
:ok
end
Expand All @@ -63,6 +65,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup :other_function
end
]
Expand All @@ -78,6 +81,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q{
defmodule SomeTest do
use ExUnit.Case
setup [:other_function, :second_function]
end
}
Expand All @@ -93,6 +97,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup {OtherModule, :setup}
end
]
Expand All @@ -108,6 +113,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [test], _doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
test "something" do
setup = 3
setup
Expand All @@ -125,6 +131,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup_all do
:ok
end
Expand All @@ -142,6 +149,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup_all arg do
:ok
end
Expand All @@ -159,6 +167,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup_all :other_function
end
]
Expand All @@ -175,6 +184,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q{
defmodule SomeTest do
use ExUnit.Case
setup_all [:other_function, :second_function]
end
}
Expand All @@ -191,6 +201,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [setup], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
setup_all {OtherModule, :setup}
end
]
Expand All @@ -209,6 +220,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [describe], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
describe "something" do
end
end
Expand All @@ -225,6 +237,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [describe, _test], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
describe "something" do
test "something"
end
Expand All @@ -247,6 +260,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [test], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
test "my test"
end
]
Expand All @@ -263,6 +277,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [test], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
test "my test" do
end
end
Expand All @@ -280,6 +295,7 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
{:ok, [test], doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
test "my test", context do
end
end
Expand All @@ -299,9 +315,10 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do

describe "block structure" do
test "describe contains tests" do
{:ok, [module, describe, test], _} =
{:ok, all_entries, _} =
~q[
defmodule SomeTexst do
use ExUnit.Case
describe "outer" do
test "my test", context do
end
Expand All @@ -310,6 +327,8 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
]
|> index_with_structure()

[module, describe, test] = Enum.filter(all_entries, &(&1.subtype == :definition))

assert module.type == :module
assert module.block_id == :root

Expand Down Expand Up @@ -340,11 +359,61 @@ defmodule Engine.Search.Indexer.Extractors.ExUnitTest do
assert {:ok, [], _doc} =
~q[
defmodule SomeTest do
use ExUnit.Case
test "my test" do
assert true
end
]
|> index_definitions()
end
end

describe "when ExUnit.Case is in scope" do
test "indexes test/describe/setup" do
{:ok, entries, _doc} =
~q[
defmodule SomeTest do
use ExUnit.Case

setup do
:ok
end

describe "some group" do
test "my test" do
:ok
end
end
end
]
|> index_definitions()

types = Enum.map(entries, & &1.type)
assert :ex_unit_setup in types
assert :ex_unit_describe in types
assert :ex_unit_test in types
end
end

describe "when ExUnit.Case is not in scope" do
test "does not index" do
{:ok, entries, _doc} =
~q[
defmodule NotATest do
def setup(arg), do: arg

def describe(name) do
name
end

def test(name, _context) do
name
end
end
]
|> index_definitions()

assert entries == []
end
end
end
Loading