-
-
Notifications
You must be signed in to change notification settings - Fork 525
space-age: Add generator #583
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still needed a custom template to add this constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've created an issue for this: #589
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be helpful, I'll add it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
age = SpaceAge.new(1_000_000_000) | ||
assert_in_delta 31.69, age.on_earth, DELTA | ||
end | ||
|
||
def test_age_in_mercury_years | ||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is no longer used.
|
||
refine Fixnum do | ||
def underscore | ||
self.to_s.reverse.gsub(/...(?=.)/, '\&_').reverse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good 👍
@@ -0,0 +1,31 @@ | |||
class SpaceAgeCase < Generator::ExerciseCase | |||
using Generator::Underscore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Generator::Underscore
already used by Generator::ExerciseCase
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it definitely is. I can swap my using
statement in favor of requiring 'generator/exercise_case'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is missing the canonical_data_version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be an array?
|
||
end | ||
|
||
SpaceAgeCases = proc do |data| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is no longer needed.
"age = SpaceAge.new(#{seconds.underscore})", | ||
assertion, | ||
].join("\n") | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might be a method in Generator::ExerciseCase that can join and indent for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this constant used/necessary?
db627f8
to
f11ad7b
Compare
|
||
class SpaceAgeCase < Generator::ExerciseCase | ||
using Generator::Underscore | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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: