Skip to content

Add triangle test generator #474

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 4 commits into from
Nov 21, 2016
Merged

Add triangle test generator #474

merged 4 commits into from
Nov 21, 2016

Conversation

favrik
Copy link
Contributor

@favrik favrik commented Oct 26, 2016

Hello!,

this is for issue #472, thoughts? :)

Thanks!

@Insti
Copy link
Contributor

Insti commented Oct 26, 2016

Awesome, thanks, ❤️ I'll review this a bit later.

@bmulvihill
Copy link
Contributor

bmulvihill commented Oct 27, 2016

@favrik Thanks for the PR! We have recently standardized our generator interface so please ensure the methods test_name, skipped and workload are defined, and use them within your example.tt

This has only been recently decided and here is the currently open PR for reference

Excerpt from that PR's README update:

All generators currently adhere to a common public interface, and must define the following three methods:

  • test_name - Output the name of the test
  • workload - Output the body of the test
  • skipped - Output skip syntax

end

def test_isosceles_triangles_have_first_and_last_sides_equal
def test_all_zero_sides_are_illegal__so_the_triangle_is_not_equilateral
Copy link
Contributor

Choose a reason for hiding this comment

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

I see a couple test names with two underscores

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah, decided to replace commas with underscores too, but I see is not that really necessary. xD Ty!

class TriangleTest < Minitest::Test<% test_cases.each do |test_case| %>
def <%= test_case.name %><% if test_case.skipped? %>
skip<% end %>
triangle = Triangle.new(<%= test_case.sides %>)<% if test_case.expected%>
Copy link
Contributor

Choose a reason for hiding this comment

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

I would consider moving some of this logic into the workload method once it is defined

Copy link
Member

@kotp kotp Oct 27, 2016

Choose a reason for hiding this comment

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

Check out Hamming as an example as well. It will help to remove the logic in the view, at least for skip.

@favrik
Copy link
Contributor Author

favrik commented Oct 27, 2016

@bmulvihill totally missed that PR!

Thanks for the feedback!, I'll apply the updates to conform to the interface in a few hours. :)

* Conform to the test generator common public interface
* Fix double underscores in method names
* Remove unused TriangleError class
@favrik
Copy link
Contributor Author

favrik commented Oct 27, 2016

Updated, thanks!

"triangle.#{triangle}?"
def workload
"triangle = Triangle.new(#{sides})
#{assert_or_refute} triangle.#{triangle}?, #{failure_message}"
Copy link
Contributor

Choose a reason for hiding this comment

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

This relies on the indentation of the test case generator being the same as the indentation of the template file, Which is not a problem now, but is rather fragile.
Have a look at how Transpose handles indenting: #466

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, it took me a while to understand this, but I think I get it now. Basically, if the *_cases.rb file changes (due to some refactoring for example), the indentation can be affected, and now you have 1 more thing that needs to be adjusted. Thanks!

initial = description.downcase
replaced = initial.gsub(/(true|false)/, replacements)
if initial.eql?(replaced) && !initial.include?(triangle)
replaced = triangle + ' triangle ' + initial
end
'test_%s' % replaced.gsub(/[ ,-]/, '_')
'test_%s' % replaced.gsub(/[, -]/, '_').squeeze('_')
Copy link
Contributor

@Insti Insti Oct 27, 2016

Choose a reason for hiding this comment

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

gsub(/[, -]/, '_').squeeze('_')
Ruby has a method that does this.
tr_s(', -','_')

end

def failure_message
"Expected '#{expected}', triangle is #{expected ? '' : 'not '}#{triangle}."
"\"Expected '#{expected}', triangle is #{expected ? '' : 'not '}" +
"#{triangle}.\""
Copy link
Contributor

@Insti Insti Oct 27, 2016

Choose a reason for hiding this comment

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

Rather than splitting this line, how about refactoring it to extract some named methods.
You can also use %Q to avoid having to escape your doublequotes.
%Q("Expected '#{expected}', triangle is #{expected_type}")

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.

Looking good.
Edit: Looks like you replaced the commit I'd commented on :( The comments are still relevant I think.

@favrik
Copy link
Contributor Author

favrik commented Oct 27, 2016

@Insti I only added a new commit, all your comments are relevant, thanks very much for the review! :)

I'll add another commit with the suggested changes.

* Use indentation for workload method
* Use tr_s instead of gsub
* Use %Q() to simplify string
@favrik
Copy link
Contributor Author

favrik commented Oct 27, 2016

I've added @Insti suggestions in a new commit, and also extracted some duplicate strings to a method. Thanks for the reviews!! :)

Copy link
Member

@kotp kotp left a comment

Choose a reason for hiding this comment

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

The prior version seems to be "cleaner", perhaps this is a little over engineered?

@favrik
Copy link
Contributor Author

favrik commented Oct 31, 2016

Hi @kotp, I guess you are referring to the expected_type method and related logic in lib/triangle_cases.rb, if that's the case, I agree. On one hand I think it's okay-ish. On the other hand, I think it's a bit convoluted due to how I'm handling the canonical data. I can revisit in a couple of days, suggestions are definitely welcome. Thanks!

@Insti
Copy link
Contributor

Insti commented Nov 5, 2016

@favrik have you had a chance to revisit this?

@favrik
Copy link
Contributor Author

favrik commented Nov 5, 2016

@Insti I haven't 😞, but I just looked at it again and realized I had logic that is not needed. xD Added a new commit. Could use a pair of fresh eyes too! 😄


def kind
fail TriangleError if illegal?
Copy link
Member

Choose a reason for hiding this comment

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

Are we no longer raising on an illegal triangle? I did not see a comment about this in the discussions here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The canonical data for the triangle problem was recently updated to test for properties instead of its type. Thoughts?

skip
assert_raises(TriangleError) do
Triangle.new(1, 3, 1).kind
end
Copy link
Member

Choose a reason for hiding this comment

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

Where did the tests for illegal triangles go?

@kotp kotp merged commit 6e14659 into exercism:master Nov 21, 2016
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.

4 participants