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

Commit 6e5a48f

Browse files
committed
Refactor: always create module for shared example groups.
This simplifies things, makes things more consistent, and prepares us to be able to better handle metadata as per discussion in #1790.
1 parent 9795a57 commit 6e5a48f

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

lib/rspec/core/configuration.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,8 +1219,8 @@ def include(mod, *filters)
12191219
#
12201220
# @see #include
12211221
def include_context(shared_group_name, *filters)
1222-
block = world.shared_example_group_registry.find([:main], shared_group_name)
1223-
include SharedExampleGroupModule.new(shared_group_name, block), *filters
1222+
shared_module = world.shared_example_group_registry.find([:main], shared_group_name)
1223+
include shared_module, *filters
12241224
end
12251225

12261226
# Tells RSpec to extend example groups with `mod`. Methods defined in

lib/rspec/core/example_group.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -364,16 +364,16 @@ def self.remove_example(example)
364364

365365
# @private
366366
def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block)
367-
shared_block = RSpec.world.shared_example_group_registry.find(parent_groups, name)
367+
shared_module = RSpec.world.shared_example_group_registry.find(parent_groups, name)
368368

369-
unless shared_block
369+
unless shared_module
370370
raise ArgumentError, "Could not find shared #{label} #{name.inspect}"
371371
end
372372

373-
SharedExampleGroupInclusionStackFrame.with_frame(name, Metadata.relative_path(inclusion_location)) do
374-
module_exec(*args, &shared_block)
375-
module_exec(&customization_block) if customization_block
376-
end
373+
shared_module.include_in(
374+
self, Metadata.relative_path(inclusion_location),
375+
args, customization_block
376+
)
377377
end
378378

379379
# @!endgroup

lib/rspec/core/shared_example_group.rb

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ module Core
55
# eval'd when the `SharedExampleGroupModule` instance is included in an example
66
# group.
77
class SharedExampleGroupModule < Module
8+
# @private
9+
attr_reader :definition
10+
811
def initialize(description, definition)
912
@description = description
1013
@definition = definition
@@ -21,8 +24,14 @@ def inspect
2124
# including example group.
2225
def included(klass)
2326
inclusion_line = klass.metadata[:location]
27+
include_in klass, inclusion_line, [], nil
28+
end
29+
30+
# @private
31+
def include_in(klass, inclusion_line, args, customization_block)
2432
SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do
25-
klass.class_exec(&@definition)
33+
klass.class_exec(*args, &@definition)
34+
klass.class_exec(&customization_block) if customization_block
2635
end
2736
end
2837
end
@@ -142,16 +151,17 @@ def self.remove_globally!
142151
class Registry
143152
def add(context, name, *metadata_args, &block)
144153
ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line }
154+
shared_module = SharedExampleGroupModule.new(name, block)
145155

146156
if valid_name?(name)
147157
warn_if_key_taken context, name, block
148-
shared_example_groups[context][name] = block
158+
shared_example_groups[context][name] = shared_module
149159
else
150160
metadata_args.unshift name
151161
end
152162

153163
return if metadata_args.empty?
154-
RSpec.configuration.include SharedExampleGroupModule.new(name, block), *metadata_args
164+
RSpec.configuration.include shared_module, *metadata_args
155165
end
156166

157167
def find(lookup_contexts, name)
@@ -177,13 +187,13 @@ def valid_name?(candidate)
177187
end
178188

179189
def warn_if_key_taken(context, key, new_block)
180-
existing_block = shared_example_groups[context][key]
190+
existing_module = shared_example_groups[context][key]
181191

182-
return unless existing_block
192+
return unless existing_module
183193

184194
RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
185195
|WARNING: Shared example group '#{key}' has been previously defined at:
186-
| #{formatted_location existing_block}
196+
| #{formatted_location existing_module.definition}
187197
|...and you are now defining it at:
188198
| #{formatted_location new_block}
189199
|The new definition will overwrite the original one.

spec/rspec/core/shared_example_group_spec.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ module Core
4444
group.send(shared_method_name, *args, &block)
4545
end
4646

47+
def find_implementation_block(registry, scope, name)
48+
registry.find([scope], name).definition
49+
end
50+
4751
it "is exposed to the global namespace when expose_dsl_globally is enabled" do
4852
in_sub_process do
4953
RSpec.configuration.expose_dsl_globally = true
@@ -98,7 +102,7 @@ module Core
98102
it "captures the given #{type} and block in the collection of shared example groups" do
99103
implementation = lambda { }
100104
define_shared_group(object, &implementation)
101-
expect(registry.find([group], object)).to eq implementation
105+
expect(find_implementation_block(registry, group, object)).to eq implementation
102106
end
103107
end
104108
end
@@ -120,7 +124,7 @@ module Core
120124
it "captures the given string and block in the World's collection of shared example groups" do
121125
implementation = lambda { }
122126
define_shared_group("name", :foo => :bar, &implementation)
123-
expect(registry.find([group], "name")).to eq implementation
127+
expect(find_implementation_block(registry, group, "name")).to eq implementation
124128
end
125129

126130
it "delegates include on configuration" do

0 commit comments

Comments
 (0)