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
Add better inspect
output for ExampleGroup
#1687
Add better inspect
output for ExampleGroup
#1687
Conversation
@@ -548,6 +553,13 @@ def self.set_ivars(instance, ivars) | |||
end | |||
|
|||
# @private | |||
def self.set_inspect_method(instance, text) | |||
instance.define_singleton_method(:inspect) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defining singleton methods blows away the method cache, and besides, we own the class definition of instance
, so instead I'd like to see us define inspect
directly on the class with the appropriate logic, rather than defining it on each instance.
@myronmarston The latest commit removes the call to define_singleton_method and replaces it by storing the inspect output on the instance. I needed to override the instance_variables method to prevent the instance variable storing the inspect output from being set to nil. Let me know if you can think of a better way to handle the inspect output. |
This constructor change is causing some internal rspec-rails code to fail. I'll have to audit things, but it's possible it's a simple one-liner fix...I'm not sure if I'll have time to get to it before Monday. |
Previously there was no constructor for the `ExampleGroup`. This changed with rspec/rspec-core#1687. Instead of exactly matching the contructor, use the standard Ruby argument catch-all to simply delegate up the chain.
Ok, looked relatively easy to fix. Opened a PR for it on rspec-rails. |
I merged into rspec-rails master. Kicked the build to see if it passes now. |
group = ExampleGroup.describe 'SomeClass' do | ||
example 'an example' do | ||
an_example = self | ||
expcts(1).to eq(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo? This should be expects(1).to eq(1)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's actually not a typo. I based it on the example the the issue description. See #1590
However, there doesn't need to be an error in the example block in order to produce the inspect output. I'm going to remove the expct
calls.
Thanks, @kcdragon, this is really close! Besides addressing the last couple comments I left, do you mind squashing it all into one commit? Also, next time you push updates, can you post a comment mentioning you've done so? Github doesn't notify us when there are new commits and I just happened to notice you had pushed stuff this time. |
|
||
path = RSpec::Core::Metadata.relative_path(__FILE__) | ||
expect(an_example.instance_variable_get(:@__inspect_output)).to eq("\"example at #{path}:#{line}\"") | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing the instance variable directly like this is a code smell, IMO. I think this spec can be tweaked slightly to retain it's essence without doing that:
it 'does not clear the inspect output after the example runs' do
an_example = nil
line = __LINE__ + 2
group = ExampleGroup.describe do
example do
an_example = self
end
before(:context) {}
end
group.run
path = RSpec::Core::Metadata.relative_path(__FILE__)
expect(an_example.inspect).to end_with("\"example at #{path}:#{line}\">")
end
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm going to get rid of this spec. It's very similar to:
it 'includes description and location' do
an_example = nil
line = __LINE__ + 2
group = ExampleGroup.describe 'SomeClass1' do
example 'an example' do
an_example = self
end
end
group.run
path = RSpec::Core::Metadata.relative_path(__FILE__)
expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass1 \"an example\" (#{path}:#{line})>")
end
Changing from defining a singleton method to storing the inspect output on the ExampleGroup Add documentation for instance_variables and inspect Handling string element in instance_variables for ruby 1.8 Removing un-needed expct calls in spec Handling ExampleGroup without inspect output, handling ExampleGroup without a description, refactoring logic to ignore `@__inspect_output` when determining before context ivars Improve readability of no inspect output spec and does not copy inspect output from before context to examples spec
6773020
to
ffd7492
Compare
@myronmarston I added more commits and rebased. |
So this LGTM (nice work!), and I was going to merge, but then I decided to try it out for the case from #1590. Unfortunately, it doesn't work; when I try the example from #1590, here's what I get:
Playing around with it jogged my memory and reminded me that I've run across an issue like this before, where a user-defined https://bugs.ruby-lang.org/issues/8982 As it turns out, https://github.com/ruby/ruby/blob/v2_1_2/error.c#L1137-L1139 Insane, huh? Not sure if it's possible to achieve the desired behavior :(. Anyone got any ideas? |
That is really strange. My first thought was to handle the 65 character limit by only returning parts of the inspect output until we reach the limit (example description, then file name, etc.). But then I realized how little 65 characters gives us so I'm not sure if that's even worth it. |
I thought about possibly truncating it, too, but as you said, that would truncate a lot and it's ridiculous we have to do that. Anyhow, I'm going to merge this because it's still a big improvement, even if not visible to users when they hit |
Thanks, @kcdragon! |
…for-example-group Add better `inspect` output for ExampleGroup
…tput-for-example-group Add better `inspect` output for ExampleGroup
[ci skip]
Pull Request for #1590
The only problem I ran into was that the syntax error in the after hook test produces error output while running the spec (the test still passes).
This is definitely not ideal because it could distract from problems with "real" after hooks. The only two options I could up with were: 1) remove the test, or 2) add a way to suppress that error. I'm interested in your thoughts on the best way to handle this.