Replace hard-coded Bowling tests with test generator (Fixes #456)#465
Replace hard-coded Bowling tests with test generator (Fixes #456)#465Insti merged 2 commits intoexercism:masterfrom
Conversation
|
Awesome, thanks. The current |
| assert_respond_to @game, :roll | ||
| assert_equal 1, @game.method(:roll).arity | ||
| def roll(rolls) | ||
| rolls.each { |pins| @game.roll(pins) } |
There was a problem hiding this comment.
I like that you've extracted this helper method. Good variable naming too 👍
| rolls.each { |pins| @game.roll(pins) } | ||
| end | ||
| <% test_cases.each do |test_case| %> | ||
| def <%= test_case.name %><% if test_case.skipped? %> |
There was a problem hiding this comment.
Try to keep logic out of the template file.
Have a look at the PR for anagram generator: #464 for some examples of how to do this.
Basically the test template should look like:
def <%= test_case.test_name %>
<%= test_case.skipped %>
<%= test_case.work_load %>
endThere was a problem hiding this comment.
Also we're trying to standardise the method names in generators, so using test_name, skipped, work_load is preferred.
c980e66 to
5742c74
Compare
|
Thanks, I have moved the logic into the cases file. Do you have any ideas how I could improve |
5742c74 to
f1ef7ab
Compare
| end | ||
|
|
||
| def work_load | ||
| if assert_error? |
There was a problem hiding this comment.
You're checking assert_error? twice, (again on line 30)
What if you moved all this logic into the assert method?
There was a problem hiding this comment.
Oops, the assert_error? conditional check isn't required in assert.
If we moved the logic to the assert method, we will still have one assert_error? check?
| end | ||
|
|
||
| def assert | ||
| "assert_equal #{expected}, @game.score" unless assert_error? |
There was a problem hiding this comment.
hint: assert could return an array of lines that get joined later..
There was a problem hiding this comment.
Something like this?
def assert
if assert_error?
[
"assert_raises StandardError do",
" #{roll}",
" @game.score",
"end"
]
else
[roll, "assert_equal #{expected}, @game.score"]
end
endAlso updated the example solution to address new test case
f1ef7ab to
1cd441f
Compare
|
Thanks @gchan, This looks much better now. I'd personally refactor Nice work updating the example.rb to pass the tests. 👍 |
|
For Running rubocop with your own configuration (or a default) you can use this: Copy that and create a file named, Then invoke Right now, the cops aren't really reporting anything (I would have to look to be absolutely sure, of course) so this gives you a way to use the tool in a manner that is more helpful than Bob (Jan says, 'Bob, tell me what you think of my code style.!', Bob says "Whatever."). |
|
Up to you @gchan if you do want to do the quick updates based on feedback from Rubocop. Or we can bring it in, according to me. @Insti has been looking at it closer than I have, I think. I will leave it up to his and your decision to bring it in, either as it stands or with those slight modifications. |
|
There are some Rubocop violations that can be addressed in |
|
Thanks @gchan. |
|
Corrected some Rubocop violations in a separate commit. Let me know if you need me to squash the commits. |
|
The way the two commits are now, one is style related, the other is the actual "Cargo". So these two commits are good unsquashed, if you like. Together, you would not have to show the changes. It is up to you. But the style changes may be "noise" rather than "signal". |
|
|
||
| def validate(pins) | ||
| raise 'Invalid number of pins' unless (RULES[:MIN]..RULES[:MAX]).cover?(pins) | ||
| raise 'Invalid number of pins' unless (PINS[:MIN]..PINS[:MAX]).cover?(pins) |
There was a problem hiding this comment.
According to this 1.5 is a valid number of pins.
There was a problem hiding this comment.
The correctness of example.rb is not super important, just something I noticed while I was looking through the code.
There was a problem hiding this comment.
Nice catch. Do we test for this? I don't think it is an important aspect in relation to what things are learned from the exercise. But definitely fodder for discussion in solutions!
I think when we were putting this together we didn't even consider it.
There was a problem hiding this comment.
That's a good point. I guess the xcommon data doesn't test for non-integer numbers given that it needs to support languages that are typed?
There was a problem hiding this comment.
So I think for this aspect, the discussion should go to x-common... find out if this is an aspect for others, and if we can change it in common.
There was a problem hiding this comment.
The kata is about scoring bowling, not worrying if your test inputs are valid. So I would argue against adding test cases for it.
It is something that could be discussed during solution reviews.
|
You're right about the style changes being 'noise' and is better off as a separate commit. Is there anything else I need to do on this PR to bring it in? |
| roll_n_times(10, 10) | ||
| assert_raises StandardError do | ||
| roll([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]) | ||
| @game.score |
There was a problem hiding this comment.
The error you are detecting is raised by the roll method, the way it is called hides this.
I'd like to see it made explicit that game.roll is what is raising the exception.
The way it is now @game.score is never executed, but it's still sitting there in the test looking like it is what will cause the problem. This is very misleading.
There was a problem hiding this comment.
Some of the test cases expect an exception to be raised by game.roll and an invalid roll while some are raised by game.score when the game is incomplete.
As there is no data in x-common to indicate whether the exception could be raised by score or by roll, it is difficult to procedurally generate test cases to include or exclude game.score from test cases. I'm open to any ideas.
The x-common data for exceptions sets the expected value as -1 and the decision of when to error is left up to the implementation (error when an invalid roll is made, error when scoring a game with an invalid roll, or error in both cases). With the current test cases, an implemented solution may decide to only error on game.score, game.roll, or both. This way a person could implement a solution that never errors on roll but only error on score.
There was a problem hiding this comment.
Thanks for that good explanation.
I think you've made the right decision and we need to leave the tests the way they currently are.
We can revisit this if necessary if/when the canonical data is updated.
|
Thanks for all your work on this @gchan ❤️ |
|
No problem. Thanks for the feedback. I learnt a few things along the way |
As per #456
Also updated the example solution to address new test case
Feedback is appreciated. I ran
rubocopbut I'm uncertain if it actually was able to detect offences (I deliberately indented incorrect to testrubocop).