Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit ffd7492

Browse files
kcdragonMike Dalton
authored andcommitted
Add better inspect output for ExampleGroup
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
1 parent 70ca4e4 commit ffd7492

File tree

3 files changed

+129
-7
lines changed

3 files changed

+129
-7
lines changed

lib/rspec/core/example.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ def description
8282
RSpec.configuration.format_docstrings_block.call(description)
8383
end
8484

85+
# Returns a description of the example that always includes the location.
86+
def inspect_output
87+
inspect_output = "\"#{description}\""
88+
unless metadata[:description].to_s.empty?
89+
inspect_output << " (#{location})"
90+
end
91+
inspect_output
92+
end
93+
8594
# @attr_reader
8695
#
8796
# Returns the first exception raised in the context of running this
@@ -170,7 +179,7 @@ def run(example_group_instance, reporter)
170179
rescue Exception => e
171180
set_exception(e)
172181
ensure
173-
@example_group_instance.instance_variables.each do |ivar|
182+
ExampleGroup.instance_variables_for_example(@example_group_instance).each do |ivar|
174183
@example_group_instance.instance_variable_set(ivar, nil)
175184
end
176185
@example_group_instance = nil

lib/rspec/core/example_group.rb

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,7 @@ def self.before_context_ivars
419419

420420
# @private
421421
def self.store_before_context_ivars(example_group_instance)
422-
return if example_group_instance.instance_variables.empty?
423-
424-
example_group_instance.instance_variables.each do |ivar|
422+
instance_variables_for_example(example_group_instance).each do |ivar|
425423
before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
426424
end
427425
end
@@ -459,7 +457,8 @@ def self.run(reporter)
459457
reporter.example_group_started(self)
460458

461459
begin
462-
run_before_context_hooks(new)
460+
instance = new('before(:context) hook')
461+
run_before_context_hooks(instance)
463462
result_for_this_group = run_examples(reporter)
464463
results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
465464
result_for_this_group && results_for_descendants
@@ -469,7 +468,8 @@ def self.run(reporter)
469468
RSpec.world.wants_to_quit = true if fail_fast?
470469
for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) }
471470
ensure
472-
run_after_context_hooks(new)
471+
instance = new('after(:context) hook')
472+
run_after_context_hooks(instance)
473473
before_context_ivars.clear
474474
reporter.example_group_finished(self)
475475
end
@@ -495,7 +495,7 @@ def self.ordering_strategy
495495
def self.run_examples(reporter)
496496
ordering_strategy.order(filtered_examples).map do |example|
497497
next if RSpec.world.wants_to_quit
498-
instance = new
498+
instance = new(example.inspect_output)
499499
set_ivars(instance, before_context_ivars)
500500
succeeded = example.run(instance, reporter)
501501
RSpec.world.wants_to_quit = true if fail_fast? && !succeeded
@@ -570,6 +570,27 @@ def self.pending_metadata_and_block_for(options, block)
570570

571571
return options, callback
572572
end
573+
574+
if RUBY_VERSION.to_f < 1.9
575+
# @private
576+
def self.instance_variables_for_example(group)
577+
group.instance_variables - ['@__inspect_output']
578+
end
579+
else
580+
# @private
581+
def self.instance_variables_for_example(group)
582+
group.instance_variables - [:@__inspect_output]
583+
end
584+
end
585+
586+
def initialize(inspect_output=nil)
587+
@__inspect_output = inspect_output || '(no description provided)'
588+
end
589+
590+
# @private
591+
def inspect
592+
"#<#{self.class} #{@__inspect_output}>"
593+
end
573594
end
574595

575596
# @private

spec/rspec/core/example_group_spec.rb

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,5 +1604,97 @@ def foo; end
16041604
end
16051605
}.to raise_error(/not allowed/)
16061606
end
1607+
1608+
describe 'inspect output' do
1609+
context 'when there is no inspect output provided' do
1610+
it "uses '(no description provided)' instead" do
1611+
expect(ExampleGroup.new.inspect).to eq('#<RSpec::Core::ExampleGroup (no description provided)>')
1612+
end
1613+
end
1614+
1615+
context 'when an example has a description' do
1616+
it 'includes description and location' do
1617+
an_example = nil
1618+
1619+
line = __LINE__ + 2
1620+
group = ExampleGroup.describe 'SomeClass1' do
1621+
example 'an example' do
1622+
an_example = self
1623+
end
1624+
end
1625+
1626+
group.run
1627+
1628+
path = RSpec::Core::Metadata.relative_path(__FILE__)
1629+
expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass1 \"an example\" (#{path}:#{line})>")
1630+
end
1631+
end
1632+
1633+
context 'when an example does not have a description' do
1634+
it 'includes fallback description' do
1635+
an_example = nil
1636+
1637+
line = __LINE__ + 2
1638+
group = ExampleGroup.describe 'SomeClass2' do
1639+
example do
1640+
an_example = self
1641+
end
1642+
end
1643+
1644+
group.run
1645+
1646+
path = RSpec::Core::Metadata.relative_path(__FILE__)
1647+
expect(an_example.inspect).to eq("#<RSpec::ExampleGroups::SomeClass2 \"example at #{path}:#{line}\">")
1648+
end
1649+
end
1650+
1651+
it 'handles before context hooks' do
1652+
a_before_hook = nil
1653+
1654+
group = ExampleGroup.describe 'SomeClass3' do
1655+
before(:context) do
1656+
a_before_hook = self
1657+
end
1658+
1659+
example {}
1660+
end
1661+
1662+
group.run
1663+
expect(a_before_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass3 before(:context) hook>")
1664+
end
1665+
1666+
it 'handles after context hooks' do
1667+
an_after_hook = nil
1668+
1669+
group = ExampleGroup.describe 'SomeClass4' do
1670+
after(:context) do
1671+
an_after_hook = self
1672+
end
1673+
1674+
example {}
1675+
end
1676+
1677+
group.run
1678+
expect(an_after_hook.inspect).to eq("#<RSpec::ExampleGroups::SomeClass4 after(:context) hook>")
1679+
end
1680+
1681+
it "does not pollute an example's `inspect` output with the inspect ivar from `before(:context)`" do
1682+
inspect_output = nil
1683+
1684+
line = __LINE__ + 2
1685+
group = ExampleGroup.describe do
1686+
example do
1687+
inspect_output = inspect
1688+
end
1689+
1690+
before(:context) {}
1691+
end
1692+
1693+
group.run
1694+
1695+
path = RSpec::Core::Metadata.relative_path(__FILE__)
1696+
expect(inspect_output).to end_with("\"example at #{path}:#{line}\">")
1697+
end
1698+
end
16071699
end
16081700
end

0 commit comments

Comments
 (0)