Added erlang ast test in captains-log#455
Conversation
|
Thank you for the PR!
|
|
It should be fixed now. |
|
It has been open for 5 months. Can someone take a look? |
|
Hi there! We did completely forget about your PR, sorry about that 😞 I'm writing this comment to confirm that both @jiegillet and I saw your recent reminder and we'll looking for some free time to re-review the PR soon. |
jiegillet
left a comment
There was a problem hiding this comment.
Sorry about the wait. I think I was waiting for you to address my second point, and then lost track of the PR altogether.
- The tests in
test_dataare used as smoke tests for the CI, we don't typically add new ones in there unless we have a good reason. The tests you added intest/elixir_analyzer/test_suite/captains_log_test.exsshould be enough.
This still stands, could you revert the changes to test_data?
Other than that, I've looked at your changes and left some comments.
| captains_log_do_not_use_rand_uniform_real: "elixir.captains-log.do_not_use_rand_uniform_real", | ||
| captains_log_use_rand_uniform: "elixir.captains-log.use_rand_uniform", | ||
| captains_log_use_io_lib: "elixir.captains-log.use_io_lib", | ||
| captains_log_use_erlang: "elixir.captains-log.use_erlang", |
There was a problem hiding this comment.
This value is a path to a file in this repo that contains the text of the analyzer comment, so you need to create a new file over there for the analyzer to work. Could you do the appropriate change over there, link to the PR in this PR's description and request a review from me?
There was a problem hiding this comment.
I cannot ask anyone for a review on the repo.
| comment Constants.captains_log_use_io_lib() | ||
| comment Constants.captains_log_use_erlang() | ||
|
|
||
| check(%Source{code_ast: code_ast}) do |
There was a problem hiding this comment.
I'm hesitating about this change.
It doesn't check that "format_stardate uses erlang", it checks that one of two specific Erlang functions are used anywhere at all, even in dead code.
I can think of two preferable approaches:
- The easy one: add an extra
assert_call(the following code is missing values, it's just to show the structure)
assert_call "format_stardate uses :io_lib" do
calling_fn module: CaptainsLog, name: :format_stardate
called_fn module: :io_lib, name: :_
suppress_if "format_stardate uses :erlang", :pass
end
assert_call "format_stardate uses :erlang" do
calling_fn module: CaptainsLog, name: :format_stardate
called_fn module: :erlang, name: :_
suppress_if "format_stardate uses :io_lib", :pass
endthis should be equivalent to the intent of your PR.
- The hard one: add a feature to the macro
assert_call, something like
assert_call "format_stardate uses an Erlang module" do
calling_fn module: CaptainsLog, name: :format_stardate
called_fn module: AnyErlangModule, name: :_
endThis would detect the use of any non-elixir module, while preserving all of the advantages of assert_call (tracking imports, aliases, the use of helper functions...). It would also be future proof in case there is another Erlang module that could solve the problem. I think it should be possible since Elixir module names are always capitalized unlike erlang ones, but this is the hard approach because the assert_call macro is quite complex, so I'm not pushing for it, just writing down my thoughts.
Since approach 1. would already be a strict improvement, I think that's the one we should aim at to relieve your from your 5-month journey within a reasonable time :)
|
|
||
| test_exercise_analysis "format_stardate uses Float.round", | ||
| comments_include: [Constants.captains_log_use_io_lib()] do | ||
| comments_include: [Constants.captains_log_use_erlang()] do |
There was a problem hiding this comment.
Could you add at one test that use an :erlang function to solve the problem and doesn't raise a comment?
There was a problem hiding this comment.
Pull request overview
This PR updates the Captains Log analyzer rule for format_stardate/1 to allow Erlang-based implementations (per issue #340), switching from a call-based assertion to an AST-based source check.
Changes:
- Replaced the
format_stardateanalyzer check with acheck_sourcethat scans the submission AST for Erlang usage. - Renamed the Captains Log analyzer comment id from
use_io_libtouse_erlang. - Updated the Captains Log test to expect the new comment id.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
lib/elixir_analyzer/test_suite/captains_log.ex |
Replaces the format_stardate check with an AST traversal looking for :io_lib/:erlang calls. |
lib/elixir_analyzer/constants.ex |
Renames the analyzer comment id used for the Captains Log format_stardate guidance. |
test/elixir_analyzer/test_suite/captains_log_test.exs |
Updates the expectation to the renamed comment id. |
Comments suppressed due to low confidence (1)
test/elixir_analyzer/test_suite/captains_log_test.exs:110
- There’s no test covering the newly-allowed
format_stardateimplementations that use:erlang(e.g.,:erlang.float_to_binary/2) and should not emit this comment. Add atest_exercise_analysiscase that uses an Erlang-based implementation and assertsConstants.captains_log_use_erlang()is excluded, so the analyzer change is protected against regressions.
test_exercise_analysis "format_stardate uses Float.round",
comments_include: [Constants.captains_log_use_erlang()] do
defmodule CaptainsLog do
def format_stardate(stardate) do
if is_float(stardate) do
Float.round(stardate, 1) |> to_string()
else
raise ArgumentError
end
end
end
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I should have sorted everything out. My only concern with the first approach is that if a user makes a mistake, both the comments from :io_lib and :erlang will be displayed, I suppose. |
jiegillet
left a comment
There was a problem hiding this comment.
Thanks for the quick follow up, I didn't take 5 months to reply this time :)
We are on the right track, but your concern is warranted, so let's address it.
| @@ -48,5 +48,14 @@ defmodule ElixirAnalyzer.TestSuite.CaptainsLog do | |||
| calling_fn module: CaptainsLog, name: :format_stardate | |||
| called_fn module: :io_lib, name: :_ | |||
| comment Constants.captains_log_use_io_lib() | |||
There was a problem hiding this comment.
You are right that we should not be sending two (contradictory) comments to someone that didn't use an Erlang function.
Let's make it so that both assert_call for format_stardate send the same comment Constants.captains_log_use_erlang(), but that comment should be generic and say that we expect the use of an Erlang function, any function, not the one from the :erlang module specifically.
And then we can dump the more specific Constants.captains_log_use_io_lib() comment.
As described in issue #340, I modified the file by attempting to perform the
checkwith the AST.I am uncertain if this is correct, but the tests I added also work with the examples I created.
As soon as I get the go-ahead, I'll also make a PR on website-copy.
I hope this has been helpful. 😄