Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c56c153
WIP
angelikatyborska Apr 5, 2021
77ced7a
Make it work somehow with eval_quoted :sob:
angelikatyborska Apr 5, 2021
866e061
Add more tests
angelikatyborska Apr 5, 2021
6ad5c70
Remove outdated comment
angelikatyborska Apr 5, 2021
8f1aff1
Merge branch 'main' into analyze-bird-count
angelikatyborska Apr 7, 2021
4bc05b9
Try to use "name: :_"
angelikatyborska Apr 7, 2021
749321e
Should support functions in assert_call test cases now
neenjaw Apr 7, 2021
7b26a9b
making constant functions work
neenjaw Apr 7, 2021
6baa2ad
Merge branch 'patch' into analyze-bird-count-patch
angelikatyborska Apr 14, 2021
2735c5e
Use full module path for comments
angelikatyborska Apr 15, 2021
3f9f807
Add failing test for underscore usage
angelikatyborska Apr 15, 2021
e7526f4
Add failing test for function usage without module usage
angelikatyborska Apr 15, 2021
e8284ad
Do not ignore given module in assert_call
angelikatyborska Apr 20, 2021
e2374b2
Merge branch 'assert-call-bugs' into analyze-bird-count-patch
angelikatyborska Apr 20, 2021
a5d4b1f
Adjust test after two parallel fixes
angelikatyborska Apr 20, 2021
3f817c4
Add detecting aliases and imports
angelikatyborska Apr 20, 2021
dde1363
Add to config
angelikatyborska Apr 23, 2021
a700398
Add failing test that asserts on comments exactly
angelikatyborska Apr 23, 2021
eb6c88b
Merge branch 'main' into analyze-bird-count
neenjaw May 16, 2021
eb3c7ae
move test_suite file after merging main
neenjaw May 16, 2021
f23508f
Remove Macro.escape from ExerciseTest
neenjaw May 16, 2021
19ea103
renamed and credo fix
neenjaw May 16, 2021
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
3 changes: 3 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ config :elixir_analyzer,
},
"take-a-number" => %{
analyzer_module: ElixirAnalyzer.TestSuite.TakeANumber
},
"bird-count" => %{
analyzer_module: ElixirAnalyzer.TestSuite.BirdCount
}
}

Expand Down
5 changes: 4 additions & 1 deletion lib/elixir_analyzer/constants.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ defmodule ElixirAnalyzer.Constants do
"elixir.pacman-rules.use_strictly_boolean_operators",

# Take A Number Comments
take_a_number_do_not_use_abstractions: "elixir.take-a-number.do_not_use_abstractions"
take_a_number_do_not_use_abstractions: "elixir.take-a-number.do_not_use_abstractions",

# Bird Count Comments
bird_count_use_recursion: "elixir.bird-count.use_recursion"
]

for {constant, markdown} <- @constants do
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_analyzer/exercise_test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule ElixirAnalyzer.ExerciseTest do

defmacro __before_compile__(env) do
# credo:disable-for-previous-line Credo.Check.Refactor.CyclomaticComplexity
feature_test_data = Macro.escape(Module.get_attribute(env.module, :feature_tests))
feature_test_data = Module.get_attribute(env.module, :feature_tests)
assert_call_data = Module.get_attribute(env.module, :assert_call_tests)

# ast placeholder for the submission code ast
Expand Down
17 changes: 11 additions & 6 deletions lib/elixir_analyzer/exercise_test/assert_call.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCall do
{node, Map.put(test_data, :called_fn, formatted_signature)}
end

defp do_walk_assert_call_block({:comment, _, [comment]} = node, test_data)
when is_binary(comment) do
defp do_walk_assert_call_block({:comment, _, [comment]} = node, test_data) do
{node, Map.put(test_data, :comment, comment)}
end

Expand Down Expand Up @@ -117,9 +116,11 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCall do
{:__aliases__, _, module} ->
module

_ ->
x ->
raise ArgumentError,
"calling function signature requires :module to be nil or a module atom"
"calling function signature requires :module to be nil or a module atom, got: #{
inspect(x)
}"
end

Keyword.put(signature, :module, module)
Expand All @@ -128,8 +129,12 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCall do
defp validate_name(signature) do
module =
case signature[:name] do
name when is_atom(name) -> name
_ -> raise ArgumentError, "calling function signature requires :name to be an atom"
name when is_atom(name) ->
name

x ->
raise ArgumentError,
"calling function signature requires :name to be an atom, got: #{inspect(x)}"
end

Keyword.put(signature, :name, module)
Expand Down
4 changes: 2 additions & 2 deletions lib/elixir_analyzer/exercise_test/assert_call/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCall.Compiler do
name = assert_call_data.description
called_fn = Macro.escape(assert_call_data.called_fn)
calling_fn = Macro.escape(assert_call_data.calling_fn)
comment = assert_call_data.comment
{comment, _} = Code.eval_quoted(assert_call_data.comment)
should_call = assert_call_data.should_call
type = assert_call_data.type

