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

Commit 3af9007

Browse files
committed
Apply config hooks to previously defined groups.
Fixes #1939.
1 parent d99d536 commit 3af9007

File tree

4 files changed

+104
-8
lines changed

4 files changed

+104
-8
lines changed

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Enhancements:
55

66
* Remove unneeded `:execution_result` example groups metadata, saving a
77
bit of memory. (Myron Marston, #2172)
8+
* Apply hooks registered with `config` to previously defined groups.
9+
(Myron Marston, #2189)
810

911
### 3.5.0.beta1 / 2016-02-06
1012
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.3...v3.5.0.beta1)

lib/rspec/core/configuration.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,8 @@ def apply_derived_metadata_to(metadata)
15701570
# @see #after
15711571
# @see #append_after
15721572
def before(scope=nil, *meta, &block)
1573+
on_existing_matching_groups({}) { |g| g.before(scope, *meta, &block) }
1574+
15731575
handle_suite_hook(scope, meta) do
15741576
@before_suite_hooks << Hooks::BeforeHook.new(block, {})
15751577
end || super(scope, *meta, &block)
@@ -1590,6 +1592,8 @@ def before(scope=nil, *meta, &block)
15901592
# @see #after
15911593
# @see #append_after
15921594
def prepend_before(scope=nil, *meta, &block)
1595+
on_existing_matching_groups({}) { |g| g.prepend_before(scope, *meta, &block) }
1596+
15931597
handle_suite_hook(scope, meta) do
15941598
@before_suite_hooks.unshift Hooks::BeforeHook.new(block, {})
15951599
end || super(scope, *meta, &block)
@@ -1605,6 +1609,8 @@ def prepend_before(scope=nil, *meta, &block)
16051609
# @see #before
16061610
# @see #prepend_before
16071611
def after(scope=nil, *meta, &block)
1612+
on_existing_matching_groups({}) { |g| g.after(scope, *meta, &block) }
1613+
16081614
handle_suite_hook(scope, meta) do
16091615
@after_suite_hooks.unshift Hooks::AfterHook.new(block, {})
16101616
end || super(scope, *meta, &block)
@@ -1625,11 +1631,22 @@ def after(scope=nil, *meta, &block)
16251631
# @see #before
16261632
# @see #prepend_before
16271633
def append_after(scope=nil, *meta, &block)
1634+
on_existing_matching_groups({}) { |g| g.append_after(scope, *meta, &block) }
1635+
16281636
handle_suite_hook(scope, meta) do
16291637
@after_suite_hooks << Hooks::AfterHook.new(block, {})
16301638
end || super(scope, *meta, &block)
16311639
end
16321640

1641+
# Registers `block` as an `around` hook.
1642+
#
1643+
# See {Hooks#around} for full `around` hook docs.
1644+
def around(scope=nil, *meta, &block)
1645+
on_existing_matching_groups({}) { |g| g.around(scope, *meta, &block) }
1646+
1647+
super(scope, *meta, &block)
1648+
end
1649+
16331650
# @private
16341651
def with_suite_hooks
16351652
return yield if dry_run?

lib/rspec/core/hooks.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,7 @@ def hooks
342342
private
343343

344344
# @private
345-
class Hook
346-
attr_reader :block, :options
347-
348-
def initialize(block, options)
349-
@block = block
350-
@options = options
351-
end
352-
end
345+
Hook = Struct.new(:block, :options)
353346

354347
# @private
355348
class BeforeHook < Hook

spec/rspec/core/hooks_filtering_spec.rb

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,89 @@
11
module RSpec::Core
22
RSpec.describe "config block hook filtering" do
3+
context "when hooks are defined after a group has been defined" do
4+
it "still applies" do
5+
sequence = []
6+
7+
group = RSpec.describe do
8+
example { sequence << :ex_1 }
9+
example { sequence << :ex_2 }
10+
end
11+
12+
RSpec.configure do |c|
13+
c.before(:context) { sequence << :before_cont_2 }
14+
c.prepend_before(:context) { sequence << :before_cont_1 }
15+
16+
c.before(:example) { sequence << :before_ex_2 }
17+
c.prepend_before(:example) { sequence << :before_ex_1 }
18+
19+
c.after(:context) { sequence << :after_cont_1 }
20+
c.append_after(:context) { sequence << :after_cont_2 }
21+
22+
c.after(:example) { sequence << :after_ex_1 }
23+
c.append_after(:example) { sequence << :after_ex_2 }
24+
25+
c.around(:example) do |ex|
26+
sequence << :around_before_ex
27+
ex.run
28+
sequence << :around_after_ex
29+
end
30+
end
31+
32+
group.run
33+
34+
expect(sequence).to eq [
35+
:before_cont_1, :before_cont_2,
36+
:around_before_ex, :before_ex_1, :before_ex_2, :ex_1, :after_ex_1, :after_ex_2, :around_after_ex,
37+
:around_before_ex, :before_ex_1, :before_ex_2, :ex_2, :after_ex_1, :after_ex_2, :around_after_ex,
38+
:after_cont_1, :after_cont_2
39+
]
40+
end
41+
42+
it "applies only to groups with matching metadata" do
43+
sequence = []
44+
45+
unmatching_group = RSpec.describe do
46+
example { }
47+
example { }
48+
end
49+
50+
matching_group = RSpec.describe "", :run_hooks do
51+
example { sequence << :ex_1 }
52+
example { sequence << :ex_2 }
53+
end
54+
55+
RSpec.configure do |c|
56+
c.before(:context, :run_hooks) { sequence << :before_cont_2 }
57+
c.prepend_before(:context, :run_hooks) { sequence << :before_cont_1 }
58+
59+
c.before(:example, :run_hooks) { sequence << :before_ex_2 }
60+
c.prepend_before(:example, :run_hooks) { sequence << :before_ex_1 }
61+
62+
c.after(:context, :run_hooks) { sequence << :after_cont_1 }
63+
c.append_after(:context, :run_hooks) { sequence << :after_cont_2 }
64+
65+
c.after(:example, :run_hooks) { sequence << :after_ex_1 }
66+
c.append_after(:example, :run_hooks) { sequence << :after_ex_2 }
67+
68+
c.around(:example, :run_hooks) do |ex|
69+
sequence << :around_before_ex
70+
ex.run
71+
sequence << :around_after_ex
72+
end
73+
end
74+
75+
expect { unmatching_group.run }.not_to change { sequence }.from([])
76+
77+
matching_group.run
78+
expect(sequence).to eq [
79+
:before_cont_1, :before_cont_2,
80+
:around_before_ex, :before_ex_1, :before_ex_2, :ex_1, :after_ex_1, :after_ex_2, :around_after_ex,
81+
:around_before_ex, :before_ex_1, :before_ex_2, :ex_2, :after_ex_1, :after_ex_2, :around_after_ex,
82+
:after_cont_1, :after_cont_2
83+
]
84+
end
85+
end
86+
387
describe "unfiltered hooks" do
488
it "is run" do
589
filters = []

0 commit comments

Comments
 (0)