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

Make be_predicate fail upon calling a private method #207

Merged
merged 10 commits into from May 30, 2013

Conversation

JonRowe
Copy link
Member

@JonRowe JonRowe commented Feb 13, 2013

A potential solution to #206, this makes be_predicate fail with a nice warning when calling a private methods.

Potentially this might want to be configurable, so as not to break existing test suites? Is this a decision we want to make for the person writing the test suite? Is #206 the desired behaviour or do we want to let users make the decision about calling private methods...

@myronmarston
Copy link
Member

@JonRowe -- thanks for taking a stab at this. I've been meaning to respond to #206. I share many of the questions you mentioned above!

Anyhow, let's take the conversation back to #206 where we can figure out the overall strategy to solve this, and then, if it lines up with what you've done here, we can return to this PR to discuss any remaining implementation concerns.

"""
When I run `rspec attempting_to_match_private_method_spec.rb`
Then the output should contain "1 example, 1 failure"
And the output should contain "expected secret? to return true, but it's a private method"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this message should clarify that private methods are not accessible in expectations. It might seem obvious to some, but it reads (to me) like "I was trying to make a left turn, but I was thirsty" (the "but" being somewhat orthogonal to the expectation).

In normal use, calling privates from the outside results in an error e.g.

NoMethodError: private method `print' called for "this":String

Why not treat these as errors as well, e.g.

NoMethodError: private method `print' called for "this":String (expectations on private methods are not supported)

Or even take it a step further:

UnsupportedOperationError: expectation set on private method `print' for "this":String

@JonRowe
Copy link
Member Author

JonRowe commented Feb 15, 2013

I've taken your feedback to heart, and am raising an error with a message, which actually cleans up the resulting failure messages again, however on 1.8.7 I'm now getting weird Too many open files (Errno::EMFILE) errors, but not on the changed feature, any hints as to what's wrong there?

@dchelimsky
Copy link
Contributor

@JonRowe no idea :( I've never understood why that happens.

@JonRowe
Copy link
Member Author

JonRowe commented Feb 17, 2013

Just re-run today and they work, from a bit of googling seems this is a "weird" Heisenbug which is platform dependant... So this passes on 1.8.7 and 1.9.3

@fables-tales
Copy link
Member

So my feeling here is this might be a travis weirdness, can we force it to rerun the build?

@JonRowe
Copy link
Member Author

JonRowe commented Apr 15, 2013

We can do, but I have experienced the failure locally, it's a weird Ruby heisenbug...

@JonRowe
Copy link
Member Author

JonRowe commented Apr 16, 2013

I rebased this, so let's see what happens to the build.

@JonRowe
Copy link
Member Author

JonRowe commented Apr 16, 2013

Woo, passes

@fables-tales
Copy link
Member

@JonRowe I think this needs a changelog entry, but is otherwise pretty awesome. Could you add one? 👍 💚 :

@myronmarston
Copy link
Member

This can't be merged until 3.0, because it'll be a breaking change. It's definitely a good change, though!

@fables-tales
Copy link
Member

That too :)

@@ -135,6 +135,9 @@ def initialize(*args, &block)

def matches?(actual)
@actual = actual

raise "UnsupportedOperationError: expectation set on private method `#{predicate}`" if actual.private_methods.include?(predicate.to_sym) || actual.private_methods.include?(predicate.to_s)
Copy link
Member

Choose a reason for hiding this comment

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

  • This line is super long, particularly for having a trailing if. I'd prefer to see the non-trailing if for a case like this.
  • Rather than including handling for both 1.8 and 1.9 in a single line, I'd prefer to see something like:
if methods.first.is_a?(String)
  def private_method_on?(object)
    object.private_methods.include?(predicate.to_s)
  end
else
  def private_method_on?(object)
    object.private_methods.include?(predicate.to_sym)
  end
end

Copy link
Member Author

Choose a reason for hiding this comment

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

I've refactored this, take a look when you have a sec.

@fables-tales
Copy link
Member

@JonRowe want to merge this in now we're doing 3.0 on master?

@dchelimsky
Copy link
Contributor

@JonRowe want to merge this in now we're doing 3.0 on master?

I thought that was after the 2.14.0 final release. Correct? No?

@JonRowe
Copy link
Member Author

JonRowe commented May 28, 2013

That's what I was pushing for on the mailing list. I think master should be 2.14 until we actually ship 2.14 and not just an rc. /cc @myronmarston @soulcutter

@fables-tales
Copy link
Member

@dchelimsky 2.14 dev is on the maintenance branch now. @myronmarston @alindeman and myself were chatting about this last night on irc. The 2.99 maintenance branch also exists.

@dchelimsky
Copy link
Contributor

No sense going back :)

On Tue, May 28, 2013 at 6:29 PM, Sam Phippen notifications@github.comwrote:

@dchelimsky https://github.com/dchelimsky 2.14 dev is on the
maintenance branch now. @myronmarston https://github.com/myronmarston
@alindeman https://github.com/alindeman and myself were chatting about
this last night on irc. The 2.99 maintenance branch also exists.


Reply to this email directly or view it on GitHubhttps://github.com//pull/207#issuecomment-18587035
.

@JonRowe
Copy link
Member Author

JonRowe commented May 30, 2013

I'm going to look at this and merge it tonight

@@ -135,6 +135,9 @@ def initialize(*args, &block)

def matches?(actual)
@actual = actual

raise "UnsupportedOperationError: expectation set on private method `#{predicate}`" if is_private_on?( @actual )
Copy link
Contributor

Choose a reason for hiding this comment

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

How about making an UnsupportedOperationError class? Raising a RuntimeError with a message that suggests it is a different kind of error feels odd to me.

Copy link
Member

Choose a reason for hiding this comment

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

👍

@fables-tales
Copy link
Member

I like this. 🐑 it.

@@ -31,6 +31,18 @@
}.to raise_error(NameError, /happy\?/)
end

it 'fails when :predicate? is private' do
klass = Class.new do
Copy link
Contributor

Choose a reason for hiding this comment

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

Just for grins: I'd name this class privately_happy and have happy? return true :)

Copy link
Member Author

Choose a reason for hiding this comment

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

On your head be it... ;) I totally did not indulge my own humour in the commit message...

Copy link
Contributor

Choose a reason for hiding this comment

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

:)

JonRowe added a commit that referenced this pull request May 30, 2013
…vate

Make be_predicate fail upon calling a private method
@JonRowe JonRowe merged commit 0409804 into rspec:master May 30, 2013
@JonRowe JonRowe deleted the expect_private_methods_to_be_private branch May 30, 2013 13:30
@JonRowe JonRowe restored the expect_private_methods_to_be_private branch June 1, 2013 01:31
@JonRowe JonRowe deleted the expect_private_methods_to_be_private branch June 1, 2013 01:44
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

4 participants