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

Commit b191e89

Browse files
committed
Add helpful warning message for shared example groups
I found myself with a strange warning message not long ago saying the following: ``` WARNING: Shared example group 'a flagger_or_tagger' has been previously defined at: /Users/devoncestes/esh/IRT/spec/services/shared_examples/flagger_or_tagger_spec.rb:10 ...and you are now defining it at: /Users/devoncestes/esh/IRT/spec/services/shared_examples/flagger_or_tagger_spec.rb:10 The new definition will overwrite the original one. ``` Turns out that this was happening because the file in which we defined our shared example group ended in `_spec.rb`, which triggered the Rspec auto loading, thus creating the strange warning. I had no idea how ths could happen until I opened up an issue and @myronmarston pointed out the error. I figured that a helpful warning message that could guide the user to fixing this warning themselves might be good to add, so I've done so here!
1 parent 4e616cc commit b191e89

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

lib/rspec/core/shared_example_group.rb

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,35 @@ def valid_name?(candidate)
213213

214214
def warn_if_key_taken(context, key, new_block)
215215
existing_module = shared_example_groups[context][key]
216-
217216
return unless existing_module
218217

219-
RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
220-
|WARNING: Shared example group '#{key}' has been previously defined at:
221-
| #{formatted_location existing_module.definition}
222-
|...and you are now defining it at:
223-
| #{formatted_location new_block}
224-
|The new definition will overwrite the original one.
225-
WARNING
218+
old_definition = formatted_location existing_module.definition
219+
new_definition = formatted_location new_block
220+
221+
if old_definition == new_definition
222+
RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
223+
|WARNING: Shared example group '#{key}' has been previously defined at:
224+
| #{old_definition}
225+
|...and you are now defining it at:
226+
| #{new_definition}
227+
|The new definition will overwrite the original one.
228+
|
229+
|You might be seeing this warning because of a naming issue
230+
|If you have defined a shared example group in a file that
231+
|ends in _spec.rb, and you're also including that file in another
232+
|spec, causing the shared example group to be loaded twice.
233+
|You can solve this by renaming your file so it doesn't end in
234+
|_spec.rb and continuing to include the file manually.
235+
WARNING
236+
else
237+
RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
238+
|WARNING: Shared example group '#{key}' has been previously defined at:
239+
| #{old_definition}
240+
|...and you are now defining it at:
241+
| #{new_definition}
242+
|The new definition will overwrite the original one.
243+
WARNING
244+
end
226245
end
227246

228247
def formatted_location(block)

spec/rspec/core/shared_example_group_spec.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def find_implementation_block(registry, scope, name)
6969
expect(Kernel).to_not respond_to(shared_method_name)
7070
end
7171

72-
it "displays a warning when adding a second shared example group with the same name" do
72+
it 'displays a warning when adding a second shared example group with the same name' do
7373
group.send(shared_method_name, 'some shared group') {}
7474
original_declaration = [__FILE__, __LINE__ - 1].join(':')
7575

@@ -82,6 +82,21 @@ def find_implementation_block(registry, scope, name)
8282
expect(warning).to_not include 'Called from'
8383
end
8484

85+
it 'displays a helpful message when you define a shared example group in *_spec.rb file' do
86+
warning = nil
87+
allow(::Kernel).to receive(:warn) { |msg| warning = msg }
88+
declaration = nil
89+
90+
2.times do
91+
group.send(shared_method_name, 'some shared group') {}
92+
declaration = [__FILE__, __LINE__ - 1].join(':')
93+
end
94+
95+
better_error = 'You might be seeing this warning because of a naming issue'
96+
expect(warning).to include('some shared group', declaration, better_error)
97+
expect(warning).to_not include 'Called from'
98+
end
99+
85100
it 'works with top level defined examples in modules' do
86101
expect(RSpec::configuration.reporter).to_not receive(:deprecation)
87102
RSpec.describe('example group') { include_context 'top level in module' }

0 commit comments

Comments
 (0)