Expand Down Expand Up @@ -145,7 +145,7 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCall.Compiler do

def matching_function_call?(
{name, _, _args},
{_, name}
{nil, name}
) do
true
end
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir_analyzer/exercise_test/feature/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule ElixirAnalyzer.ExerciseTest.Feature.Compiler do

def compile({feature_data, feature_forms}, code_ast) do
name = Keyword.fetch!(feature_data, :name)
comment = Keyword.fetch!(feature_data, :comment)
{comment, _} = Code.eval_quoted(Keyword.fetch!(feature_data, :comment))
status = Keyword.get(feature_data, :status, :test)
type = Keyword.get(feature_data, :type, :informative)
find_type = Keyword.get(feature_data, :find, :all)
Expand Down
104 changes: 104 additions & 0 deletions lib/elixir_analyzer/test_suite/bird_count.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
defmodule ElixirAnalyzer.TestSuite.BirdCount do
@dialyzer generated: true
@moduledoc """
This is an exercise analyzer extension module for the concept exercise Bird Count
"""

use ElixirAnalyzer.ExerciseTest

assert_no_call "does not call any Enum functions" do
type :essential
called_fn module: Enum, name: :_
comment ElixirAnalyzer.Constants.bird_count_use_recursion()
end

feature "does not alias or import Enum" do
find :none
type :essential
comment ElixirAnalyzer.Constants.bird_count_use_recursion()

form do
import Enum
end

form do
import Enum, _ignore
end

form do
alias Enum, as: _ignore
end
end

assert_no_call "does not call any Stream functions" do
type :essential
called_fn module: Stream, name: :_
comment ElixirAnalyzer.Constants.bird_count_use_recursion()
end

feature "does not alias or import Stream" do
find :none
type :essential
comment ElixirAnalyzer.Constants.bird_count_use_recursion()

form do
import Stream
end

form do
import Stream, _ignore
end

form do
alias Stream, as: _ignore
end
end

assert_no_call "does not call any List functions" do
type :essential
called_fn module: List, name: :_
comment ElixirAnalyzer.Constants.bird_count_use_recursion()
end

feature "does not alias or import List" do
find :none
type :essential
comment ElixirAnalyzer.Constants.bird_count_use_recursion()

form do
import List
end

form do
import List, _ignore
end

form do
alias List, as: _ignore
end
end

feature "doesn't use list comprehensions" do
find :none
type :essential
comment ElixirAnalyzer.Constants.bird_count_use_recursion()

form do
for _ignore <- _ignore do
_ignore
end
end

form do
for _ignore <- _ignore, _ignore do
_ignore
end
end

form do
for _ignore <- _ignore, _ignore, into: _ignore do
_ignore
end
end
end
end
32 changes: 30 additions & 2 deletions test/elixir_analyzer/exercise_test/assert_call_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCallTest do

test_exercise_analysis "missing call to a List function in function/0 solution",
comments: [
"didn't find a call to a List function in function/0"
"didn't find a call to a List function in function/0",
"mock.constant"
] do
defmodule AssertCallVerification do
def function() do
Expand All @@ -144,7 +145,8 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCallTest do
test_exercise_analysis "missing call to a List function in solution",
comments: [
"didn't find a call to a List function",
"didn't find a call to a List function in function/0"
"didn't find a call to a List function in function/0",
"mock.constant"
] do
defmodule AssertCallVerification do
def function() do
Expand All @@ -163,4 +165,30 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertCallTest do
end
end
end

test_exercise_analysis "usages of the underscore don't fool the missing call check",
comments: [
"didn't find a call to a List function",
"didn't find a call to a List function in function/0",
"mock.constant"
] do
defmodule AssertCallVerification do
def function() do
result = helper()
IO.puts(result)

2 * 3

_ = private_helper() |> IO.puts()
end

def helper do
:helped
end

defp private_helper do
:privately_helped
end
end
end
end
34 changes: 34 additions & 0 deletions test/elixir_analyzer/exercise_test/assert_no_call_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,40 @@ defmodule ElixirAnalyzer.ExerciseTest.AssertNoCallTest do
end
end

test_exercise_analysis "calling a function with the same name or imported doesn't trigger the check",
comments: [] do
[
defmodule AssertNoCallVerification do
def function() do
map([], fn x -> x + 1 end)
end

def helper do
:helped
end

defp private_helper do
:privately_helped
end
end,
defmodule AssertNoCallVerification do
import Enum

def function() do
map([], fn x -> x + 1 end)
end

def helper do
:helped
end

defp private_helper do
:privately_helped
end
end
]
end

test_exercise_analysis "found a call to other module function in specific function",
comments: [
"found a call to Atom.to_string/1 in helper/0 function in solution"
Expand Down
Loading