markbates / cover_me

An RCov-esque coverage tool for Ruby 1.9
http://www.metabates.com
MIT License
203 stars 18 forks source link

Code incorrectly marked as covered when using one-line if statement #37

Closed dicom closed 13 years ago

dicom commented 13 years ago

I noticed an inconsistency where the code line is marked differently depending on if you use a one-liner if statement or the traditional multi-line version.

In my example, I had a method with code similar to this:

unless bin.is_a?(String)
  raise "Expected String, got #{bin.class}."
end

My spec did not have an example which provoked this exception, so the cover_me gem correctly marked it as not covered.

Then I changed it to a one-liner as such:

raise "Expected String, got #{bin.class}." unless bin.is_a?(String)

I made no changes to my spec, and expected this line to still be marked as not covered. However, cover_me now marked this line as green and gave me a 100%.

Upon further investigation also this version will be (incorrectly) marked as covered:

unless bin.is_a?(String) then raise "Expected String, got #{bin.class}." end
markbates commented 13 years ago

Actually that is correct behavior. Under the covers CoverMe uses a part of the standard Ruby library that tells you which lines of code were executed. It shows up in CoverMe as executed because the line was executed. Ruby has to execute the line to evaluate the if or unless statements on the right. Ruby doesn't have a way to mark a line as half executed so it marks it as fully executed. Does that make sense? The only solution is to use the multiline version of if/unless if you want to make sure Ruby reports back correctly. Make sense?

dicom commented 13 years ago

Yeah I understand, thanks for explaining.

I still think it is kind of unfortunate though, because although the actual line is executed, the code of interest in the line is not executed, and that's what we'd like to be aware of. I wonder if it is possible for the Coverage library to acquire this feature. Anyway, I understand that this is not cover_me's fault!

Thanks for making this useful gem!