Skip to content

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

Merged
merged 1 commit into from
May 19, 2017
Merged

Conversation

ajwann
Copy link
Contributor

@ajwann ajwann commented Apr 30, 2017

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

  • Bug fix (non-breaking change which fixes an issue)
  • n/a Enhancement (non-breaking change which adds functionality)
  • n/a Breaking change (fix or enhancement that would cause existing functionality to change)
  • n/a Gardening (code and/or documentation cleanup)

References and Closures

references #396

Checklist:

  • I have read the CONTRIBUTING document.
  • n/a My change relies on a pending issue/pull request
  • n/a My change requires a change to the documentation.
  • n/a I have updated the documentation accordingly.
  • n/a I have added tests to cover my changes.
  • All new and existing tests passed.

def test_age_in_seconds
age = SpaceAge.new(1_000_000)
assert_in_delta 1_000_000, age.seconds, DELTA
end
Copy link
Contributor Author

@ajwann ajwann Apr 30, 2017

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

Copy link
Contributor

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.

@tommyschaefer
Copy link
Contributor

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! 😄

@hilary
Copy link
Contributor

hilary commented Apr 30, 2017

You might also find it helpful to see what the final version of the etl PR looked like: #575.

@ajwann
Copy link
Contributor Author

ajwann commented May 1, 2017

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.

@Insti Insti changed the title space-age: added generator [WIP] space-age: added generator May 1, 2017
@Insti Insti changed the title [WIP] space-age: added generator [WIP] space-age: Add generator May 1, 2017
@ajwann ajwann force-pushed the add-generator-for-space-age branch 2 times, most recently from f0e7283 to ec3fce6 Compare May 2, 2017 00:00
"age = SpaceAge.new(#{underscore_format(seconds)})",
indent(4, assertion),
].join("\n")
end
Copy link
Contributor Author

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
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 still needed a custom template to add this constant.

Copy link
Contributor

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

Copy link
Contributor

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.

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 think that would be helpful, I'll add it.

Copy link
Contributor Author

@ajwann ajwann May 11, 2017

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.

@ajwann
Copy link
Contributor Author

ajwann commented May 2, 2017

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
Copy link
Contributor

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?

Copy link
Contributor Author

@ajwann ajwann May 4, 2017

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),
Copy link
Contributor

@Insti Insti May 2, 2017

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

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; I can use the indent_lines method of ExerciseCases, and add the integer underscore formatting method I'm using to the Underscore module.

Copy link
Contributor

@Insti Insti left a 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.

@Insti
Copy link
Contributor

Insti commented May 2, 2017

Sorry for all the complications here @ajwann, you're on the 🔪 bleeding edge 🔪 of test generation right now!

@ajwann ajwann force-pushed the add-generator-for-space-age branch 2 times, most recently from 823be7e to 515686c Compare May 11, 2017 22:55
@ajwann
Copy link
Contributor Author

ajwann commented May 11, 2017

I think we are finally good to go!

@@ -0,0 +1,26 @@
#!/usr/bin/env ruby
gem 'minitest', '>= 5.0.0'
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

@Insti Insti May 12, 2017

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?

Copy link
Contributor Author

@ajwann ajwann May 14, 2017

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'.

Copy link
Contributor

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/

@Insti
Copy link
Contributor

Insti commented May 12, 2017

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
Copy link
Contributor

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

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
Copy link
Contributor

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)}",
]
Copy link
Contributor

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|
Copy link
Contributor

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
Copy link
Contributor

@Insti Insti May 12, 2017

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.

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 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
Copy link
Contributor

Choose a reason for hiding this comment

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

Great explanatory comment. 👍

@ajwann ajwann force-pushed the add-generator-for-space-age branch from 515686c to 4a91b62 Compare May 14, 2017 22:24
@ajwann ajwann force-pushed the add-generator-for-space-age branch from 4a91b62 to e4615ad Compare May 14, 2017 22:50
@ajwann
Copy link
Contributor Author

ajwann commented May 14, 2017

@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 bin/generate space-age I get an error saying that a generator currently doesn't exist for spage-age. My generator is still in exercises/space-age/.meta/generator/ so I'm not sure what's causing the issue.

@Insti
Copy link
Contributor

Insti commented May 15, 2017

@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'
Copy link
Contributor

@Insti Insti May 15, 2017

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.

@Insti
Copy link
Contributor

Insti commented May 15, 2017

@ajwann

when I attempt to run bin/generate space-age I get an error saying that a generator currently doesn't exist for spage-age. My generator is still in exercises/space-age/.meta/generator/ so I'm not sure what's causing the issue.

The expected filename has changed, it should now be called space_age_case.rb (no 's' on 'case'). More apologies for changing everything on you!


def workload
indent_lines(["age = SpaceAge.new(#{seconds.underscore})",
" assert_in_delta #{expected}, age.on_#{planet.downcase}, DELTA"
Copy link
Contributor

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.

require 'generator/exercise_case'

class SpaceAgeCase < Generator::ExerciseCase
using Generator::Underscore
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 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.

Copy link
Contributor

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
Copy link
Contributor

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?

@ajwann ajwann force-pushed the add-generator-for-space-age branch from db627f8 to f11ad7b Compare May 19, 2017 19:33

class SpaceAgeCase < Generator::ExerciseCase
using Generator::Underscore

Copy link
Contributor Author

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.

@Insti Insti changed the title [WIP] space-age: Add generator space-age: Add generator May 19, 2017
@Insti Insti merged commit f421126 into exercism:master May 19, 2017
@Insti
Copy link
Contributor

Insti commented May 19, 2017

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! 😄

@Insti Insti removed the in progress label May 19, 2017
@Insti Insti mentioned this pull request May 21, 2017
@Insti Insti removed the ready label Jun 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants