Skip to content

Commit

Permalink
Merge pull request rspec#1687 from kcdragon/feature-better-inspect-ou…
Browse files Browse the repository at this point in the history
…tput-for-example-group

Add better `inspect` output for ExampleGroup
  • Loading branch information
myronmarston committed Sep 12, 2014
2 parents 80e5e13 + 25ba15d commit aea8648
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 7 deletions.
11 changes: 10 additions & 1 deletion lib/rspec/core/example.rb
Expand Up @@ -82,6 +82,15 @@ def description
RSpec.configuration.format_docstrings_block.call(description)
end

# Returns a description of the example that always includes the location.
def inspect_output
inspect_output = "\"#{description}\""
unless metadata[:description].to_s.empty?
inspect_output << " (#{location})"
end
inspect_output
end

# @attr_reader
#
# Returns the first exception raised in the context of running this
Expand Down Expand Up @@ -170,7 +179,7 @@ def run(example_group_instance, reporter)
rescue Exception => e
set_exception(e)
ensure
@example_group_instance.instance_variables.each do |ivar|
ExampleGroup.instance_variables_for_example(@example_group_instance).each do |ivar|
@example_group_instance.instance_variable_set(ivar, nil)
end
@example_group_instance = nil
Expand Down
33 changes: 27 additions & 6 deletions lib/rspec/core/example_group.rb
Expand Up @@ -419,9 +419,7 @@ def self.before_context_ivars

# @private
def self.store_before_context_ivars(example_group_instance)
return if example_group_instance.instance_variables.empty?

example_group_instance.instance_variables.each do |ivar|
instance_variables_for_example(example_group_instance).each do |ivar|
before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
end
end
Expand Down Expand Up @@ -459,7 +457,8 @@ def self.run(reporter)
reporter.example_group_started(self)

begin
run_before_context_hooks(new)
instance = new('before(:context) hook')
run_before_context_hooks(instance)
result_for_this_group = run_examples(reporter)
results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
result_for_this_group && results_for_descendants
Expand All @@ -469,7 +468,8 @@ def self.run(reporter)
RSpec.world.wants_to_quit = true if fail_fast?
for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) }
ensure
run_after_context_hooks(new)
instance = new('after(:context) hook')
run_after_context_hooks(instance)
before_context_ivars.clear
reporter.example_group_finished(self)
end
Expand All @@ -495,7 +495,7 @@ def self.ordering_strategy
def self.run_examples(reporter)
ordering_strategy.order(filtered_examples).map do |example|
next if RSpec.world.wants_to_quit
instance = new
instance = new(example.inspect_output)
set_ivars(instance, before_context_ivars)
succeeded = example.run(instance, reporter)
RSpec.world.wants_to_quit = true if fail_fast? && !succeeded
Expand Down Expand Up @@ -570,6 +570,27 @@ def self.pending_metadata_and_block_for(options, block)

return options, callback
end

if RUBY_VERSION.to_f < 1.9
# @private
def self.instance_variables_for_example(group)
group.instance_variables - ['@__inspect_output']
end
else
# @private
def self.instance_variables_for_example(group)
group.instance_variables - [:@__inspect_output]
end
end

def initialize(inspect_output=nil)
@__inspect_output = inspect_output || '(no description provided)'
end

# @private
def inspect
"#<#{self.class} #{@__inspect_output}>"
end
end

# @private
Expand Down
92 changes: 92 additions & 0 deletions spec/rspec/core/example_group_spec.rb
Expand Up @@ -1604,5 +1604,97 @@ def foo; end
end
}.to raise_error(/not allowed/)
end

describe 'inspect output' do
context 'when there is no inspect output provided' do
it "uses '(no description provided)' instead" do
expect(ExampleGroup.new.inspect).to eq('#<RSpec::Core::ExampleGroup (no description provided)>')
end
end

context 'when an example has a description' do
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
end

context 'when an example does not have a description' do
it 'includes fallback description' do
an_example = nil

line = __LINE__ + 2
group = ExampleGroup.describe 'SomeClass2' do
example do
an_example = self
end
end

group.run

path = RSpec::Core::Metadata.relative_path(__FILE__)
expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass2 \"example at #{path}:#{line}\">")
end
end

it 'handles before context hooks' do
a_before_hook = nil

group = ExampleGroup.describe 'SomeClass3' do
before(:context) do
a_before_hook = self
end

example {}
end

group.run
expect(a_before_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass3 before(:context) hook>")
end

it 'handles after context hooks' do
an_after_hook = nil

group = ExampleGroup.describe 'SomeClass4' do
after(:context) do
an_after_hook = self
end

example {}
end

group.run
expect(an_after_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass4 after(:context) hook>")
end

it "does not pollute an example's `inspect` output with the inspect ivar from `before(:context)`" do
inspect_output = nil

line = __LINE__ + 2
group = ExampleGroup.describe do
example do
inspect_output = inspect
end

before(:context) {}
end

group.run

path = RSpec::Core::Metadata.relative_path(__FILE__)
expect(inspect_output).to end_with("\"example at #{path}:#{line}\">")
end
end
end
end

0 comments on commit aea8648

Please sign in to comment.