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

Consider changing the semantics of shared example group metadata #1790

Closed
@myronmarston

Description

@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 with include_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 or let you want to make available everywhere...). You could do something like RSpec.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 Auto-included shared contexts are not subject to the same scoping rules that manually included ones are #1762).
  • 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 to config.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 to config.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions