Skip to content

Commit 980dc4e

Browse files
Carl-FosterCarl Fosterscohen
authored
Enable smarter test searches (#800)
* Allow doctests to be run. Integrate more metadata in code lens * Fix up formatting * Fix up case of no doctests * Clean up the code style * Update apps/language_server/lib/language_server/providers/code_lens/test.ex Co-authored-by: Steve Cohen <scohen@scohen.org> --------- Co-authored-by: Carl Foster <cfoster@squiz.net> Co-authored-by: Steve Cohen <scohen@scohen.org>
1 parent 7ed5cdd commit 980dc4e

File tree

6 files changed

+319
-22
lines changed

6 files changed

+319
-22
lines changed

apps/language_server/lib/language_server/ex_unit_test_tracer.ex

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,14 @@ defmodule ElixirLS.LanguageServer.ExUnitTestTracer do
7676
test_info
7777
|> Enum.group_by(fn %ExUnit.Test{tags: tags} -> {tags.describe, tags.describe_line} end)
7878
|> Enum.map(fn {{describe, describe_line}, tests} ->
79+
grouped_tests = Enum.group_by(tests, fn %ExUnit.Test{tags: tags} -> tags.test_type end)
80+
7981
tests =
80-
tests
82+
grouped_tests
83+
|> Map.get(:test, [])
8184
|> Enum.map(fn %ExUnit.Test{tags: tags} = test ->
8285
# drop test prefix
83-
"test " <> test_name = Atom.to_string(test.name)
86+
test_name = drop_test_prefix(test.name)
8487

8588
test_name =
8689
if describe != nil do
@@ -96,6 +99,21 @@ defmodule ElixirLS.LanguageServer.ExUnitTestTracer do
9699
}
97100
end)
98101

102+
tests =
103+
case grouped_tests do
104+
%{doctest: [doctest | _]} ->
105+
test_meta = %{
106+
name: "doctest #{inspect(doctest.tags.doctest)}",
107+
line: doctest.tags.line - 1,
108+
type: :doctest
109+
}
110+
111+
[test_meta | tests]
112+
113+
_ ->
114+
tests
115+
end
116+
99117
%{
100118
describe: describe,
101119
line: if(describe_line, do: describe_line - 1),
@@ -112,4 +130,10 @@ defmodule ElixirLS.LanguageServer.ExUnitTestTracer do
112130
def trace(_, %Macro.Env{} = _env) do
113131
:ok
114132
end
133+
134+
defp drop_test_prefix(test_name) when is_atom(test_name),
135+
do: test_name |> Atom.to_string() |> drop_test_prefix
136+
137+
defp drop_test_prefix("test " <> rest), do: rest
138+
defp drop_test_prefix(test_name), do: test_name
115139
end

apps/language_server/lib/language_server/providers/code_lens/test.ex

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test do
5353
%{
5454
"filePath" => file_path,
5555
"testName" => block.name,
56-
"projectDir" => project_dir
56+
"projectDir" => project_dir,
57+
"module" => get_module_name(block.module)
5758
}
5859
|> Map.merge(if block.describe != nil, do: %{"describe" => block.describe.name}, else: %{})
5960
end
@@ -70,17 +71,18 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test do
7071
CodeLens.build_code_lens(block.line, "Run tests", @run_test_command, %{
7172
"filePath" => file_path,
7273
"describe" => block.name,
73-
"projectDir" => project_dir
74+
"projectDir" => project_dir,
75+
"module" => get_module_name(block.module)
7476
})
7577
end)
7678
end
7779

7880
defp find_test_blocks(lines_to_env_list, calls_list, describe_blocks, source_lines) do
79-
runnable_functions = [{:test, 3}, {:test, 2}]
81+
runnable_functions = [test: 3, test: 2, doctest: 2, doctest: 1]
8082

8183
for func <- runnable_functions,
8284
{line, _col} <- calls_to(calls_list, func) do
83-
{_line, %{scope_id: scope_id}} =
85+
{_line, %{scope_id: scope_id, module: module}} =
8486
Enum.find(lines_to_env_list, fn {env_line, _env} -> env_line == line end)
8587

8688
describe =
@@ -89,11 +91,23 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test do
8991
describe.body_scope_id == scope_id
9092
end)
9193

92-
%{"name" => test_name} =
93-
~r/^\s*test "(?<name>.*)"(,.*)?/
94-
|> Regex.named_captures(Enum.at(source_lines, line - 1))
95-
96-
%TestBlock{name: test_name, describe: describe, line: line}
94+
test_name =
95+
source_lines
96+
|> Enum.at(line - 1)
97+
|> String.trim()
98+
|> case do
99+
"test " <> rest ->
100+
rest
101+
|> String.split(~s("))
102+
|> Enum.at(1)
103+
104+
"doctest" <> _ = line ->
105+
line
106+
|> String.split(~s(,))
107+
|> Enum.at(0)
108+
end
109+
110+
%TestBlock{name: test_name, describe: describe, line: line, module: module}
97111
end
98112
end
99113

@@ -145,4 +159,10 @@ defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test do
145159
{:ok, buffer_file_metadata}
146160
end
147161
end
162+
163+
defp get_module_name(module) do
164+
module
165+
|> Module.split()
166+
|> Enum.join(".")
167+
end
148168
end

apps/language_server/lib/language_server/providers/code_lens/test/describe_block.ex

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test.DescribeBlock do
22
alias ElixirSense.Core.State.Env
33

4-
@struct_keys [:line, :name, :body_scope_id]
4+
@struct_keys [:line, :name, :body_scope_id, :module]
55

66
@enforce_keys @struct_keys
77
defstruct @struct_keys
88

99
def find_block_info(line, lines_to_env_list, lines_to_env_list_length, source_lines) do
1010
name = get_name(source_lines, line)
1111

12+
module =
13+
lines_to_env_list
14+
|> Enum.find(fn {env_line, _env} -> env_line == line end)
15+
|> elem(1)
16+
|> Map.get(:module)
17+
1218
body_scope_id =
1319
get_body_scope_id(
1420
line,
1521
lines_to_env_list,
1622
lines_to_env_list_length
1723
)
1824

19-
%__MODULE__{line: line, body_scope_id: body_scope_id, name: name}
25+
%__MODULE__{line: line, body_scope_id: body_scope_id, name: name, module: module}
2026
end
2127

2228
defp get_name(source_lines, declaration_line) do

apps/language_server/lib/language_server/providers/code_lens/test/test_block.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule ElixirLS.LanguageServer.Providers.CodeLens.Test.TestBlock do
2-
@struct_keys [:name, :describe, :line]
2+
@struct_keys [:name, :describe, :line, :module]
33

44
@enforce_keys @struct_keys
55
defstruct @struct_keys

0 commit comments

Comments
 (0)