Consider changing the semantics of shared example group metadata
Created by: myronmarston
Currently, you can tag a shared example group definition with some metadata:
RSpec.shared_context "DB support", :db do
# ...
end
...and that will cause the shared example group to be automatically included in matching example groups:
RSpec.describe MyModelThatUsesTheDB, :db do
# ...
end
This works fine (and was originally my idea, IIRC), but I've realized a few problems with it:
- The first argument to
shared_context
(the shared group name) is superfluous. It feels a bit like "what's this argument for again?" (Note that you could still use it withinclude_context
to include the group manually, but it's a bit odd to mix-and-match the approaches). - Some users have expressed surprised that the metadata is treated "special" here and isn't simply applied to the shared example group like it is applied to a normal example group.
- It makes it impossible to attach some metadata to a shared example group that will be automatically applied to including example groups. While no user has asked for this, I've occasionally wanted to temporarily add
:focus
,:skip
or:pending
metadata to a shared example group so that that behavior applies to all inclusions of the shared group. - There's no obvious way to make a shared example group get auto-included in every example group (e.g. for a global
before
hook orlet
you want to make available everywhere...). You could do something likeRSpec.shared_context "...", :description => //
, since//
will match the description of every example group, but that's pretty indirect and non-obvious. - It doesn't gel well with the scoping behavior of shared contexts (see #1762 (closed)).
- It's inconsistent with how module inclusion works (e.g.
config.include mod, *metadata
).
I think we can rectify all of these with a few simple changes:
- Add a new
config.include_context
API that is similar toconfig.include
but is for shared contexts. This would solve the "no obvious way to auto-include a shared group everywhere" issue mentioned above and provide a sister API toconfig.include
for consistency. - Stop using the metadata passed to
shared_context
as a means to determine which example groups should have the context auto-included, instead allowing it the metadata to get applied to including example groups.
The first change is a new API and could be made in any 3.x release. The latter is a breaking change and either has to wait until RSpec 4 or we have to add a config option. I lean towards the latter -- something like config.use_shared_example_group_metadata_for_auto_inclusion = true
(although that is a bit ambiguous -- the config.include_context
API would still use it for auto-inclusion -- maybe someone has a better idea?)
Thoughts?
/cc @rspec/rspec