space-age: Add generator#583
Conversation
| def test_age_in_seconds | ||
| age = SpaceAge.new(1_000_000) | ||
| assert_in_delta 1_000_000, age.seconds, DELTA | ||
| end |
There was a problem hiding this comment.
This method was missing from x-common, so I omitted it. If it's needed, I can add it to x-common or manually hack it in before the test_age_on_earth method in space_age_cases.rb
There was a problem hiding this comment.
Leaving it out is fine. If it's not specified in the readme or the canonical data it probably shouldn't be there.
|
Hi There! First off, thank you for your help converting this exercise to use generated tests! There has been some really awesome new work on generators by @hilary that has changed how we implement new generators. Check out the updated documentation, for some tips on upgrading this to the new pattern! Thank you again for your work and time! 😄 |
|
You might also find it helpful to see what the final version of the etl PR looked like: #575. |
|
Awesome, thank you both. I've read over the final etl PR and I'll take a look at the new docs as soon as I can this week. |
f0e7283 to
ec3fce6
Compare
| "age = SpaceAge.new(#{underscore_format(seconds)})", | ||
| indent(4, assertion), | ||
| ].join("\n") | ||
| end |
There was a problem hiding this comment.
Now workload is the only public method as per the docs.
|
|
||
| # Common test data version: <%= abbreviated_commit_hash %> | ||
| class <%= exercise_name_camel %>Test < Minitest::Test | ||
| DELTA = 0.01 |
There was a problem hiding this comment.
I still needed a custom template to add this constant.
There was a problem hiding this comment.
I wonder if a comment explaining what delta is used for would be helpful for people who are meeting assert_in_delta for the first time.
There was a problem hiding this comment.
I think that would be helpful, I'll add it.
There was a problem hiding this comment.
I̶'̶v̶e̶ ̶t̶h̶o̶u̶g̶h̶t̶ ̶a̶b̶o̶u̶t̶ ̶w̶h̶a̶t̶ ̶t̶h̶i̶s̶ ̶c̶o̶m̶m̶e̶n̶t̶ ̶s̶h̶o̶u̶l̶d̶ ̶s̶a̶y̶,̶ ̶a̶n̶d̶ ̶I̶'̶m̶ ̶k̶i̶n̶d̶ ̶o̶f̶ ̶e̶m̶b̶a̶r̶r̶a̶s̶s̶e̶d̶ ̶t̶o̶ ̶s̶a̶y̶ ̶t̶h̶a̶t̶ ̶I̶ ̶d̶o̶n̶'̶t̶ ̶r̶e̶a̶l̶l̶y̶ ̶k̶n̶o̶w̶ ̶w̶h̶a̶t̶ ̶d̶e̶l̶t̶a̶ ̶m̶e̶a̶n̶s̶ ̶i̶n̶ ̶t̶h̶i̶s̶ ̶c̶a̶s̶e̶.̶ ̶B̶e̶s̶i̶d̶e̶s̶ ̶t̶h̶e̶ ̶b̶a̶s̶i̶c̶ ̶m̶a̶t̶h̶e̶m̶a̶t̶i̶c̶s̶ ̶d̶e̶f̶i̶n̶i̶t̶i̶o̶n̶ ̶o̶f̶ ̶"̶c̶h̶a̶n̶g̶e̶ ̶i̶n̶ ̶a̶ ̶g̶i̶v̶e̶n̶ ̶q̶u̶a̶n̶t̶i̶t̶y̶"̶,̶ ̶I̶'̶m̶ ̶k̶i̶n̶d̶ ̶o̶f̶ ̶s̶t̶u̶m̶p̶e̶d̶.̶
Thanks Internet. I'll add a comment.
|
I think I've moved everything where it belongs, please let me know if I missed anything. |
| def test_age_on_mercury | ||
| skip | ||
| age = SpaceAge.new(2_134_835_688) | ||
| assert_in_delta 67.65, age.on_earth, DELTA |
There was a problem hiding this comment.
I don't like that the on_earth method is also being tested here, I wouldn't do it in real life code, but I cannot tell if this test has educational value and should remain.
https://github.com/exercism/xruby#workload-philosophy
Thoughts?
There was a problem hiding this comment.
I don't think it provides a lot value, other than to give the user a baseline for which to compare the age difference. I personally think we could take out the on_earth assertions for each test and just leave the single test_age_on_earth test.
| def workload | ||
| [ | ||
| "age = SpaceAge.new(#{underscore_format(seconds)})", | ||
| indent(4, assertion), |
There was a problem hiding this comment.
There are some (currently undocumented) methods in ExerciseCases that can do underscore formatting and indenting for you.
https://github.com/exercism/xruby/blob/master/lib/generator/exercise_cases.rb
We should probably also add Integer underscore formatting to https://github.com/exercism/xruby/blob/master/lib/generator/underscore.rb
There was a problem hiding this comment.
Sounds good; I can use the indent_lines method of ExerciseCases, and add the integer underscore formatting method I'm using to the Underscore module.
Insti
left a comment
There was a problem hiding this comment.
I like what you've done here and would be happy to merge it as is, but have made some comments I'd be interested in hearing your thoughts on.
|
Sorry for all the complications here @ajwann, you're on the 🔪 bleeding edge 🔪 of test generation right now! |
823be7e to
515686c
Compare
|
I think we are finally good to go! |
| @@ -0,0 +1,26 @@ | |||
| #!/usr/bin/env ruby | |||
| gem 'minitest', '>= 5.0.0' | |||
There was a problem hiding this comment.
This line is no longer used.
|
|
||
| refine Fixnum do | ||
| def underscore | ||
| self.to_s.reverse.gsub(/...(?=.)/, '\&_').reverse |
| @@ -0,0 +1,31 @@ | |||
| class SpaceAgeCase < Generator::ExerciseCase | |||
| using Generator::Underscore | |||
There was a problem hiding this comment.
Is Generator::Underscore already used by Generator::ExerciseCase?
There was a problem hiding this comment.
Yep, it definitely is. I can swap my using statement in favor of requiring 'generator/exercise_case'.
There was a problem hiding this comment.
It turns out you can not, due to lexical scope issues. Sorry for misleading you.
http://blog.honeybadger.io/understanding-ruby-refinements-and-lexical-scope/
|
This is looking good @ajwann, sorry we keep moving the goalposts on you! |
| require 'minitest/autorun' | ||
| require_relative 'space_age' | ||
|
|
||
| # Common test data version: 7c63e40 |
There was a problem hiding this comment.
This line is missing the canonical_data_version
There was a problem hiding this comment.
There was a problem hiding this comment.
These comments should be about the test_template.erb version. (sorry)
| @@ -0,0 +1,31 @@ | |||
| class SpaceAgeCase < Generator::ExerciseCase | |||
There was a problem hiding this comment.
There should be a require 'generator/exercise_case' at the top of this file.
See: https://github.com/exercism/xruby#implementing-a-generator
| def assertion | ||
| [ | ||
| " #{assertion_for_location(expected, planet)}", | ||
| ] |
There was a problem hiding this comment.
Does this need to be an array?
|
|
||
| end | ||
|
|
||
| SpaceAgeCases = proc do |data| |
There was a problem hiding this comment.
This section is no longer needed.
| "age = SpaceAge.new(#{seconds.underscore})", | ||
| assertion, | ||
| ].join("\n") | ||
| end |
There was a problem hiding this comment.
There might be a method in Generator::ExerciseCase that can join and indent for you.
There was a problem hiding this comment.
I ended up using indent_lines.
| class SpaceAgeTest < Minitest::Test | ||
| # assert_in_delta will pass if the difference | ||
| # between the values being compared is less | ||
| # than the allowed delta |
There was a problem hiding this comment.
Great explanatory comment. 👍
515686c to
4a91b62
Compare
4a91b62 to
e4615ad
Compare
|
@Insti I've made all the requested updates, but I am having trouble testing the changes. I rebased off of master, but when I attempt to run |
|
@ajwann Thanks, I'll have a look into this for you when I get a chance. |
| @@ -1,67 +1,82 @@ | |||
| #!/usr/bin/env ruby | |||
| gem 'minitest', '>= 5.0.0' | |||
There was a problem hiding this comment.
This line is no longer required/used and can be deleted.
Oh, you have, you've just not regenerated the tests due the problem you were having. No problem.
The expected filename has changed, it should now be called |
|
|
||
| def workload | ||
| indent_lines(["age = SpaceAge.new(#{seconds.underscore})", | ||
| " assert_in_delta #{expected}, age.on_#{planet.downcase}, DELTA" |
There was a problem hiding this comment.
The spaces between " and assert are not required when you're using indent_lines.
e4615ad to
db627f8
Compare
| require 'generator/exercise_case' | ||
|
|
||
| class SpaceAgeCase < Generator::ExerciseCase | ||
| using Generator::Underscore |
There was a problem hiding this comment.
I'm not too familiar with refinements, but it looks like this using statement is necessary.
It doesn't look like the using statement in ExerciseCase gets inherited by SpaceAgeCase.
There was a problem hiding this comment.
Yeah, I also discovered this and commented here: #583 (comment)
It turns out you can not, due to lexical scope issues. Sorry for misleading you.
http://blog.honeybadger.io/understanding-ruby-refinements-and-lexical-scope/
Looks like github managed to hide the comment.
I also made an issue about addressing this here in xruby: #645
But including it for now is good. 👍
|
|
||
| class SpaceAgeCase < Generator::ExerciseCase | ||
| using Generator::Underscore | ||
| SECONDS_PER_YEAR_ON_EARTH = 31557600 |
There was a problem hiding this comment.
Is this constant used/necessary?
db627f8 to
f11ad7b
Compare
|
|
||
| class SpaceAgeCase < Generator::ExerciseCase | ||
| using Generator::Underscore | ||
|
|
There was a problem hiding this comment.
@Insti; I definitely didn't need that constant, it was left over from when each assertion was unnecessarily testing the age on Earth.
|
Awesome! Thanks for all your work on this @ajwann. I've merged it now, so any more changes we make to the process will be our responsibility to fix! 😄 |
Why?
space-age exercise needs a generator
What?
added generator for space-age
How Has This Been Tested?
rake test:space-age
rubocop -D
Screenshots (if appropriate):
Types of changes
References and Closures
references #396
Checklist: