Skip to content

Commit

Permalink
yield current running example to it/example and before/after hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
dchelimsky committed Jun 19, 2013
1 parent dee12fc commit d941ba7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 67 deletions.
4 changes: 2 additions & 2 deletions lib/rspec/core/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def run(example_group_instance, reporter)
with_around_each_hooks do
begin
run_before_each
@example_group_instance.instance_eval(&@example_block)
@example_group_instance.instance_exec(self, &@example_block)
rescue Pending::PendingDeclaredInExample => e
@pending_declared_in_example = e.message
rescue Exception => e
Expand Down Expand Up @@ -239,7 +239,7 @@ def instance_eval(*args, &block)

# @private
def instance_eval_with_rescue(context = nil, &block)
@example_group_instance.instance_eval_with_rescue(context, &block)
@example_group_instance.instance_eval_with_rescue(self, context, &block)
end

# @private
Expand Down
32 changes: 20 additions & 12 deletions lib/rspec/core/example_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -439,16 +439,24 @@ def self.set_ivars(instance, ivars)
ivars.each {|name, value| instance.instance_variable_set(name, value)}
end

# @attr_reader
# Returns the {Example} object that wraps this instance of
# `ExampleGroup`
attr_accessor :example
def initialize
@_current_rspec_example = nil
end

def example=(current_example)
@_current_rspec_example = current_example
end

# @deprecated use a block argument
def example
RSpec.deprecate("example", :replacement => "a block argument")
@_current_rspec_example
end

# @deprecated use {ExampleGroup#example}
# @deprecated use a block argument
def running_example
RSpec.deprecate("running_example",
:replacement => "example")
example
RSpec.deprecate("running_example", :replacement => "a block argument")
@_current_rspec_example
end

# Returns the class or module passed to the `describe` method (or alias).
Expand All @@ -468,12 +476,12 @@ def described_class
# @private
# instance_evals the block, capturing and reporting an exception if
# raised
def instance_eval_with_rescue(context = nil, &hook)
def instance_eval_with_rescue(example, context = nil, &hook)
begin
instance_eval(&hook)
instance_exec(example, &hook)
rescue Exception => e
raise unless example
example.set_exception(e, context)
raise unless @_current_rspec_example
@_current_rspec_example.set_exception(e, context)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rspec/core/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def options_apply?(example_or_group)

class BeforeHook < Hook
def run(example)
example.instance_eval(&block)
example.instance_exec(example, &block)
end

def display_name
Expand Down
13 changes: 6 additions & 7 deletions lib/rspec/core/pending.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def pending_fixed?; true; end
# # ...
# end
def pending(*args)
return self.class.before(:each) { pending(*args) } unless example
return self.class.before(:each) { pending(*args) } unless @_current_rspec_example

options = args.last.is_a?(Hash) ? args.pop : {}
message = args.first || NO_REASON_GIVEN
Expand All @@ -85,18 +85,17 @@ def pending(*args)
return block_given? ? yield : nil
end

example.metadata[:pending] = true
example.metadata[:execution_result][:pending_message] = message
@_current_rspec_example.metadata[:pending] = true
@_current_rspec_example.metadata[:execution_result][:pending_message] = message
if block_given?
begin
result = begin
yield
example.example_group_instance.instance_eval { verify_mocks_for_rspec }
true
@_current_rspec_example.example_group_instance.instance_eval { verify_mocks_for_rspec }
end
example.metadata[:pending] = false
@_current_rspec_example.metadata[:pending] = false
rescue Exception => e
example.execution_result[:exception] = e
@_current_rspec_example.execution_result[:exception] = e
ensure
teardown_mocks_for_rspec
end
Expand Down
58 changes: 20 additions & 38 deletions spec/rspec/core/example_group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ def metadata_hash(*args)
examples_run = []
group = ExampleGroup.describe("parent") do
describe("child") do
it "does something" do
examples_run << example
it "does something" do |ex|
examples_run << ex
end
end
end
Expand All @@ -79,13 +79,13 @@ def metadata_hash(*args)
it "runs its children " do
examples_run = []
group = ExampleGroup.describe("parent") do
it "fails" do
examples_run << example
it "fails" do |ex|
examples_run << ex
raise "fail"
end
describe("child") do
it "does something" do
examples_run << example
it "does something" do |ex|
examples_run << ex
end
end
end
Expand Down Expand Up @@ -663,19 +663,10 @@ def define_and_run_group(define_outer_example = false)
end
end

it "has no 'running example' within before(:all)" do
group = ExampleGroup.describe
running_example = :none
group.before(:all) { running_example = example }
group.example("no-op") { }
group.run
expect(running_example).to be(nil)
end

it "has access to example options within before(:each)" do
group = ExampleGroup.describe
option = nil
group.before(:each) { option = example.options[:data] }
group.before(:each) {|ex| option = ex.options[:data] }
group.example("no-op", :data => :sample) { }
group.run
expect(option).to eq(:sample)
Expand All @@ -684,20 +675,11 @@ def define_and_run_group(define_outer_example = false)
it "has access to example options within after(:each)" do
group = ExampleGroup.describe
option = nil
group.after(:each) { option = example.options[:data] }
group.after(:each) {|ex| option = ex.options[:data] }
group.example("no-op", :data => :sample) { }
group.run
expect(option).to eq(:sample)
end

it "has no 'running example' within after(:all)" do
group = ExampleGroup.describe
running_example = :none
group.after(:all) { running_example = example }
group.example("no-op") { }
group.run
expect(running_example).to be(nil)
end
end

%w[pending xit xspecify xexample].each do |method_name|
Expand Down Expand Up @@ -755,20 +737,20 @@ def define_and_run_group(define_outer_example = false)
describe Object, "describing nested example_groups", :little_less_nested => 'yep' do

describe "A sample nested group", :nested_describe => "yep" do
it "sets the described class to the described class of the outer most group" do
expect(example.example_group.described_class).to eq(ExampleGroup)
it "sets the described class to the described class of the outer most group" do |ex|
expect(ex.example_group.described_class).to eq(ExampleGroup)
end

it "sets the description to 'A sample nested describe'" do
expect(example.example_group.description).to eq('A sample nested group')
it "sets the description to 'A sample nested describe'" do |ex|
expect(ex.example_group.description).to eq('A sample nested group')
end

it "has top level metadata from the example_group and its parent groups" do
expect(example.example_group.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
it "has top level metadata from the example_group and its parent groups" do |ex|
expect(ex.example_group.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
end

it "exposes the parent metadata to the contained examples" do
expect(example.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
it "exposes the parent metadata to the contained examples" do |ex|
expect(ex.metadata).to include(:little_less_nested => 'yep', :nested_describe => 'yep')
end
end

Expand Down Expand Up @@ -826,12 +808,12 @@ def define_and_run_group(define_outer_example = false)
expect(@before_all_top_level).to eq('before_all_top_level')
end

it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.8 do
expect(example.example_group.before_all_ivars).to include('@before_all_top_level' => 'before_all_top_level')
it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.8 do |ex|
expect(ex.example_group.before_all_ivars).to include('@before_all_top_level' => 'before_all_top_level')
end

it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.9 do
expect(example.example_group.before_all_ivars).to include(:@before_all_top_level => 'before_all_top_level')
it "can access the before all ivars in the before_all_ivars hash", :ruby => 1.9 do |ex|
expect(ex.example_group.before_all_ivars).to include(:@before_all_top_level => 'before_all_top_level')
end

describe "but now I am nested" do
Expand Down
21 changes: 14 additions & 7 deletions spec/rspec/core/example_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,19 @@ def assert(val)
end

describe "accessing metadata within a running example" do
it "has a reference to itself when running" do
expect(example.description).to eq("has a reference to itself when running")
it "has a reference to itself when running" do |ex|
expect(ex.description).to eq("has a reference to itself when running")
end

it "can access the example group's top level metadata as if it were its own" do
expect(example.example_group.metadata).to include(:parent_metadata => 'sample')
expect(example.metadata).to include(:parent_metadata => 'sample')
it "can access the example group's top level metadata as if it were its own" do |ex|
expect(ex.example_group.metadata).to include(:parent_metadata => 'sample')
expect(ex.metadata).to include(:parent_metadata => 'sample')
end
end

describe "accessing options within a running example" do
it "can look up option values by key", :demo => :data do
expect(example.metadata[:demo]).to eq(:data)
it "can look up option values by key", :demo => :data do |ex|
expect(ex.metadata[:demo]).to eq(:data)
end
end

Expand Down Expand Up @@ -436,4 +436,11 @@ def run_and_capture_reported_message(group)

expect(values.uniq).to have(2).values
end

describe "optional block argument" do
it "contains the example" do |ex|
expect(ex).to be_an(RSpec::Core::Example)
expect(ex.description).to match(/contains the example/)
end
end
end

0 comments on commit d941ba7

Please sign in to comment.