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

Commit 331ca53

Browse files
committed
Explicitly ignore :suite hooks from Hooks module.
The Configuration class now handles these and it’s the only place they are supported. This allows us to reduce object allocations a bit, and also clarifies the semantics of :suite hooks.
1 parent 200746c commit 331ca53

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

benchmarks/allocations/1000_groups_1_example.rb

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,51 @@
1515

1616
class_plus count
1717
---------------------------------------- -----
18-
String 32000
19-
Array 14000
20-
RubyVM::Env 9000
18+
String 26000
19+
Array 15000
2120
Hash 9000
21+
RubyVM::Env 9000
2222
Proc 9000
2323
RSpec::Core::Hooks::HookCollection 6000
2424
Array<String> 5000
2525
MatchData 3000
26+
Module 2000
27+
Array<Module> 2000
2628
RSpec::Core::Example::ExecutionResult 2000
2729
Array<String,Fixnum> 2000
30+
RSpec::Core::Hooks::HookCollections 1000
31+
RSpec::Core::Hooks::AroundHookCollection 1000
32+
RSpec::Core::Metadata::ExampleHash 1000
33+
RSpec::Core::Metadata::ExampleGroupHash 1000
34+
Class 1000
35+
Array<Hash> 1000
36+
Array<RSpec::Core::Example> 1000
37+
RSpec::Core::Example 1000
38+
39+
40+
After removing `:suite` support from `Hooks` module,
41+
it cut Array and RSpec::Core::Hooks::HookCollection
42+
allocations by 2000 each:
43+
44+
class_plus count
45+
---------------------------------------- -----
46+
String 26000
47+
Array 13000
48+
Hash 9000
49+
Proc 9000
50+
RubyVM::Env 9000
51+
Array<String> 5000
52+
RSpec::Core::Hooks::HookCollection 4000
53+
MatchData 3000
2854
Array<Module> 2000
55+
Array<String,Fixnum> 2000
2956
Module 2000
57+
RSpec::Core::Example::ExecutionResult 2000
58+
RSpec::Core::Metadata::ExampleGroupHash 1000
3059
Class 1000
3160
Array<Hash> 1000
32-
RSpec::Core::Metadata::ExampleGroupHash 1000
61+
RSpec::Core::Hooks::AroundHookCollection 1000
62+
RSpec::Core::Hooks::HookCollections 1000
3363
RSpec::Core::Metadata::ExampleHash 1000
3464
RSpec::Core::Example 1000
3565
Array<RSpec::Core::Example> 1000
36-
RSpec::Core::Hooks::AroundHookCollection 1000
37-
RSpec::Core::Hooks::HookCollections 1000

lib/rspec/core/hooks.rb

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,8 @@ def hooks
326326
@hooks ||= HookCollections.new(
327327
self,
328328
:around => { :example => AroundHookCollection.new },
329-
:before => { :example => HookCollection.new,
330-
:context => HookCollection.new,
331-
:suite => HookCollection.new },
332-
:after => { :example => HookCollection.new,
333-
:context => HookCollection.new,
334-
:suite => HookCollection.new }
329+
:before => { :example => HookCollection.new, :context => HookCollection.new },
330+
:after => { :example => HookCollection.new, :context => HookCollection.new }
335331
)
336332
end
337333

@@ -496,6 +492,15 @@ def around_example_hooks_for(example, initial_procsy=nil)
496492

497493
def register(prepend_or_append, hook, *args, &block)
498494
scope, options = scope_and_options_from(*args)
495+
496+
if scope == :suite
497+
RSpec.warn_with "`#{hook}(:suite)` hooks are only supported on " \
498+
"the RSpec configuration object. This " \
499+
"`#{hook}(:suite)` hook, defined on an example " \
500+
"group, will be ignored."
501+
return
502+
end
503+
499504
self[hook][scope].__send__(prepend_or_append,
500505
HOOK_TYPES[hook][scope].new(block, options))
501506
end
@@ -509,7 +514,7 @@ def run(hook, scope, example_or_group, initial_procsy=nil)
509514
find_hook(hook, scope, example_or_group, initial_procsy).run
510515
end
511516

512-
SCOPES = [:example, :context, :suite]
517+
SCOPES = [:example, :context]
513518

514519
SCOPE_ALIASES = { :each => :example, :all => :context }
515520

@@ -532,6 +537,7 @@ def process(host, globals, position, scope)
532537
end
533538

534539
def scope_and_options_from(*args)
540+
return :suite if args.first == :suite
535541
scope = extract_scope_from(args)
536542
meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
537543
return scope, meta
@@ -573,8 +579,6 @@ def find_hook(hook, scope, example_or_group, initial_procsy)
573579
before_example_hooks_for(example_or_group)
574580
when [:after, :example]
575581
after_example_hooks_for(example_or_group)
576-
when [:before, :suite], [:after, :suite]
577-
self[hook][:suite].with(example_or_group)
578582
end
579583
end
580584

spec/rspec/core/suite_hooks_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ module RSpec::Core
2121
RSpec.configuration.with_suite_hooks { }
2222
}.to raise_error(ZeroDivisionError)
2323
end
24+
25+
context "defined on an example group" do
26+
it "is ignored with a clear warning" do
27+
sequence = []
28+
29+
expect {
30+
RSpec.describe "Group" do
31+
__send__(type, :suite) { sequence << :suite_hook }
32+
example { sequence << :example }
33+
end.run
34+
}.to change { sequence }.to([:example]).
35+
and output(a_string_including("#{type}(:suite)")).to_stderr
36+
end
37+
end
2438
end
2539
end
2640

0 commit comments

Comments
 (0)