diff --git a/lib/rspec/core/example_group.rb b/lib/rspec/core/example_group.rb index cabcae47b5..9bb216f6eb 100644 --- a/lib/rspec/core/example_group.rb +++ b/lib/rspec/core/example_group.rb @@ -414,6 +414,8 @@ def self.set_it_up(description, *args, &example_group_block) ) ExampleGroups.assign_const(self) + @currently_executing_a_context_hook = false + hooks.register_globals(self, RSpec.configuration.hooks) RSpec.configuration.configure_group(self) end @@ -486,15 +488,24 @@ def self.store_before_context_ivars(example_group_instance) end end + # Returns true if a `before(:context)` or `after(:context)` + # hook is currently executing. + def self.currently_executing_a_context_hook? + @currently_executing_a_context_hook + end + # @private def self.run_before_context_hooks(example_group_instance) set_ivars(example_group_instance, superclass_before_context_ivars) + @currently_executing_a_context_hook = true + ContextHookMemoized::Before.isolate_for_context_hook(example_group_instance) do hooks.run(:before, :context, example_group_instance) end ensure store_before_context_ivars(example_group_instance) + @currently_executing_a_context_hook = false end if RUBY_VERSION.to_f >= 1.9 @@ -525,11 +536,14 @@ def self.superclass_before_context_ivars def self.run_after_context_hooks(example_group_instance) set_ivars(example_group_instance, before_context_ivars) + @currently_executing_a_context_hook = true + ContextHookMemoized::After.isolate_for_context_hook(example_group_instance) do hooks.run(:after, :context, example_group_instance) end ensure before_context_ivars.clear + @currently_executing_a_context_hook = false end # Runs all the examples in this group. diff --git a/spec/rspec/core/example_group_spec.rb b/spec/rspec/core/example_group_spec.rb index f798be6429..eb19b8701c 100644 --- a/spec/rspec/core/example_group_spec.rb +++ b/spec/rspec/core/example_group_spec.rb @@ -713,6 +713,51 @@ def define_and_run_group(define_outer_example = false) group.run expect(order).to eq([:example, :after_example, :example, :after_example]) end + + describe "#currently_executing_a_context_hook?" do + it "sets currently_executing_a_context_hook? to false initially" do + group = RSpec.describe + expect(group.currently_executing_a_context_hook?).to be false + end + + it "sets currently_executing_a_context_hook? during before(:context) execution" do + group = RSpec.describe + hook_result = nil + group.before(:context) { hook_result = group.currently_executing_a_context_hook? } + group.example("") {} + group.run + expect(hook_result).to be true + end + + it "does not set currently_executing_a_context_hook? outside of before(:context) execution" do + group = RSpec.describe + hook_result = nil + + group.before(:context) { hook_result = group.currently_executing_a_context_hook? } + group.before(:each) { hook_result = group.currently_executing_a_context_hook? } + group.example("") {} + group.run + expect(hook_result).to be false + end + + it "sets currently_executing_a_context_hook? during after(:context) execution" do + group = RSpec.describe + hook_result = nil + + group.after(:context) { hook_result = group.currently_executing_a_context_hook? } + group.example("") {} + group.run + expect(hook_result).to be true + end + + it "unsets currently_executing_a_context_hook? after an after(:context) hook is done" do + group = RSpec.describe + group.after(:context) { } + group.example("") {} + group.run + expect(group.currently_executing_a_context_hook?).to be false + end + end end it "runs the before alls in order" do