Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new check_source check to check source code as a string #189

Merged
merged 12 commits into from
Oct 14, 2021

Conversation

jiegillet
Copy link
Contributor

@jiegillet jiegillet commented Oct 9, 2021

Closes part 2 of #169.
This one came together faster than expected.
It might be easiest to review commit by commit.

If it gets approved, I will also add it the docs and recipe (with warnings to only use this if other techniques can't work).

@jiegillet jiegillet added x:action/create Work on something from scratch x:module/analyzer Work on Analyzers x:type/coding Write code that is not student-facing content (e.g. test-runners, generators, but not exercises) x:size/large Large amount of work labels Oct 9, 2021
Copy link
Contributor

@neenjaw neenjaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition, I have a few questions/comments that I think should be addressed before merge.

lib/elixir_analyzer/exercise_test/check_source.ex Outdated Show resolved Hide resolved
{node, Map.put(test_data, :comment, comment)}
end

@supported_types ~w(essential actionable informative celebratory)a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either in this pr or another, this check for the supported check levels is probably something that is repeated. Can we extract this check to another module so we can just do something like this:

# ...
    if not AnalyzerCaseUtil.supported_case_type?(type) do
      raise #...
    end
# ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to do this in another PR (which I think is fine and keeps this PR's focus singular), can you open an issue and assign to me? I would like to do this if not already done, thanks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought about that actually, some code is now duplicated three times, which starts to smell like a refactor. I'd be happy to assign this to you, once this gets merged.

Maybe even

 defp do_walk_check_source_block({:type, _, [type]} = node, test_data) do
    AnalyzerCaseUtil.supported_case_type?(type, :check_source)

If it works well for the other cases.

Copy link
Contributor

@neenjaw neenjaw Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pros and cons for sure. There is a cost to drying up code too much. If you have the bandwidth, reading 99 bottles of oop is a good discussion on this.

Passing the type of check (:check_source) creates a dependency in that future Util function because it then has to "know" about all of the types of check that exist which perhaps all it really need to know is if the type is one of the standard 4 types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just thinking of inserting :check_source in the string raised, but I do see your point.

Co-authored-by: Tim Austin <tim@neenjaw.com>
lib/elixir_analyzer/exercise_test.ex Outdated Show resolved Hide resolved
type :actionable
comment Constants.german_sysadmin_no_integer_literal()

check(source) do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String source only? No AST?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... Originally I had both, so it's not like it's impossible. I removed it because it felt too complex, somehow. And since the AST is built from the string to begin with, it's very simple to use Code.string_to_quoted to get the AST.

I'm on the fence, so if you think it's better design, I will put it back in. The test I would add would probably be the same as the indentation check, that's the best use I can think of.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can think of many checks that I would want to do on the AST that current macros do not allow, but you're right, we can just call Code.string_to_quoted. As long as it doesn't happen a thousand times in a single analyzer run, there's probably no need to worry about the performance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. And if end up using ASTs many times, it won't be difficult to put in back in.

Comment on lines 44 to 45
integers = ["252", "246", "228", "223"]
not Enum.any?(integers, &String.contains?(source, &1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried that this check is a bit weak. It could be accidentally triggered by something silly in a comment, for example writing ?ü # 252 😁. What if we did the opposite check - ensure that the strings "?ü" etc are all in the source code? Maybe for all the special values from the exercise, so including a, z, and underscore. I just saw a solution that only used the question mark syntax for the special characters, but not the simple ones.

It's not much better, but at least it won't be falsely triggered by comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, it's a more robust check.

test/elixir_analyzer/test_suite/german_sysadmin_test.exs Outdated Show resolved Hide resolved
Co-authored-by: Angelika Tyborska <angelikatyborska@fastmail.com>
Copy link
Member

@angelikatyborska angelikatyborska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (except for the remaining typos and comment that still needs merging)

It will have false-positives for some solutions that I can see in community solutions right now. They're all all over the place... using Enum.filter when it's completely unnecessary or spelling out the whole alphabet as a charlist 🤷. But I think it's better to have those false positives now and help all of those people lost without ? and add more analyzer check for the exercise later.

end
end

check_source "finds integer litteral" do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that this typo with double t is everywhere...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so sorry, its the French spelling. My English is pretty good, but I have a few words that I simply cannot spell right (exercice, litterature, comparaison, ...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that explains it! I have words that I can't spell correctly either. Having a dictionary in the text editor helps a lot. That's how I even noticed those typos 😁

case game do
"fifa" -> "fifa 98"
"tomb raider" -> "tomb raider II (1997)"
_ -> "goat simulator"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to argue with that code 👍

@angelikatyborska
Copy link
Member

Let's merge! I'm waiting on the docs and recipes update in a new PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
x:action/create Work on something from scratch x:module/analyzer Work on Analyzers x:size/large Large amount of work x:type/coding Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants