Skip to content
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

Fix raise error when the expectation target is an error instance. #236

Merged

Conversation

fables-tales
Copy link
Member

Not sure if this is the best way to do it, but it certainly seems to work. Thoughts?

@fables-tales
Copy link
Member Author

Related #232

@fables-tales
Copy link
Member Author

Also this gave some errors related to differs when I ran locally, I want to see if it's a local problem or if travis picks it up.

@fables-tales
Copy link
Member Author

I also get these errors on master, any ideas @myronmarston ?

def expected_error_class
(@expected_error.is_a? Class) ? @expected_error : @expected_error.class
end

Copy link
Member

Choose a reason for hiding this comment

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

This is interesting -- I didn't realize 1.9.3- supported rescuring an exception instance but 2.0.0 doesn't. Good find! I noticed something when playing around in irb:

2.0.0p0 :001 > $exc = StandardError.new("boom")
 => #<StandardError: boom>
2.0.0p0 :002 > def try
2.0.0p0 :003?>     raise $exc
2.0.0p0 :004?>   rescue $exc => e
2.0.0p0 :005?>     puts "Rescued #{e}"
2.0.0p0 :006?>   end
 => nil
2.0.0p0 :007 > try
TypeError: class or module required for rescue clause
    from (irb):4:in `rescue in try'
    from (irb):3:in `try'
    from (irb):7
    from /Users/myron/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in `<main>'
2.0.0p0 :008 >

As the error indicates, rescue SomeModule is valid, too...and your is_a?(Class) conditional here will skip that case.

On top of that, I was just realizing that this logic will wrongly allow it to pass when you do this:

error = StandardError.new("foo")
expect {
  raise StandardError.new("bar")
}.to raise_error(error)

When a user passes an exception instance to raise_error, I think the expectation is that it will only pass if the raised error is == to the passed exception instance. The change here will allow it to pass if the exception class is the same.

I'm thinking that we may want to do a bit of a larger refactoring of this matcher....rather than having a rescue expected_class and another rescue Exception, maybe we should just have the rescue Exception part, and then the actual and expected exceptions can be compared using == and ===.

Regardless of the approach taken, it would be great to have additional spec coverage of the exception instance case to handle the example I put above.

(BTW, here's the 2.0.0 change: http://bugs.ruby-lang.org/issues/4438 )

Copy link
Member Author

Choose a reason for hiding this comment

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

Hi @myronmarston. I've updated this with some new specs to actually assert around this behaviour. So what I felt the best way to do this is compare whether actual == expected, or actual.is_a? expected. Thoughts?

fables-tales pushed a commit to fables-tales/rspec-expectations that referenced this pull request Apr 10, 2013
Signed-off-by: Sam Phippen <samphippen@googlemail.com>
# This clause should be empty, but rcov will not report it as covered
# unless something (anything) is executed within the clause
"http://eigenclass.org/hiki.rb?rcov-0.8.0"
if @actual_error == @expected_error || @actual_error.is_a?(@expected_error)
Copy link
Member

Choose a reason for hiding this comment

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

I believe rescue actually uses === for matching (at least, that's what Exceptional Ruby said), so I think we should use that here:

if @actual_error == @expected_error || @expected_error === @actual_error

@fables-tales
Copy link
Member Author

@myronmarston how's this looking now?

@myronmarston
Copy link
Member

@myronmarston how's this looking now?

Closer! But see my comment on === -- once that's fixed, we can merge this.

Sam Phippen added 5 commits April 15, 2013 16:13
This closes rspec#232

Signed-off-by: Sam Phippen <samphippen@googlemail.com>
Signed-off-by: Sam Phippen <samphippen@googlemail.com>
Signed-off-by: Sam Phippen <samphippen@googlemail.com>
Signed-off-by: Sam Phippen <samphippen@googlemail.com>
Signed-off-by: Sam Phippen <samphippen@googlemail.com>
@fables-tales
Copy link
Member Author

pew pew pew. Also rebase against master.

@myronmarston
Copy link
Member

Looks good. Feel free to merge once travis is green.

@fables-tales
Copy link
Member Author

@myronmarston should I make my expectations more lax, or is there a way that I can get 1.8.7, 1.9.2 and ree to give me the strings instead of pointers on that travis backtrace?

@myronmarston
Copy link
Member

Can you interpolate the exception instances into the expected failure string to match what the matcher does?

Signed-off-by: Sam Phippen <samphippen@googlemail.com>
@fables-tales
Copy link
Member Author

@myronmarston so I think this is now ready for merging. Anything I've missed?

myronmarston added a commit that referenced this pull request Apr 15, 2013
Fix raise error when the expectation target is an error instance.
@myronmarston myronmarston merged commit 7f02b50 into rspec:master Apr 15, 2013
@myronmarston
Copy link
Member

nope :). Thanks as always!

@fables-tales
Copy link
Member Author

literally awesome. 🐴

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.

None yet

2 participants